Ignore:
Timestamp:
Dec 20, 2017, 4:51:09 PM (4 years ago)
Author:
alain
Message:

Fix bugs in exec

File:
1 edited

Legend:

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

    r408 r409  
    4040    cxy_t         target_cxy;
    4141    ltid_t        target_ltid;
    42     uint32_t      flags;        // target thread flags
    43     intptr_t      value;        // value returned by target thread
    44     paddr_t       paddr;        // required for vmm_v2p_translate()
     42        uint32_t      target_blocked;   // target thread blocked bit-vector
     43    uint32_t      target_flags;     // target thread flags bit-bector
     44    paddr_t       paddr;            // required for vmm_v2p_translate()
    4545
    46         thread_t  * this    = CURRENT_THREAD;
    47     process_t * process = this->process;
     46        thread_t    * this    = CURRENT_THREAD;
     47    process_t   * process = this->process;
    4848
    4949    // get target thread ltid and cxy
     
    8989
    9090    // check target thread joinable
    91     flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
    92     if( flags & THREAD_FLAG_DETACHED )
     91    target_flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     92    if( target_flags & THREAD_FLAG_DETACHED )
    9393    {
    9494        printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ );
     
    100100    if( target_ptr->signature != THREAD_SIGNATURE )
    101101    {
    102         printk("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
    103         hal_core_sleep();
     102        panic("\n[PANIC] in %s : kernel stack overflow\n", __FUNCTION__ );
    104103    }
    105104
    106     // wait target thread exit
    107     while( 1 )
     105    // get the lock protecting the join in target thread
     106    remote_spinlock_lock( XPTR( target_cxy , &target_ptr->join_lock ) );
     107
     108    // get the blocked bit_vector from the target thread
     109    target_blocked = hal_remote_lw( XPTR( target_cxy , &target_ptr->blocked ) );
     110
     111    if( target_blocked & THREAD_BLOCKED_JOIN )    // target thread arrived first
    108112    {
    109         // take the target thread lock protecting flags     
    110         remote_spinlock_lock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     113        // unblock the target thread
     114        thread_unblock( target_xp , THREAD_BLOCKED_JOIN );
    111115
    112         // get the remote thread flags
    113         flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) );
     116        // release the lock protecting flags     
     117        remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) );
    114118
    115         // check the EXIT flag
    116         if( flags & THREAD_FLAG_EXIT )   // target made an exit
    117         {
    118             // unblock the target thread
    119             thread_unblock( target_xp , THREAD_BLOCKED_EXIT );
     119        // get the exit value from target thread
     120        *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) );
     121    }
     122    else                                          // this thread arrived first
     123    {
     124        // register this thread extended pointer in target thread
     125        hal_remote_swd( XPTR( target_cxy , &target_ptr->join_xp ) ,
     126                              XPTR( local_cxy , this ) );
    120127
    121             // release the target thread lock protecting flags     
    122             remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
     128        // set the JOIN_DONE flag in target thread
     129        hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) ,
     130                              THREAD_FLAG_JOIN_DONE );
    123131
    124             // exit while
    125             break;
    126         }
    127         else                             // no exit done by target thread
    128         {
    129             // set the JOIN flag in target thread
    130             hal_remote_atomic_or( XPTR( target_xp , &target_ptr->flags ) ,
    131                                   THREAD_BLOCKED_JOIN );
     132        // block this thread on BLOCKED_EXIT
     133        thread_block( this , THREAD_BLOCKED_EXIT );
    132134
    133             // block this thread
    134             thread_block( this , THREAD_BLOCKED_JOIN );
     135        // release the lock protecting flags     
     136        remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) );
    135137
    136             // release the target thread lock protecting flags
    137                 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->flags_lock ) );
    138 
    139             // deschedule
    140             sched_yield("waiting child exit");
    141         }
     138        // deschedule
     139        sched_yield( "WAITING_EXIT" );
     140   
     141        // get the exit value from target thread when resume
     142        *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) );
    142143    }
    143144
    144     // return exit_value from target thread descriptor
    145     value = (intptr_t)hal_remote_lpt( XPTR( target_cxy , &target_ptr->exit_value ) );
    146     *exit_value = (void *)value;
    147145    return 0;
    148146
Note: See TracChangeset for help on using the changeset viewer.