Ignore:
Timestamp:
Feb 14, 2018, 3:40:19 PM (6 years ago)
Author:
alain
Message:

blip

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_wait.c

    r421 r433  
    4141    pid_t       child_pid;
    4242    int         child_state;
     43    thread_t  * child_thread;
    4344
    4445    thread_t  * this    = CURRENT_THREAD;
    4546    process_t * process = this->process;
     47    pid_t       pid     = process->pid;
    4648
    47 #if CONFIG_SYSCALL_DEBUG
     49#if CONFIG_DEBUG_SYS_WAIT
    4850uint64_t    tm_start;
    4951uint64_t    tm_end;
    5052tm_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 );
     53if( CONFIG_DEBUG_SYS_WAIT < tm_start )
     54printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
     55__FUNCTION__, this, process->pid, (uint32_t)tm_start );
    5356#endif
    5457
     
    6467        }
    6568
    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 );
    7071
    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" );
    7375
    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 );
    7683
    7784    // exit this blocking loop only when a child processes change state
    7885    while( 1 )
    7986    {
    80         // get lock
    81         remote_spinlock_lock( lock_xp );
     87        // get lock protecting children list
     88        remote_spinlock_lock( children_lock_xp );
    8289
    83         // scan the list of child process
    84         XLIST_FOREACH( root_xp , iter_xp )
     90        // scan the list of owner child process
     91        XLIST_FOREACH( children_root_xp , iter_xp )
    8592        {
    86             // get child process cluster and local pointer
     93            // get child process owner cluster and local pointer
    8794            child_xp  = XLIST_ELEMENT( iter_xp , process_t , children_list );
    8895            child_ptr = GET_PTR( child_xp );
    8996            child_cxy = GET_CXY( child_xp );
    9097
    91             // get the child PID
    92             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));
    93100
    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]));
    96111
    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 );
    102115
    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
    104121tm_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) );
     122if( CONFIG_DEBUG_SYS_WAIT < tm_end )
     123printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n",
     124__FUNCTION__, this, process->pid, (uint32_t)tm_end );
    107125#endif
    108126
    109                 // return relevant info to process
    110                 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;
    112130            }
    113131        }
    114132       
    115133        // release lock
    116         remote_spinlock_unlock( lock_xp );
     134        remote_spinlock_unlock( children_lock_xp );
    117135
    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" );
    121138    }
    122139
Note: See TracChangeset for help on using the changeset viewer.