Ignore:
Timestamp:
May 3, 2018, 5:51:22 PM (4 years ago)
Author:
alain
Message:

1/ Fix a bug in the Multithreaded "sort" applicationr:
The pthread_create() arguments must be declared as global variables.
2/ The exit syscall can be called by any thread of a process..

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/chdev.c

    r438 r440  
    124124{
    125125    thread_t * server_ptr;    // local pointer on server thread associated to chdev
     126    xptr_t     server_xp;     // extended pointer on server thread
    126127    core_t   * core_ptr;      // local pointer on core running the server thread
    127128    uint32_t   lid;           // core running the server thread local index
     
    140141    thread_t * this = CURRENT_THREAD;
    141142
    142     // get device descriptor cluster and local pointer
     143    // get chdev cluster and local pointer
    143144    cxy_t     chdev_cxy = GET_CXY( chdev_xp );
    144     chdev_t * chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );
     145    chdev_t * chdev_ptr = GET_PTR( chdev_xp );
     146
     147    // get local and extended pointers on server thread
     148    server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) );
     149    server_xp  = XPTR( chdev_cxy , server_ptr );
     150
     151    // get local pointer on core running the server thread
     152    core_ptr   = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) );
     153
     154    // get server core local index
     155    lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
    145156
    146157#if (DEBUG_CHDEV_CMD_RX || DEBUG_CHDEV_CMD_TX)
     
    162173#endif
    163174
    164     // build extended pointers on client thread xlist and device root
    165     xptr_t  list_xp = XPTR( local_cxy , &this->wait_list );
    166     xptr_t  root_xp = XPTR( chdev_cxy , &chdev_ptr->wait_root );
    167 
    168     // get local pointer on server thread
    169     server_ptr = (thread_t *)hal_remote_lpt( XPTR( chdev_cxy , &chdev_ptr->server) );
    170 
    171     // build extended pointer on chdev lock protecting queue
     175    // build extended pointer on client thread xlist
     176    xptr_t  list_xp    = XPTR( local_cxy , &this->wait_list );
     177
     178    // build extended pointer on chdev waiting queue root
     179    xptr_t  root_xp    = XPTR( chdev_cxy , &chdev_ptr->wait_root );
     180
     181    // build extended pointer on server thread blocked state
     182    xptr_t  blocked_xp = XPTR( chdev_cxy , &server_ptr->blocked );
     183
     184    // build extended pointer on lock protecting chdev waiting queue
    172185    lock_xp = XPTR( chdev_cxy , &chdev_ptr->wait_lock );
    173186
    174     // get local pointer on core running the server thread
    175     core_ptr = (core_t *)hal_remote_lpt( XPTR( chdev_cxy , &server_ptr->core ) );
    176 
    177     // get core local index
    178     lid = hal_remote_lw( XPTR( chdev_cxy , &core_ptr->lid ) );
    179 
    180     // compute server core != thread core
    181     different = (lid != this->core->lid) || (local_cxy != chdev_cxy);
    182 
    183     // enter critical section to make atomic :
    184     // (1) client blocking
    185     // (2) client registration in server queue
    186     // (3) IPI to force server scheduling
    187     // (4) descheduling
     187    // critical section for the following sequence:
     188    // (1) take the lock protecting waiting queue
     189    // (2) block the client thread
     190    // (3) unblock the server thread if required
     191    // (4) register client thread in server queue
     192    // (5) send IPI to force server scheduling
     193    // (6) release the lock protecting waiting queue
     194    // (7) deschedule
    188195    // ... in this order
     196
     197    // enter critical section
    189198    hal_disable_irq( &save_sr );
     199
     200    // take the lock
     201    remote_spinlock_lock( lock_xp );
    190202
    191203    // block current thread
    192204    thread_block( XPTR( local_cxy , CURRENT_THREAD ) , THREAD_BLOCKED_IO );
    193205
     206    if( hal_remote_lw( blocked_xp ) & THREAD_BLOCKED_IDLE )
     207    thread_unblock( server_xp , THREAD_BLOCKED_IDLE );
     208
    194209    // register client thread in waiting queue
    195     remote_spinlock_lock( lock_xp );
    196210    xlist_add_last( root_xp , list_xp );
    197     remote_spinlock_unlock( lock_xp );
    198 
    199     // send IPI to core running the server thread if required
     211
     212    // send IPI to core running the server thread when server != client
     213    different = (lid != this->core->lid) || (local_cxy != chdev_cxy);
    200214    if( different ) dev_pic_send_ipi( chdev_cxy , lid );
    201215   
     216    // release lock
     217    remote_spinlock_unlock( lock_xp );
     218
    202219    // deschedule
    203220    assert( thread_can_yield( this ) , __FUNCTION__ , "illegal sched_yield\n" );
     
    260277            remote_spinlock_unlock( lock_xp );
    261278
     279            // block
     280            thread_block( XPTR( local_cxy , server ) , THREAD_BLOCKED_IDLE );
     281
    262282            // deschedule
     283            assert( thread_can_yield( server ) , __FUNCTION__ , "illegal sched_yield\n" );
    263284            sched_yield("I/O queue empty");
    264285        }
    265286        else                            // waiting queue not empty
    266287        {
     288            // get extended pointer on first client thread
     289            client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
     290
     291            // get client thread cluster and local pointer
     292            client_cxy = GET_CXY( client_xp );
     293            client_ptr = GET_PTR( client_xp );
     294
     295            // remove this first client thread from waiting queue
     296            xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
     297
    267298            // release lock
    268299            remote_spinlock_unlock( lock_xp );
    269 
    270             // get extended pointer on first client thread
    271             client_xp = XLIST_FIRST_ELEMENT( root_xp , thread_t , wait_list );
    272 
    273             // get client thread cluster, local pointer, and identifier
    274             client_cxy = GET_CXY( client_xp );
    275             client_ptr = (thread_t *)GET_PTR( client_xp );
    276300
    277301#if DEBUG_CHDEV_SERVER_RX
     
    300324            chdev->cmd( client_xp );
    301325       
    302             // remove the client thread from waiting queue
    303             remote_spinlock_lock( lock_xp );
    304             xlist_unlink( XPTR( client_cxy , &client_ptr->wait_list ) );
    305             remote_spinlock_unlock( lock_xp );
    306 
    307326            // unblock client thread
    308327            thread_unblock( client_xp , THREAD_BLOCKED_IO );
     
    343362    chdev_t     * chdev_ptr;
    344363
     364    assert( (file_xp != XPTR_NULL) , __FUNCTION__,
     365    "file_xp == XPTR_NULL\n" );
     366
    345367    // get cluster and local pointer on remote file descriptor
    346368    // associated inode and chdev are stored in same cluster as the file desc.
     
    353375
    354376    assert( (inode_type == INODE_TYPE_DEV) , __FUNCTION__ ,
    355     "inode type %d is not INODE_TYPE_DEV", inode_type );
     377    "inode type %d is not INODE_TYPE_DEV\n", inode_type );
    356378
    357379    // get chdev local pointer from inode extension
Note: See TracChangeset for help on using the changeset viewer.