Changeset 433 for trunk/kernel/syscalls/sys_wait.c
- Timestamp:
- Feb 14, 2018, 3:40:19 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_wait.c
r421 r433 41 41 pid_t child_pid; 42 42 int child_state; 43 thread_t * child_thread; 43 44 44 45 thread_t * this = CURRENT_THREAD; 45 46 process_t * process = this->process; 47 pid_t pid = process->pid; 46 48 47 #if CONFIG_ SYSCALL_DEBUG49 #if CONFIG_DEBUG_SYS_WAIT 48 50 uint64_t tm_start; 49 51 uint64_t tm_end; 50 52 tm_start = hal_get_cycles(); 51 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle %d\n", 52 __FUNCTION__ , local_cxy , this->core->lid , process->pid, (uint32_t)tm_start ); 53 if( CONFIG_DEBUG_SYS_WAIT < tm_start ) 54 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 55 __FUNCTION__, this, process->pid, (uint32_t)tm_start ); 53 56 #endif 54 57 … … 64 67 } 65 68 66 // get cluster and local pointer on reference process 67 xptr_t ref_xp = process->ref_xp; 68 cxy_t ref_cxy = GET_CXY( ref_xp ); 69 process_t * ref_ptr = GET_PTR( ref_xp ); 69 // get process owner cluster 70 cxy_t owner_cxy = CXY_FROM_PID( pid ); 70 71 71 // get extended pointer on children list root 72 xptr_t root_xp = XPTR( ref_cxy , &ref_ptr->children_root ); 72 // This function must be executed in owner cluster 73 assert( (owner_cxy == local_cxy) , __FUNCTION__ , 74 "calling thread must execute in owner cluster" ); 73 75 74 // get extended pointer on lock protecting the children list 75 xptr_t lock_xp = XPTR( ref_cxy , &ref_ptr->children_lock ); 76 // This function must be executed by the main thread 77 assert( (process->th_tbl[0] == this) , __FUNCTION__ , 78 "this function must be executed by the main thread" ); 79 80 // get extended pointer on children list root and lock 81 xptr_t children_root_xp = XPTR( owner_cxy , &process->children_root ); 82 xptr_t children_lock_xp = XPTR( owner_cxy , &process->children_lock ); 76 83 77 84 // exit this blocking loop only when a child processes change state 78 85 while( 1 ) 79 86 { 80 // get lock 81 remote_spinlock_lock( lock_xp );87 // get lock protecting children list 88 remote_spinlock_lock( children_lock_xp ); 82 89 83 // scan the list of child process84 XLIST_FOREACH( root_xp , iter_xp )90 // scan the list of owner child process 91 XLIST_FOREACH( children_root_xp , iter_xp ) 85 92 { 86 // get child process cluster and local pointer93 // get child process owner cluster and local pointer 87 94 child_xp = XLIST_ELEMENT( iter_xp , process_t , children_list ); 88 95 child_ptr = GET_PTR( child_xp ); 89 96 child_cxy = GET_CXY( child_xp ); 90 97 91 // get t he child PID92 child_ pid = (int)hal_remote_lw( XPTR( child_cxy , &child_ptr->pid ));98 // get term_state from child owner process 99 child_state = (int)hal_remote_lw ( XPTR(child_cxy,&child_ptr->term_state)); 93 100 94 // get the child process state 95 child_state = hal_remote_lw( XPTR( child_cxy , &child_ptr->state ) ); 101 // test if child process is terminated, 102 // but termination not yet reported to parent process 103 if( ((child_state & PROCESS_FLAG_EXIT) || 104 (child_state & PROCESS_FLAG_KILL) || 105 (child_state & PROCESS_FLAG_BLOCK)) && 106 ((child_state & PROCESS_FLAG_WAIT) == 0) ) 107 { 108 // get pointer on main thread and PID from child owner process 109 child_pid = (pid_t) hal_remote_lw ( XPTR(child_cxy,&child_ptr->pid)); 110 child_thread = (thread_t *)hal_remote_lpt( XPTR(child_cxy,&child_ptr->th_tbl[0])); 96 111 97 // check child process state 98 if( child_state != PROCESS_STATE_RUNNING ) 99 { 100 // release lock 101 remote_spinlock_unlock( lock_xp ); 112 // set the PROCESS_FLAG_WAIT in owner child descriptor 113 hal_remote_atomic_or( XPTR( child_cxy , &child_ptr->term_state ), 114 PROCESS_FLAG_WAIT ); 102 115 103 #if CONFIG_SYSCALL_DEBUG 116 // set the THREAD_FLAG_REQ_DELETE in child main thread 117 hal_remote_atomic_or( XPTR( child_cxy , &child_thread->flags ) , 118 THREAD_FLAG_REQ_DELETE ); 119 120 #if CONFIG_DEBUG_SYS_WAIT 104 121 tm_end = hal_get_cycles(); 105 printk("\n[DBG] %s : core[%x,%d] exit / process %x / cost = %d\n", 106 __FUNCTION__ , local_cxy, this->core->lid, process->pid, (uint32_t)(tm_end - tm_start) ); 122 if( CONFIG_DEBUG_SYS_WAIT < tm_end ) 123 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n", 124 __FUNCTION__, this, process->pid, (uint32_t)tm_end ); 107 125 #endif 108 126 109 // return relevant info toprocess110 hal_copy_to_uspace( status , &child_state , sizeof(int) );111 return child_pid;127 // return relevant info to calling parent process 128 hal_copy_to_uspace( status , &child_state , sizeof(int) ); 129 return child_pid; 112 130 } 113 131 } 114 132 115 133 // release lock 116 remote_spinlock_unlock( lock_xp );134 remote_spinlock_unlock( children_lock_xp ); 117 135 118 // block the calling thread until a child process change state 119 thread_block( this , THREAD_BLOCKED_WAIT ); 120 sched_yield( "wait child termination" ); 136 // deschedule without blocking 137 sched_yield( "parent wait children termination" ); 121 138 } 122 139
Note: See TracChangeset
for help on using the changeset viewer.