Changeset 416 for trunk/kernel/kern


Ignore:
Timestamp:
Jan 4, 2018, 10:05:47 AM (7 years ago)
Author:
alain
Message:

Improve sys_exec.

Location:
trunk/kernel/kern
Files:
10 edited

Legend:

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

    r409 r416  
    228228}
    229229
    230 ////////////////////////////////////////////////
    231 error_t cluster_pid_alloc( xptr_t    process_xp,
    232                            pid_t   * pid )
    233 {
    234     error_t     error;
     230///////////////////////////////////////////////
     231error_t cluster_pid_alloc( process_t * process,
     232                           pid_t     * pid )
     233{
    235234    lpid_t      lpid;
    236235    bool_t      found;
     
    255254    {
    256255        // register process in pref_tbl[]
    257         pm->pref_tbl[lpid] = process_xp;
     256        pm->pref_tbl[lpid] = XPTR( local_cxy , process );
    258257        pm->pref_nr++;
    259258
     
    261260        *pid = PID( local_cxy , lpid );
    262261
    263         error = 0;
     262        // release the processs_manager lock
     263        spinlock_unlock( &pm->pref_lock );
     264
     265        return 0;
    264266    }
    265267    else
    266268    {
    267         error = EAGAIN;
    268     }
    269 
    270     // release the processs_manager lock
    271     spinlock_unlock( &pm->pref_lock );
    272 
    273     return error;
     269        // release the processs_manager lock
     270        spinlock_unlock( &pm->pref_lock );
     271
     272        return -1;
     273    }
    274274
    275275} // end cluster_pid_alloc()
     
    286286    assert( (lpid < CONFIG_MAX_PROCESS_PER_CLUSTER) && (owner_cxy == local_cxy) ,
    287287    __FUNCTION__ , "illegal PID" );
    288 
    289     // check number of copies
    290     assert( (pm->copies_nr[lpid] == 0) ,
    291     __FUNCTION__ , "number of copies must be 0" ); 
    292288
    293289    // get the process manager lock
  • trunk/kernel/kern/cluster.h

    r409 r416  
    197197 * It registers the process descriptor extended pointer in the local processs manager
    198198 * pref_tbl[] array. This function is called by the process_make_fork() function,
    199  * or by the process_init_create() function.
    200  ******************************************************************************************
    201  * @ process    : [in]  extended pointer on the process descriptor.
     199 * by the process_make_exec() function, and by the process_init_create() function.
     200 ******************************************************************************************
     201 * @ process    : pointer on process descriptor.
    202202 * @ pid        : [out] allocated PID.
    203  * @ return 0 if success / return EAGAIN if no PID slot available
    204  *****************************************************************************************/
    205 error_t cluster_pid_alloc( xptr_t    process_xp,
    206                            pid_t   * pid );
     203 * @ return 0 if success / return -1 if no PID slot available.
     204 *****************************************************************************************/
     205error_t cluster_pid_alloc( struct process_s * process,
     206                           pid_t            * pid );
    207207
    208208/******************************************************************************************
  • trunk/kernel/kern/process.c

    r415 r416  
    337337    pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    338338
    339     // get the lock protecting the list of local process descriptors
     339    // remove the process descriptor from local_list in cluster manager
    340340    remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) );
    341 
    342     // remove the process descriptor from local_list in local cluster manager
    343341    xlist_unlink( XPTR( local_cxy , &process->local_list ) );
    344 
    345     // release the lock protecting the list of local process descriptors
    346342    remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) );
    347343
     
    356352    remote_spinlock_unlock( copies_lock );
    357353
     354    // release the process PID to cluster manager
     355    cluster_pid_release( process->pid );
     356
    358357        hal_fence();
    359358
     
    370369    vmm_destroy( process );
    371370
    372         process_dmsg("\n[DBG] %s for pid %d / page_faults = %d\n",
    373                  __FUNCTION__ , process->pid, process->vmm.pgfault_nr );
     371    // release memory allocated to process descriptor
     372    process_free( process );
    374373
    375374}  // end process_destroy()
     
    393392    xptr_t             root_xp;           // extended pointer on root of copies
    394393    xptr_t             lock_xp;           // extended pointer on lock protecting copies
    395     xptr_t             client_xp;         // extended pointer on client thread
    396     uint32_t           rsp_count;         // number of expected responses
    397     xptr_t             rsp_xp;            // extended pointer on responses counter
    398394    xptr_t             iter_xp;           // iterator on copies list
    399395    xptr_t             process_xp;        // extended pointer on process copy
    400396    cxy_t              process_cxy;       // process copy cluster identifier
    401397    process_t        * process_ptr;       // local pointer on process copy
    402 
    403 sigaction_dmsg("\n[DBG] %s : enter for signal %s to process %x in cluster %x\n",
    404 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
    405 
    406     thread_t         * this = CURRENT_THREAD;
    407 
    408     // get extended pointer on client thread and response counter
    409     client_xp = XPTR( local_cxy , this );
    410     rsp_xp    = XPTR( local_cxy , &rsp_count );
     398    uint32_t           responses;         // number of remote process copies
     399    uint32_t           rsp_count;         // used to assert number of copies
     400
     401    rpc_desc_t         rpc;               // rpc descriptor allocated in stack
     402
     403sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n",
     404__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
     405
     406    thread_t         * client = CURRENT_THREAD;
     407    xptr_t             client_xp = XPTR( local_cxy , client );
     408
     409    // get local pointer on local cluster manager
     410    cluster = LOCAL_CLUSTER;
    411411
    412412    // get owner cluster identifier and process lpid
     
    414414    lpid      = LPID_FROM_PID( process->pid );
    415415
    416     assert( (owner_cxy == local_cxy) , __FUNCTION__ , "illegal cluster\n" );
     416    // check owner cluster
     417    assert( (owner_cxy == local_cxy) , __FUNCTION__ ,
     418    "must be executed in the owner cluster\n" );
    417419   
    418     // get local pointer on local cluster manager
    419     cluster = LOCAL_CLUSTER;
     420    // get number of remote copies
     421    responses = cluster->pmgr.copies_nr[lpid] - 1;
     422    rsp_count = 0;
     423
     424    // check action type
     425    assert( ((action_type == DELETE_ALL_THREADS ) ||
     426             (action_type == BLOCK_ALL_THREADS )  ||
     427             (action_type == UNBLOCK_ALL_THREADS )),
     428             __FUNCTION__ , "illegal action type" );
     429             
     430    // initialise rpc descriptor
     431    rpc.index    = RPC_PROCESS_SIGACTION;
     432    rpc.response = responses;
     433    rpc.blocking = false;
     434    rpc.thread   = client;
    420435
    421436    // get extended pointers on copies root, copies lock, and number of copies
     
    423438    lock_xp   = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] );
    424439
    425     // initialize responses number
    426     rsp_count = cluster->pmgr.copies_nr[lpid];
    427 
    428440    // take the lock protecting the copies
    429441    remote_spinlock_lock( lock_xp );
    430442
    431     // send RPCs to all process copies
     443    // send RPCs to remote clusters
    432444    XLIST_FOREACH( root_xp , iter_xp )
    433445    {
     
    436448        process_ptr = (process_t *)GET_PTR( process_xp );
    437449
    438 sigaction_dmsg("\n[DBG] %s : process = %x / pid = %x / ppid = %x\n",
    439 __FUNCTION__ , process_ptr , process_ptr->pid , process_ptr->ppid );
    440 
    441         rpc_process_sigaction_client( process_cxy,
    442                                       process_ptr,
    443                                       action_type,
    444                                       rsp_xp,
    445                                       client_xp );
     450        // send RPC to remote clusters
     451        if( process_cxy != local_cxy ) 
     452        {
     453
     454sigaction_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n",
     455__FUNCTION__ , process_cxy );
     456
     457            rpc.args[0] = (uint64_t)action_type;
     458            rpc.args[1] = (uint64_t)(intptr_t)process_ptr;
     459            rpc_process_sigaction_client( process_cxy , &rpc );
     460            rsp_count++;
     461        }
    446462    }
    447463   
     
    449465    remote_spinlock_unlock( lock_xp );
    450466
    451     // block and deschedule to wait response
    452     thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
    453     sched_yield("BLOCKED on RPC");
    454 
    455 sigaction_dmsg("\n[DBG] %s : exit for signal %s to process %x in cluster %x\n",
    456 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy );
     467    // check number of copies...
     468    assert( (rsp_count == responses) , __FUNCTION__ ,
     469    "unconsistent number of process copies : rsp_count = %d / responses = %d",
     470    rsp_count , responses );
     471
     472    // block and deschedule to wait RPC responses if required
     473    if( responses )
     474    {   
     475        thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC );
     476        sched_yield("BLOCKED on RPC_PROCESS_SIGACTION");
     477    }
     478
     479sigaction_dmsg("\n[DBG] %s : make action in owner cluster %x\n",
     480__FUNCTION__ , local_cxy );
     481
     482
     483    // call directly the relevant function in local owner cluster
     484    if      (action_type == DELETE_ALL_THREADS  ) process_delete ( process , client_xp );
     485    else if (action_type == BLOCK_ALL_THREADS   ) process_block  ( process , client_xp );
     486    else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock( process             );
     487
     488sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n",
     489__FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy );
    457490
    458491}  // end process_sigaction()
     
    460493////////////////////////////////////////
    461494void process_block( process_t * process,
    462                     xptr_t      rsp_xp,
    463495                    xptr_t      client_xp )
    464496{
    465497    thread_t          * target;         // pointer on target thread
    466498    uint32_t            ltid;           // index in process th_tbl
    467     thread_t          * killer;         // killer thread pointer
     499    thread_t          * requester;      // requesting thread pointer
    468500    uint32_t            count;          // requests counter
    469     volatile uint32_t   sig_rsp_count;  // responses counter
    470     cxy_t               client_cxy;     // client thread cluster identifier
    471     thread_t          * client_ptr;     // client thread pointer
    472     core_t            * client_core;    // client thread core pointer
    473 
    474     // get local killer thread pointer
    475     killer = CURRENT_THREAD;
     501    volatile uint32_t   rsp_count;      // responses counter
     502
     503    // get calling thread pointer
     504    requester = CURRENT_THREAD;
    476505
    477506sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     
    482511
    483512    // initialize local responses counter
    484     sig_rsp_count = process->th_nr;
     513    rsp_count = process->th_nr;
    485514
    486515    // loop on process threads to block and deschedule all threads in cluster
     
    494523            count++;
    495524
    496             // set signal in target thread descriptor
    497             thread_set_signal( target , (uint32_t *)sig_rsp_count );
    498 
    499             // set the global blocked bit in target thread descriptor.
    500             thread_block( target , THREAD_BLOCKED_GLOBAL );
    501 
    502             // - if the killer thread and the target thread are not on the same core
    503             //   we want the scheduler of target thread to acknowlege the signal
    504             //   to be sure that the target thread is descheduled
    505             // - if the killer thread and the target thread are on the same core
    506             //   we simply decrement the response counter.
    507             if( killer->core->lid != target->core->lid )
     525            // - if the target thread is the client thread, we do nothing,
     526            //   and simply decrement the responses counter.
     527            // - if the calling thread and the target thread are on the same core,
     528            //   we block the target thread, we don't ask ask anything to the scheduler,
     529            //   and simply decrement the responses counter.
     530            // - if the calling thread and the target thread are not running on the same
     531            //   core, we ask the target scheduler to acknowlege the blocking
     532            //   to be sure that the target thread is not running.
     533           
     534            if( XPTR( local_cxy , target ) == client_xp )
    508535            {
     536                // decrement responses counter
     537                hal_atomic_add( (void *)&rsp_count , -1 );
     538            }
     539            else if( requester->core->lid == target->core->lid )
     540            {
     541                // set the global blocked bit in target thread descriptor.
     542                thread_block( target , THREAD_BLOCKED_GLOBAL );
     543
     544                // decrement responses counter
     545                hal_atomic_add( (void *)&rsp_count , -1 );
     546            }
     547            else
     548            {
     549                // set the global blocked bit in target thread descriptor.
     550                thread_block( target , THREAD_BLOCKED_GLOBAL );
     551
     552                // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor
     553                thread_set_req_ack( target , (void *)&rsp_count );
     554
     555                // force scheduling on target thread
    509556                dev_pic_send_ipi( local_cxy , target->core->lid );
    510557            }
    511             else                                                         
    512             {
    513                 hal_atomic_add( (void *)&sig_rsp_count , -1 );
    514             }
    515558        }
    516559    }
    517560
    518     // poll the reponses counter
     561    // get lock protecting process th_tbl[]
     562    spinlock_unlock( &process->th_lock );
     563
     564    // wait all responses from schedulers
    519565    while( 1 )
    520566    {
    521         // exit loop when all responses received
    522         if ( sig_rsp_count == 0 ) break;
     567        // exit loop when all local responses received
     568        if ( rsp_count == 0 ) break;
    523569   
    524570        // wait 1000 cycles before retry
     
    526572    }
    527573
    528     // acknowledge client thread & unblock client thread if last response
    529     client_cxy  = GET_CXY( client_xp );
    530     client_ptr  = (thread_t *)GET_PTR( client_xp );
    531     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    532     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    533     {
    534         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    535         dev_pic_send_ipi( client_cxy , client_core->lid );
    536     }
    537 
    538574sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
    539575__FUNCTION__ , process->pid , local_cxy , count );
     
    541577}  // end process_block()
    542578
    543 //////////////////////////////////////////
    544 void process_unblock( process_t * process,
    545                       xptr_t      rsp_xp,
    546                       xptr_t      client_xp )
     579///////////////////////////////////////////
     580void process_unblock( process_t * process )
    547581{
    548582    thread_t          * target;        // pointer on target thead
    549583    uint32_t            ltid;          // index in process th_tbl
    550     thread_t          * killer;        // killer thread pointer
    551     uint32_t            req_count;     // requests counter
    552     cxy_t               client_cxy;    // client thread cluster identifier
    553     thread_t          * client_ptr;    // client thread pointer
    554     core_t            * client_core;   // client thread core pointer
    555 
    556     // get local killer thread pointer
    557     killer = CURRENT_THREAD;
     584    uint32_t            count;         // requests counter
    558585
    559586sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n",
     
    564591
    565592    // loop on process threads to unblock all threads in cluster
    566     // we use both "ltid" and "req_count" because it can exist "holes" in th_tbl
    567     for( ltid = 0 , req_count = 0 ;
    568          req_count < process->th_nr ;
    569          ltid++ )
     593    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
     594    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
    570595    {
    571596        target = process->th_tbl[ltid];
     
    573598        if( target != NULL )             // thread found
    574599        {
    575             req_count++;
     600            count++;
    576601
    577602            // reset the global blocked bit in target thread descriptor.
     
    580605    }
    581606
    582     // acknowledge client thread & unblock client thread if last response
    583     client_cxy  = GET_CXY( client_xp );
    584     client_ptr  = (thread_t *)GET_PTR( client_xp );
    585     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    586     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    587     {
    588         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    589         dev_pic_send_ipi( client_cxy , client_core->lid );
    590     }
     607    // get lock protecting process th_tbl[]
     608    spinlock_unlock( &process->th_lock );
    591609
    592610sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n",
    593 __FUNCTION__ , process->pid , local_cxy , req_count );
     611__FUNCTION__ , process->pid , local_cxy , count );
    594612
    595613}  // end process_unblock()
     
    597615/////////////////////////////////////////
    598616void process_delete( process_t * process,
    599                      xptr_t      rsp_xp,
    600617                     xptr_t      client_xp )
    601618{
    602     thread_t          * thread;        // pointer on target thread
     619    thread_t          * target;        // pointer on target thread
    603620    uint32_t            ltid;          // index in process th_tbl
    604621    uint32_t            count;         // request counter
    605     pid_t               pid;           // process PID
    606     cxy_t               client_cxy;    // client thread cluster identifier
    607     thread_t          * client_ptr;    // client thread pointer
    608     core_t            * client_core;   // client thread core pointer
    609 
    610     // get process PID
    611     pid = process->pid;
     622    thread_t          * requester;     // pointer on calling thread
    612623
    613624sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n",
    614 __FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
    615 
    616     // loop on threads to release memory allocated to threads
     625__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
     626
     627    // get calling thread pointer
     628    requester = CURRENT_THREAD;
     629
     630    // get lock protecting process th_tbl[]
     631    spinlock_lock( &process->th_lock );
     632
     633    // loop on threads to set the REQ_DELETE flag
     634    // we use both "ltid" and "count" because it can exist "holes" in th_tbl
    617635    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
    618636    {
    619         thread = process->th_tbl[ltid];
    620 
    621         if( thread != NULL )             // thread found
     637        target = process->th_tbl[ltid];
     638
     639        if( target != NULL )             // thread found
    622640        {
    623641            count++;
    624642
    625             // detach thread from parent if attached
    626             if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
    627             thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
    628 
    629             // detach thread from process
    630             process_remove_thread( thread );
    631 
    632             // remove thread from scheduler
    633             sched_remove_thread( thread );
    634 
    635             // release memory allocated to thread
    636             thread_destroy( thread );
     643            // delete only if the target is not the client
     644            if( XPTR( local_cxy , target ) != client_xp )
     645            {
     646                hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE );
     647            }
    637648        }
    638649    }
    639650
    640     // release memory allocated to process descriptors
    641     // for all clusters other than the owner cluster
    642     if( local_cxy != CXY_FROM_PID( process->pid ) ) process_destroy( process );
    643 
    644     // acknowledge client thread & unblock client thread if last response
    645     client_cxy  = GET_CXY( client_xp );
    646     client_ptr  = (thread_t *)GET_PTR( client_xp );
    647     client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
    648     if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )
    649     {
    650         thread_unblock( client_xp , THREAD_BLOCKED_RPC);
    651         dev_pic_send_ipi( client_cxy , client_core->lid );
    652     }
     651    // get lock protecting process th_tbl[]
     652    spinlock_unlock( &process->th_lock );
    653653
    654654sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x at cycle %d\n",
    655 __FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() );
     655__FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() );
    656656
    657657}  // end process_delete()
     
    951951
    952952    // allocate a child PID from local cluster
    953     error = cluster_pid_alloc( XPTR( local_cxy , process ) , &new_pid );
     953    error = cluster_pid_alloc( process , &new_pid );
    954954    if( (error != 0) || (new_pid == 0) )
    955955    {
     
    10371037    return 0;
    10381038
    1039 }  // end process_make_fork()
    1040 
    1041 /*  deprecated because we don't wand to destroy the existing process descriptor
     1039}   // end process_make_fork()
     1040
    10421041
    10431042/////////////////////////////////////////////////////
     
    10451044{
    10461045    char           * path;                    // pathname to .elf file
    1047     process_t      * old;                     // local pointer on old process
    1048     process_t      * new;                     // local pointer on new process
    1049     pid_t            pid;                     // old process identifier
    1050     thread_t       * thread;                  // pointer on new thread
     1046    process_t      * old_process;             // local pointer on old process
     1047    process_t      * new_process;             // local pointer on new process
     1048    pid_t            old_pid;                 // old process identifier
     1049    pid_t            new_pid;                 // new (temporary) process identifier
     1050    thread_t       * old_thread;              // pointer on new thread
     1051    thread_t       * new_thread;              // pointer on new thread
    10511052    pthread_attr_t   attr;                    // main thread attributes
    10521053    lid_t            lid;                     // selected core local index
     
    10541055
    10551056        // get .elf pathname and PID from exec_info
    1056         path = exec_info->path;
    1057     pid  = exec_info->pid;
    1058 
    1059     // check local cluster is process owner
    1060     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1061     "local cluster %x is not owner for process %x\n", local_cxy, pid );
     1057        path     = exec_info->path;
     1058    old_pid  = exec_info->pid;
     1059
     1060    // this function must be executed by a thread running in owner cluster
     1061    assert( (CXY_FROM_PID( old_pid ) == local_cxy), __FUNCTION__,
     1062    "local cluster %x is not owner for process %x\n", local_cxy, old_pid );
    10621063
    10631064exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
    1064 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path );
    1065 
    1066     // get old process local pointer
    1067     old = (process_t *)cluster_get_local_process_from_pid( pid );
     1065__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, old_pid , path );
     1066
     1067    // get old process and thread local pointers
     1068    old_process = (process_t *)cluster_get_local_process_from_pid( old_pid );
     1069    old_thread  = CURRENT_THREAD;
    10681070   
    1069     assert( (old != NULL ) , __FUNCTION__ ,
    1070     "process %x not found in cluster %x\n", pid , local_cxy );
     1071    if( old_process == NULL )
     1072    {
     1073        printk("\n[ERROR] in %s : cannot get old process descriptor\n", __FUNCTION__ );
     1074        return -1;
     1075    }
    10711076
    10721077    // allocate memory for new process descriptor
    1073     new = process_alloc();
     1078    new_process = process_alloc();
     1079
     1080    if( new_process == NULL )
     1081    {
     1082        printk("\n[ERROR] in %s : cannot allocate new process descriptor\n", __FUNCTION__ );
     1083        return -1;
     1084    }
     1085
     1086    // get a (temporary) PID for new process
     1087    error = cluster_pid_alloc( new_process , &new_pid );
     1088
     1089    if( error )
     1090    {
     1091        printk("\n[ERROR] in %s : cannot allocate a temporary PID\n", __FUNCTION__ );
     1092        process_destroy( new_process );
     1093        return -1;
     1094    }
    10741095
    10751096    // initialize new process descriptor
    1076     process_reference_init( new,
    1077                             old->pid,                   // same as old
    1078                             old->ppid,                  // same as old
    1079                             XPTR( local_cxy , old ) );
     1097    process_reference_init( new_process,
     1098                            new_pid,                            // temporary PID
     1099                            old_process->ppid,                  // same parent
     1100                            XPTR( local_cxy , old_process ) );
    10801101
    10811102exec_dmsg("\n[DBG] %s : core[%x,%d] created new process %x / path = %s\n",
    1082 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );
     1103__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_pid, path );
    10831104
    10841105    // register "code" and "data" vsegs as well as entry-point
    10851106    // in new process VMM, using information contained in the elf file.
    1086         if( elf_load_process( path , new ) )
     1107        if( elf_load_process( path , new_process ) )
    10871108        {
    10881109                printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    1089                 __FUNCTION__, pid , path );
    1090         process_destroy( new );
     1110                __FUNCTION__, new_pid , path );
     1111        cluster_pid_release( new_pid );
     1112        process_destroy( new_process );
    10911113        return -1;
    10921114        }
     
    11041126
    11051127    // create and initialize thread descriptor
    1106         error = thread_user_create( pid,
    1107                                 (void *)new->vmm.entry_point,
     1128        error = thread_user_create( new_pid,
     1129                                (void *)new_process->vmm.entry_point,
    11081130                                exec_info->args_pointers,
    11091131                                &attr,
    1110                                 &thread );
     1132                                &new_thread );
    11111133        if( error )
    11121134        {
    11131135                printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    1114                        __FUNCTION__, pid , path );
    1115         process_destroy( new );
     1136            __FUNCTION__, new_pid , path );
     1137        cluster_pid_release( new_pid );
     1138        process_destroy( new_process );
    11161139        return -1;
    11171140        }
    11181141
    1119 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n",
    1120 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid );
    1121 
    1122     // update children list (rooted in parent process)
    1123         xlist_replace( XPTR( local_cxy , &old->brothers_list ) ,
    1124                    XPTR( local_cxy , &new->brothers_list ) );
    1125 
    1126     // request destruction of old process copies and threads in all clusters
    1127     process_sigaction( old , SIGKILL );
    1128 
     1142exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x\n",
     1143__FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_thread->trdid );
     1144
     1145    // update children list rooted in parent process
     1146        xlist_replace( XPTR( local_cxy , &old_process->brothers_list ) ,
     1147                   XPTR( local_cxy , &new_process->brothers_list ) );
     1148
     1149    // request blocking for all threads in old process (but the calling thread)
     1150    process_sigaction( old_process , BLOCK_ALL_THREADS );
     1151
     1152    // request destruction for all threads in old process (but the calling thread)
     1153    process_sigaction( old_process , DELETE_ALL_THREADS );
     1154
     1155    // update PID for both processes
     1156    new_process->pid = old_pid;
     1157    old_process->pid = 0xFFFFFFFF;
     1158
     1159    // release temporary PID
     1160    cluster_pid_release( new_pid );
     1161   
    11291162    // activate new thread
    1130         thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
     1163        thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL );
    11311164
    11321165exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
    11331166__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
    11341167
     1168    // set BLOCKED_GLOBAL bit
     1169    thread_block( old_thread , THREAD_BLOCKED_GLOBAL );
     1170
     1171    // set REQ_DELETE flag
     1172    hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE );
     1173
     1174    // deschedule
     1175    sched_yield("suicide after exec");
     1176
     1177    // never executed but required by compiler
    11351178        return 0;
    11361179
    11371180}  // end process_make_exec()
    11381181
    1139 */
    1140 
    1141 /////////////////////////////////////////////////////
    1142 error_t process_make_exec( exec_info_t  * exec_info )
    1143 {
    1144     char           * path;                    // pathname to .elf file
    1145     process_t      * process;                 // local pointer on old process
    1146     pid_t            pid;                     // old process identifier
    1147     thread_t       * thread;                  // pointer on new main thread
    1148     pthread_attr_t   attr;                    // main thread attributes
    1149     lid_t            lid;                     // selected core local index
    1150         error_t          error;
    1151 
    1152         // get .elf pathname and PID from exec_info
    1153         path = exec_info->path;
    1154     pid  = exec_info->pid;
    1155 
    1156     // check local cluster is process owner
    1157     assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,
    1158     "local cluster %x is not owner for process %x\n", local_cxy, pid );
    1159 
    1160 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n",
    1161 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path );
    1162 
    1163     // get process local pointer
    1164     process = (process_t *)cluster_get_local_process_from_pid( pid );
    1165    
    1166     assert( (process != NULL ) , __FUNCTION__ ,
    1167     "process %x not found in cluster %x\n", pid , local_cxy );
    1168 
    1169     // reset the existing vmm
    1170     vmm_destroy( process );
    1171 
    1172 exec_dmsg("\n[DBG] %s : core[%x,%d] VMM cleared\n",
    1173 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
    1174 
    1175     // block all existing process threads
    1176     process_sigaction( process , BLOCK_ALL_THREADS );
    1177 
    1178     // kill all existing threads and process descriptors (other than owner)
    1179     process_sigaction( process , DELETE_ALL_THREADS );
    1180 
    1181     // check no threads
    1182     assert( (process->th_nr == 0) , __FUNCTION__ , "no threads at this point" );
    1183 
    1184 exec_dmsg("\n[DBG] %s : core[%x,%d] all threads deleted\n",
    1185 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid );
    1186 
    1187     // initialize VMM
    1188     error = vmm_init( process );
    1189         {
    1190                 printk("\n[ERROR] in %s : cannot initialize VMM for process %x / path = %s\n",
    1191                 __FUNCTION__, pid , path );
    1192         process_destroy( process );
    1193         return -1;
    1194         }
    1195 
    1196     if( error )
    1197 
    1198     // register "code" and "data" vsegs as well as entry-point and vfs_bin_xp
    1199     // in VMM, using information contained in the elf file.
    1200         error = elf_load_process( path , process );
    1201 
    1202     if( error )
    1203         {
    1204                 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n",
    1205                 __FUNCTION__, pid , path );
    1206         process_destroy( process );
    1207         return -1;
    1208         }
    1209 
    1210 exec_dmsg("\n[DBG] %s : core[%x,%d] new vsegs registered / path = %s\n",
    1211 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path );
    1212 
    1213 // @@@
    1214 vmm_display( process , true );
    1215 // @@@
    1216 
    1217     // select a core in local cluster to execute the new main thread
    1218     lid  = cluster_select_local_core();
    1219 
    1220     // initialize pthread attributes for new main thread
    1221     attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED;
    1222     attr.cxy        = local_cxy;
    1223     attr.lid        = lid;
    1224 
    1225     // create and initialize thread descriptor
    1226         error = thread_user_create( pid,
    1227                                 (void *)process->vmm.entry_point,
    1228                                 exec_info->args_pointers,
    1229                                 &attr,
    1230                                 &thread );
    1231         if( error )
    1232         {
    1233                 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n",
    1234                        __FUNCTION__, pid , path );
    1235         process_destroy( process );
    1236         return -1;
    1237         }
    1238 
    1239 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n",
    1240 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid );
    1241 
    1242     // activate new thread
    1243         thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );
    1244 
    1245 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n",
    1246 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path  );
    1247 
    1248         return 0;
    1249 
    1250 }  // end process_make_exec()
    1251 
    1252 ////////////////////////////////////////////
    1253 void process_make_kill( process_t * process,
    1254                         uint32_t    sig_id )
     1182///////////////////////////////////////
     1183void process_make_kill( pid_t      pid,
     1184                        uint32_t   sig_id )
    12551185{
    12561186    // this function must be executed by a thread running in owner cluster
    1257     assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1187    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
    12581188    "must execute in owner cluster" );
     1189
     1190kill_dmsg("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d\n",
     1191__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );
     1192
     1193    // get pointer on local process descriptor
     1194    process_t * process = process_get_local_copy( pid );
     1195
     1196    // does nothing if process does not exist
     1197    if( process == NULL )
     1198    {
     1199        printk("\n[WARNING] %s : process %x does not exist => do nothing\n",
     1200        __FUNCTION__ , pid );
     1201        return;
     1202    }
    12591203
    12601204    // analyse signal type
    12611205    switch( sig_id )
    12621206    {
    1263         case SIGSTOP:     // block all threads
     1207        case SIGSTOP:     // block all threads in all clusters
    12641208        {
    12651209            process_sigaction( process , BLOCK_ALL_THREADS );
    12661210        }
    12671211        break;
    1268         case SIGCONT:     // unblock all threads
     1212        case SIGCONT:     // unblock all threads in all clusters
    12691213        {
    12701214            process_sigaction( process , UNBLOCK_ALL_THREADS );
     
    12731217        case SIGKILL:  // block all threads, then delete all threads
    12741218        {
     1219            // block all threads (but the calling thread)
    12751220            process_sigaction( process , BLOCK_ALL_THREADS );
     1221
     1222            // delete all threads (but the calling thread)
    12761223            process_sigaction( process , DELETE_ALL_THREADS );
    1277             process_destroy( process );
     1224
     1225            // delete the calling thread if required
     1226            thread_t * this = CURRENT_THREAD;
     1227
     1228            if( this->process == process )
     1229            {
     1230                // set REQ_DELETE flag
     1231                hal_atomic_or( &this->flags , THREAD_FLAG_REQ_DELETE );
     1232
     1233                // deschedule
     1234                sched_yield( "suicide after kill" );
     1235            }
    12781236        }
    12791237        break;
    12801238    }
     1239
     1240//@@@
     1241sched_display( 0 );
     1242//@@@
     1243
     1244kill_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d \n",
     1245__FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id );
     1246
    12811247}  // end process_make_kill()
    12821248
    1283 ////////////////////////////////////////////
    1284 void process_make_exit( process_t * process,
     1249/////////////////////////////////////////
     1250void process_make_exit( pid_t       pid,
    12851251                        uint32_t    status )
    12861252{
    12871253    // this function must be executed by a thread running in owner cluster
    1288     assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ ,
     1254    assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ ,
    12891255    "must execute in owner cluster" );
    12901256
    1291     // block all threads in all clusters
     1257    // get pointer on local process descriptor
     1258    process_t * process = process_get_local_copy( pid );
     1259
     1260    // does nothing if process does not exist
     1261    if( process == NULL )
     1262    {
     1263        printk("\n[WARNING] %s : process %x does not exist => do nothing\n",
     1264        __FUNCTION__ , pid );
     1265        return;
     1266    }
     1267
     1268    // block all threads in all clusters (but the calling thread)
    12921269    process_sigaction( process , BLOCK_ALL_THREADS );
    12931270
    1294     // delete all threads in all clusters
     1271    // delete all threads in all clusters (but the calling thread)
    12951272    process_sigaction( process , DELETE_ALL_THREADS );
    12961273
    1297     // delete local process descriptor
    1298     process_destroy( process );
     1274    // delete the calling thread
     1275    hal_atomic_or( &CURRENT_THREAD->flags , THREAD_FLAG_REQ_DELETE );
     1276
     1277    // deschedule
     1278    sched_yield( "suicide after exit" );
    12991279
    13001280}  // end process_make_exit()
     
    13221302
    13231303    // get PID from local cluster
    1324     error = cluster_pid_alloc( XPTR( local_cxy , process ) , &pid );
     1304    error = cluster_pid_alloc( process , &pid );
    13251305    if( error )
    13261306    {
  • trunk/kernel/kern/process.h

    r415 r416  
    267267
    268268/*********************************************************************************************
    269  * This function allows any thread running in any cluster to block, unblock  or delete
    270  * all threads of a given process identified by the <process> argument, dependig on the
    271  * <acion_type> argument.
    272  * It can be called by the sys_kill() or sys_exit() functions to handle the "kill" & "exit"
    273  * system calls, or by the process_make_exec() function to handle the "exec" system call.
    274  * It must be executed in the owner cluster for the target process (using the relevant RPC
    275  * (RPC_PROCESS_SIGNAL or RPC_PROCESS_EXEC) if the client thread in not running in the
    276  * owner cluster.
    277  * It uses the multicast, non blocking, RPC_PROCESS_KILL to send the signal to all process
    278  * copies in parallel, block & deschedule when all signals have been sent, and finally
    279  * returns only when all responses have been received and the operation is completed.
    280  *********************************************************************************************
    281  * @ process     : pointer on the process descriptor.
    282  * @ action_type   : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS
     269 * This function allows a client thread running in the owner cluster of a process identified
     270 * by the <process> argument to block, unblock or delete all threads of the target process,
     271 * depending on the <action_type> argument.  The scenario is the following:
     272 * - It uses the multicast, non blocking rpc_process_sigaction_client() function to send
     273 *   parallel requests to all remote clusters containing a process copy. Then it blocks
     274 $   and deschedule to wait completion of these parrallel requests.
     275 * - In each remote cluster, the rpc_process_sigaction_server() function, calls directly
     276 *   the relevant process_block(), process_unblock(), or process_delete() function, and
     277 *   decrement the responses counter to signal completion. The last server unblock
     278 *   the client thread.
     279 * - Finally, the client thread calls directly the process_block(), process_unblock(), or
     280 *   process_delete() function in the owner cluster.
     281 * It is used by the sys_kill() & sys_exit() functions to handle the "kill" & "exit" syscalls.
     282 * It is also used by the process_make_exec() function to handle the "exec" syscall.
     283 * WARNING : the DELETE and the BLOCK actions are NOT executed on the client thread.
     284 *********************************************************************************************
     285 * @ process     : pointer on the process descriptor in owner cluster.
     286 * @ action_type : BLOCK_ALL_THREADS / UNBLOCK_ALL_THREADS / DELETE_ALL_THREADS
    283287 ********************************************************************************************/
    284288void process_sigaction( process_t * process,
     
    287291/*********************************************************************************************
    288292 * This function blocks all threads of a given user process in a given cluster.
    289  * It is always called by a local RPC thread, through the multicast RPC_PROCESS_KILL.
    290  * It loop on all local threads of the process, requesting the relevant schedulers to
    291  * block and deschedule these threads, using IPI if required. The threads are not detached
    292  * from the scheduler, and not detached from the local process.
    293  * It acknowledges the client thread in the owner cluster only when all process threads
    294  * are descheduled and blocked on the BLOCKED_GLOBAL condition, using the <rsp_xp> argument.
     293 * It loops on all local threads of the process, set the THREAD_BLOCKED_GLOBAL bit,
     294 * and request the relevant schedulers to acknowledge the blocking, using IPI if required.
     295 * The threads are not detached from the scheduler, and not detached from the local process.
     296 * This function returns only when all blockable threads in cluster are actually blocked.
     297 * WARNING : the client thread defined by the <client_xp> argument is NOT blocked.
    295298 *********************************************************************************************
    296299 * @ process     : pointer on the target process descriptor.
    297  * @ rsp_xp      : extended pointer on the response counter.
    298  * # client_xp   : extended pointer on client thread descriptor.
     300 * @ client_xp   : extended pointer on the client thread, that should not be blocked.
    299301 ********************************************************************************************/
    300302void process_block( process_t * process,
    301                     xptr_t      rsp_xp,
    302303                    xptr_t      client_xp );
    303304
    304305/*********************************************************************************************
    305306 * This function unblocks all threads of a given user process in a given cluster.
    306  * It is always called by a local RPC thread, through the multicast RPC_PROCESS_KILL.
    307  * It loops on local threads of the process, to reset the BLOCKED_GLOBAL bit in all threads.
    308  * It acknowledges directly the client thread in the owner cluster when this is done,
    309  * using the <rsp_xp> argument.
    310307 *********************************************************************************************
    311308 * @ process     : pointer on the process descriptor.
    312  * @ rsp_xp      : extended pointer on the response counter.
    313  * # client_xp   : extended pointer on client thread descriptor.
    314  ********************************************************************************************/
    315 void process_unblock( process_t * process,
    316                       xptr_t      rsp_xp,
    317                       xptr_t      client_xp );
    318 
    319 /*********************************************************************************************
    320  * This function delete all threads descriptors, of given user process in a given cluster.
    321  * It is always called by a local RPC thread, through the multicast RPC_PROCESS_KILL.
    322  * It detach all process threads from the scheduler, detach the threads from the local
    323  * process, and release the local memory allocated to threads descriptors (including the
    324  * associated structures such as CPU and FPU context). Finally, it release the memory
    325  * allocated to the local process descriptor itself, but only when the local cluster
    326  * is NOT the process owner, but only a copy.  It acknowledges directly the client thread
    327  * in the owner cluster, using ithe <rsp_xp> argument.
     309 ********************************************************************************************/
     310void process_unblock( process_t * process );
     311
     312/*********************************************************************************************
     313 * This function delete all threads, of a given user process in a given cluster.
     314 * It loops on all local threads of the process, and set the THREAD_FLAG_REQ_DELETE bit.
     315 * For each marked thread, the following actions will be done by the scheduler at the next
     316 * scheduling point:
     317 * - the thread will be detached from the scheduler.
     318 * - the thread will be detached from the local process descriptor.
     319 * - the thread will be detached from parent if required.
     320 * - the memory allocated to the thread descriptor is released.
     321 * - the memory allocated to the process descriptor is released, if it is the last thread.
     322 * WARNING : the client thread defined by the <client_xp> argument is NOT deleted.
    328323 *********************************************************************************************
    329324 * @ process     : pointer on the process descriptor.
    330  * @ rsp_xp      : extended pointer on the response counter.
    331  * # client_xp   : extended pointer on client thread descriptor.
     325 * @ client_xp   : extended pointer on the client thread, that should not be deleted.
    332326 ********************************************************************************************/
    333327void process_delete( process_t * process,
    334                      xptr_t      rsp_xp,
    335328                     xptr_t      client_xp );
    336329
     
    392385 * It must be executed by a thread running in the calling process owner cluster.
    393386 * It uses twice the multicast RPC_PROCESS_SIGNAL to first block all process threads
    394  * in all clusters, and then delete all thread  and process descriptors.
    395  *********************************************************************************************
    396  * @ process  : pointer on process descriptor in owner cluster.
     387 * in all clusters, and then delete all threads and process descriptors.
     388 *********************************************************************************************
     389 * @ pid      : process identifier.
    397390 * @ status   : exit return value.
    398391 ********************************************************************************************/
    399 void process_make_exit( process_t * process,
     392void process_make_exit( pid_t       pid,
    400393                        uint32_t    status );
    401394
     
    408401 * all process threads in all clusters, and then delete process descriptors.
    409402 *********************************************************************************************
    410  * @ process  : pointer on process descriptor in owner cluster.
    411  * @ sig_id   : signal type.
    412  ********************************************************************************************/
    413 void process_make_kill( process_t * process,
    414                         uint32_t    sig_id );
     403 * @ pid     : process identifier.
     404 * @ sig_id  : signal type.
     405 ********************************************************************************************/
     406void process_make_kill( pid_t     pid,
     407                        uint32_t  sig_id );
    415408
    416409
  • trunk/kernel/kern/rpc.c

    r415 r416  
    9494///////////////////////////////////////
    9595void rpc_send( cxy_t        server_cxy,
    96                rpc_desc_t * rpc,
    97                bool_t       block )
     96               rpc_desc_t * rpc )
    9897{
    9998    error_t    error;
     
    106105    rpc->lid       = core->lid;
    107106
    108 printk("\n   @@@ enter %s : rpc_desc_cxy = %x / rpc_desc_ptr = %x / index = %d / &index = %x\n",
    109 __FUNCTION__ , local_cxy , rpc , rpc->index , &rpc->index);
    110  
    111107    // build an extended pointer on the RPC descriptor
    112108        xptr_t   desc_xp = XPTR( local_cxy , rpc );
     
    137133        dev_pic_send_ipi( server_cxy , core->lid );
    138134
    139     // wait RPC completion if blocking
     135    // wait RPC completion before returning if blocking RPC
    140136    // - busy waiting policy during kernel_init, or if threads cannot yield
    141137    // - block and deschedule in all other cases
    142     if ( block )
     138    if ( rpc->blocking )
    143139    {
    144140        if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
     
    178174        dev_pic_ack_ipi();
    179175    }
    180    
    181 printk("\n   @@@ exit %s : rpc_desc_cxy = %x / rpc_desc_ptr = %x / index = %d / &index = %x\n",
    182 __FUNCTION__ , local_cxy , rpc , rpc->index , &rpc->index);
    183  
    184176}  // end rpc_send()
    185177
     
    244236                    hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
    245237
    246 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n",
    247 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
     238grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / trdid %x / cycle %d\n",
     239__FUNCTION__ , local_cxy , core->lid , thread , thread->trdid , hal_time_stamp() );
    248240
    249241            }
    250242        }
    251243    }
    252 
    253 //@@@
    254 sched_display( 0 );
    255 //@@@
    256244
    257245grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n",
     
    279267    rpc_desc_t * desc_ptr;    // RPC request local pointer
    280268    uint32_t     index;       // RPC request index
    281     uint32_t     responses;   // number of responses received by client
    282269    thread_t   * thread_ptr;  // local pointer on client thread
    283270    lid_t        core_lid;    // local index of client core
     271    bool_t       blocking;    // blocking RPC when true
    284272 
    285273    // makes RPC thread not preemptable
     
    319307                    desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp );
    320308
    321                     // get rpc index from RPC descriptor
    322                         index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
    323 
    324 printk("\n   @@@ in %s : rpc_desc_cxy = %x / rpc_desc_ptr = %x / index = %d / &index = %x\n",
    325 __FUNCTION__ , desc_cxy , desc_ptr , index , &desc_ptr->index );
    326  
     309                    // get RPC <index> & <blocking> fields from RPC descriptor
     310                        index    = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
     311                    blocking = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->blocking ) );
     312
    327313grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n",
    328314__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , (uint32_t)hal_get_cycles() );
     
    334320__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
    335321
    336                     // increment handled RPC counter
     322                    // increment handled RPCs counter
    337323                        count++;
    338324
    339                     // decrement response counter in RPC descriptor
    340                     responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
    341 
    342                     // unblock client thread  and send IPI to client core if last response
    343                     if( responses == 1 )
    344                     {
    345                         // get pointer on client thread and unblock it
     325                    // decrement response counter in RPC descriptor if blocking
     326                    if( blocking )
     327                    {
     328                        // decrement responses counter in RPC descriptor
     329                        hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
     330
     331                        // unblock client thread
    346332                        thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread));
    347333                        thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC );
     
    363349            // release rpc_fifo ownership if not lost
    364350            if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
    365         }
     351
     352        }  // end if RPC fifo
    366353
    367354        // sucide if too many RPC threads in cluster
     
    412399    rpc.index    = RPC_PMEM_GET_PAGES;
    413400    rpc.response = 1;
     401    rpc.blocking = true;
    414402
    415403    // set input arguments in RPC descriptor
     
    417405
    418406    // register RPC request in remote RPC fifo (blocking function)
    419     rpc_send( cxy , &rpc  , true );
     407    rpc_send( cxy , &rpc );
    420408
    421409    // get output arguments from RPC descriptor
     
    470458    rpc.index    = RPC_PMEM_RELEASE_PAGES;
    471459    rpc.response = 1;
     460    rpc.blocking = true;
    472461
    473462    // set input arguments in RPC descriptor
     
    475464
    476465    // register RPC request in remote RPC fifo (blocking function)
    477     rpc_send( cxy , &rpc  , true );
     466    rpc_send( cxy , &rpc );
    478467
    479468rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    526515    rpc.index    = RPC_PROCESS_MAKE_EXEC;
    527516    rpc.response = 1;
     517    rpc.blocking = true;
    528518
    529519    // set input arguments in RPC descriptor 
     
    531521
    532522    // register RPC request in remote RPC fifo (blocking function)
    533     rpc_send( cxy , &rpc  , true );
     523    rpc_send( cxy , &rpc );
    534524
    535525    // get output arguments from RPC descriptor
     
    597587    rpc.index    = RPC_PROCESS_MAKE_FORK;
    598588    rpc.response = 1;
     589    rpc.blocking = true;
    599590
    600591    // set input arguments in RPC descriptor 
     
    603594
    604595    // register RPC request in remote RPC fifo (blocking function)
    605     rpc_send( cxy , &rpc  , true );
     596    rpc_send( cxy , &rpc );
    606597
    607598    // get output arguments from RPC descriptor
     
    658649///////////////////////////////////////////////////
    659650void rpc_process_make_exit_client( cxy_t       cxy,
    660                                    process_t * process,
     651                                   pid_t       pid,
    661652                                   uint32_t    status )
    662653{
     
    671662    rpc.index    = RPC_PROCESS_MAKE_EXIT;
    672663    rpc.response = 1;
     664    rpc.blocking = true;
    673665
    674666    // set input arguments in RPC descriptor 
    675     rpc.args[0] = (uint64_t)(intptr_t)process;
     667    rpc.args[0] = (uint64_t)pid;
    676668    rpc.args[1] = (uint64_t)status;
    677669
    678670    // register RPC request in remote RPC fifo (blocking function)
    679     rpc_send( cxy , &rpc , true );
     671    rpc_send( cxy , &rpc );
    680672
    681673rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    691683CURRENT_THREAD->core->lid , hal_time_stamp() );
    692684
    693     process_t * process;
    694     uint32_t    status; 
     685    pid_t     pid;
     686    uint32_t  status; 
    695687
    696688    // get client cluster identifier and pointer on RPC descriptor
     
    699691
    700692    // get arguments from RPC descriptor
    701     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    702     status  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     693    pid    = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     694    status = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    703695
    704696    // call local kernel function
    705     process_make_exit( process , status );
     697    process_make_exit( pid , status );
    706698
    707699rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    716708///////////////////////////////////////////////////
    717709void rpc_process_make_kill_client( cxy_t       cxy,
    718                                    process_t * process,
     710                                   pid_t       pid,
    719711                                   uint32_t    sig_id )
    720712{
     
    729721    rpc.index    = RPC_PROCESS_MAKE_KILL;
    730722    rpc.response = 1;
     723    rpc.blocking = true;
    731724
    732725    // set input arguments in RPC descriptor 
    733     rpc.args[0] = (uint64_t)(intptr_t)process;
     726    rpc.args[0] = (uint64_t)pid;
    734727    rpc.args[1] = (uint64_t)sig_id;
    735728
    736729    // register RPC request in remote RPC fifo (blocking function)
    737     rpc_send( cxy , &rpc , true );
     730    rpc_send( cxy , &rpc );
    738731
    739732rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    749742CURRENT_THREAD->core->lid , hal_time_stamp() );
    750743
    751     process_t * process;
     744    pid_t       pid;
    752745    uint32_t    sig_id;
    753746
     
    757750
    758751    // get arguments from RPC descriptor
    759     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    760     sig_id  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     752    pid    = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     753    sig_id = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    761754
    762755    // call local kernel function
    763     process_make_exit( process , sig_id );
     756    process_make_exit( pid , sig_id );
    764757
    765758rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    791784    rpc.index     = RPC_THREAD_USER_CREATE;
    792785    rpc.response  = 1;
     786    rpc.blocking = true;
    793787
    794788    // set input arguments in RPC descriptor
     
    799793
    800794    // register RPC request in remote RPC fifo (blocking function)
    801     rpc_send( cxy , &rpc , true );
     795    rpc_send( cxy , &rpc );
    802796
    803797    // get output arguments from RPC descriptor
     
    883877    rpc.index    = RPC_THREAD_KERNEL_CREATE;
    884878    rpc.response = 1;
     879    rpc.blocking = true;
    885880
    886881    // set input arguments in RPC descriptor
     
    890885   
    891886    // register RPC request in remote RPC fifo (blocking function)
    892     rpc_send( cxy , &rpc , true );
     887    rpc_send( cxy , &rpc );
    893888
    894889    // get output arguments from RPC descriptor
     
    956951    rpc.index    = RPC_THREAD_KILL;
    957952    rpc.response = 1;
     953    rpc.blocking = true;
    958954
    959955    // set input arguments in RPC descriptor
     
    961957   
    962958    // register RPC request in remote RPC fifo (blocking function)
    963     rpc_send( cxy , &rpc , true );
     959    rpc_send( cxy , &rpc );
    964960
    965961rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    997993/////////////////////////////////////////////////////////////////////////////////////////
    998994
    999 ///////////////////////////////////////////////////
    1000 void rpc_process_sigaction_client( cxy_t       cxy,
    1001                                    process_t * process,        // in
    1002                                    uint32_t    sigaction,      // in
    1003                                    xptr_t      rsp_xp,         // in
    1004                                    xptr_t      client_xp )     // in
    1005 {
    1006 sigaction_dmsg("\n[DBG] %s : enter for %s (%d) / thread %x on core[%x,%d] / cycle %d\n",
    1007 __FUNCTION__ , process_action_str( sigaction ) , sigaction , CURRENT_THREAD ,
    1008 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
    1009 
    1010     // initialise RPC descriptor header
    1011     rpc_desc_t  rpc;
    1012     rpc.index    = RPC_PROCESS_SIGACTION;
    1013 
    1014     // set input arguments in RPC descriptor 
    1015     rpc.args[0] = (uint64_t)(intptr_t)process;
    1016     rpc.args[1] = (uint64_t)sigaction;
    1017     rpc.args[2] = (uint64_t)rsp_xp;
    1018     rpc.args[3] = (uint64_t)client_xp;
    1019 
    1020     // register RPC request in remote RPC fifo (non blocking)
    1021     rpc_send( cxy , &rpc , false );
    1022 
    1023 sigaction_dmsg("\n[DBG] %s : exit for %s (%d) / thread %x on core[%x,%d] / cycle %d\n",
    1024 __FUNCTION__ , process_action_str( sigaction ) , sigaction , CURRENT_THREAD ,
    1025 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     995////////////////////////////////////////////////////
     996void rpc_process_sigaction_client( cxy_t        cxy,
     997                                   rpc_desc_t * rpc_ptr )
     998{
     999sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x / cycle %d\n",
     1000__FUNCTION__ , process_action_str( (uint32_t)rpc_ptr->args[0] ) ,
     1001((process_t *)(intptr_t)rpc_ptr->args[1])->pid , cxy , (uint32_t)hal_get_cycles() );
     1002
     1003    // register RPC request in remote RPC fifo
     1004    rpc_send( cxy , rpc_ptr );
     1005
     1006sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x / cycle %d\n",
     1007__FUNCTION__ , process_action_str( (uint32_t)rpc_ptr->args[0] ) ,
     1008((process_t *)(intptr_t)rpc_ptr->args[1])->pid , cxy , (uint32_t)hal_get_cycles() );
    10261009
    10271010
     
    10291012void rpc_process_sigaction_server( xptr_t xp )
    10301013{
    1031     process_t * process;
    1032     uint32_t    action; 
    1033     xptr_t      rsp_xp;
    1034     xptr_t      client_xp;
    1035 
    1036     // get client cluster identifier and pointer on RPC descriptor
    1037     cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
    1038     rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     1014    process_t  * process;          // pointer on local process descriptor
     1015    uint32_t     action;           // sigaction index
     1016    thread_t   * client_ptr;       // local pointer on client thread in client cluster
     1017    cxy_t        client_cxy;       // client cluster identifier
     1018    xptr_t       client_xp;        // extended pointer on client thread
     1019    core_t     * client_core;      // local pointer on core running the client thread
     1020    rpc_desc_t * rpc;              // local pointer on rpc descriptor in client cluster
     1021
     1022    // get client cluster identifier and pointer on RPC descriptor
     1023    client_cxy = (cxy_t)GET_CXY( xp );
     1024    rpc        = (rpc_desc_t *)GET_PTR( xp );
    10391025
    10401026    // get arguments from RPC descriptor
    1041     process   = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    1042     action    = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    1043     rsp_xp    = (xptr_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    1044     client_xp = (xptr_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
    1045    
    1046 sigaction_dmsg("\n[DBG] %s : enter for %s (%d) / thread %x on core[%x,%d] / cycle %d\n",
    1047 __FUNCTION__ , process_action_str( action ) , action , CURRENT_THREAD ,
    1048 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     1027    action      = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &rpc->args[0] ) );
     1028    process     = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &rpc->args[1] ) );
     1029    client_ptr  = (thread_t *)hal_remote_lpt( XPTR( client_cxy , &rpc->thread ) );
     1030
     1031    // build extended pointer on client thread
     1032    client_xp = XPTR( client_cxy , client_ptr );
     1033
     1034sigaction_dmsg("\n[DBG] %s : enter to %s process %x / cycle %d\n",
     1035__FUNCTION__ , process_action_str( action ) , process->pid , (uint32_t)hal_get_cycles() );
    10491036
    10501037    // call relevant kernel function
    1051     if      (action == DELETE_ALL_THREADS  ) process_delete ( process , rsp_xp , client_xp );
    1052     else if (action == BLOCK_ALL_THREADS   ) process_block  ( process , rsp_xp , client_xp );
    1053     else if (action == UNBLOCK_ALL_THREADS ) process_unblock( process , rsp_xp , client_xp );
    1054 
    1055 sigaction_dmsg("\n[DBG] %s : exit for %s (%d) / thread %x on core[%x,%d] / cycle %d\n",
    1056 __FUNCTION__ , process_action_str( action ) , action , CURRENT_THREAD ,
    1057 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     1038    if      (action == DELETE_ALL_THREADS  ) process_delete ( process , client_xp );
     1039    else if (action == BLOCK_ALL_THREADS   ) process_block  ( process , client_xp );
     1040    else if (action == UNBLOCK_ALL_THREADS ) process_unblock( process             );
     1041
     1042    // decrement the responses counter in RPC descriptor,
     1043    // unblock the client thread only if it is the last response.
     1044    if( hal_remote_atomic_add( XPTR( client_cxy , &rpc->response ) , -1 ) == 1 )
     1045    {
     1046        client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );
     1047        thread_unblock( client_xp , THREAD_BLOCKED_RPC );
     1048        dev_pic_send_ipi( client_cxy , client_core->lid );
     1049    }
     1050
     1051sigaction_dmsg("\n[DBG] %s : exit after %s process %x / cycle %d\n",
     1052__FUNCTION__ , process_action_str( action ) , process->pid , (uint32_t)hal_get_cycles() );
    10581053}
    10591054
     
    10851080    rpc.index    = RPC_VFS_INODE_CREATE;
    10861081    rpc.response = 1;
     1082    rpc.blocking = true;
    10871083
    10881084    // set input arguments in RPC descriptor
     
    10971093
    10981094    // register RPC request in remote RPC fifo (blocking function)
    1099     rpc_send( cxy , &rpc , true );
     1095    rpc_send( cxy , &rpc );
    11001096
    11011097    // get output values from RPC descriptor
     
    11781174    rpc.index    = RPC_VFS_INODE_DESTROY;
    11791175    rpc.response = 1;
     1176    rpc.blocking = true;
    11801177
    11811178    // set input arguments in RPC descriptor
     
    11831180   
    11841181    // register RPC request in remote RPC fifo (blocking function)
    1185     rpc_send( cxy , &rpc , true );
     1182    rpc_send( cxy , &rpc );
    11861183
    11871184    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    12361233    rpc.index    = RPC_VFS_DENTRY_CREATE;
    12371234    rpc.response = 1;
     1235    rpc.blocking = true;
    12381236
    12391237    // set input arguments in RPC descriptor
     
    12431241
    12441242    // register RPC request in remote RPC fifo (blocking function)
    1245     rpc_send( cxy , &rpc , true );
     1243    rpc_send( cxy , &rpc );
    12461244
    12471245    // get output values from RPC descriptor
     
    13151313    rpc.index    = RPC_VFS_DENTRY_DESTROY;
    13161314    rpc.response = 1;
     1315    rpc.blocking = true;
    13171316
    13181317    // set input arguments in RPC descriptor
     
    13201319   
    13211320    // register RPC request in remote RPC fifo (blocking function)
    1322     rpc_send( cxy , &rpc , true );
     1321    rpc_send( cxy , &rpc );
    13231322
    13241323    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    13731372    rpc.index    = RPC_VFS_FILE_CREATE;
    13741373    rpc.response = 1;
     1374    rpc.blocking = true;
    13751375
    13761376    // set input arguments in RPC descriptor
     
    13791379
    13801380    // register RPC request in remote RPC fifo (blocking function)
    1381     rpc_send( cxy , &rpc , true );
     1381    rpc_send( cxy , &rpc );
    13821382
    13831383    // get output values from RPC descriptor
     
    14421442    rpc.index    = RPC_VFS_FILE_DESTROY;
    14431443    rpc.response = 1;
     1444    rpc.blocking = true;
    14441445
    14451446    // set input arguments in RPC descriptor
     
    14471448   
    14481449    // register RPC request in remote RPC fifo (blocking function)
    1449     rpc_send( cxy , &rpc , true );
     1450    rpc_send( cxy , &rpc );
    14501451
    14511452    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    14991500    rpc.index    = RPC_VFS_INODE_LOAD;
    15001501    rpc.response = 1;
     1502    rpc.blocking = true;
    15011503
    15021504    // set input arguments in RPC descriptor
     
    15061508
    15071509    // register RPC request in remote RPC fifo (blocking function)
    1508     rpc_send( cxy , &rpc , true );
     1510    rpc_send( cxy , &rpc );
    15091511
    15101512    // get output values from RPC descriptor
     
    15731575    rpc.index    = RPC_VFS_MAPPER_LOAD_ALL;
    15741576    rpc.response = 1;
     1577    rpc.blocking = true;
    15751578
    15761579    // set input arguments in RPC descriptor
     
    15781581
    15791582    // register RPC request in remote RPC fifo (blocking function)
    1580     rpc_send( cxy , &rpc , true );
     1583    rpc_send( cxy , &rpc );
    15811584
    15821585    // get output values from RPC descriptor
     
    16381641    rpc.index    = RPC_FATFS_GET_CLUSTER;
    16391642    rpc.response = 1;
     1643    rpc.blocking = true;
    16401644
    16411645    // set input arguments in RPC descriptor
     
    16451649
    16461650    // register RPC request in remote RPC fifo
    1647     rpc_send( cxy , &rpc , true );
     1651    rpc_send( cxy , &rpc );
    16481652
    16491653    // get output argument from rpc descriptor
     
    17111715    rpc.index    = RPC_VMM_GET_VSEG;
    17121716    rpc.response = 1;
     1717    rpc.blocking = true;
    17131718
    17141719    // set input arguments in RPC descriptor
     
    17171722
    17181723    // register RPC request in remote RPC fifo (blocking function)
    1719     rpc_send( cxy , &rpc , true );
     1724    rpc_send( cxy , &rpc );
    17201725
    17211726    // get output argument from rpc descriptor
     
    17861791    rpc.index    = RPC_VMM_GET_PTE;
    17871792    rpc.response = 1;
     1793    rpc.blocking = true;
    17881794
    17891795    // set input arguments in RPC descriptor
     
    17931799
    17941800    // register RPC request in remote RPC fifo (blocking function)
    1795     rpc_send( cxy , &rpc , true );
     1801    rpc_send( cxy , &rpc );
    17961802
    17971803    // get output argument from rpc descriptor
     
    18601866    rpc.index    = RPC_THREAD_USER_CREATE;
    18611867    rpc.response = 1;
     1868    rpc.blocking = true;
    18621869
    18631870    // set input arguments in RPC descriptor
     
    18651872
    18661873    // register RPC request in remote RPC fifo (blocking function)
    1867     rpc_send( cxy , &rpc , true );
     1874    rpc_send( cxy , &rpc );
    18681875
    18691876    // get output arguments from RPC descriptor
     
    19231930    rpc.index    = RPC_THREAD_USER_CREATE;
    19241931    rpc.response = 1;
     1932    rpc.blocking = true;
    19251933
    19261934    // set input arguments in RPC descriptor
     
    19291937
    19301938    // register RPC request in remote RPC fifo (blocking function)
    1931     rpc_send( cxy , &rpc , true );
     1939    rpc_send( cxy , &rpc );
    19321940
    19331941    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    19861994    rpc.index    = RPC_MAPPER_MOVE_BUFFER;
    19871995    rpc.response = 1;
     1996    rpc.blocking = true;
    19881997
    19891998    // set input arguments in RPC descriptor
     
    19962005
    19972006    // register RPC request in remote RPC fifo (blocking function)
    1998     rpc_send( cxy , &rpc , true );
     2007    rpc_send( cxy , &rpc );
    19992008
    20002009    // get output values from RPC descriptor
     
    20832092    rpc.index    = RPC_MAPPER_GET_PAGE;
    20842093    rpc.response = 1;
     2094    rpc.blocking = true;
    20852095
    20862096    // set input arguments in RPC descriptor
     
    20892099
    20902100    // register RPC request in remote RPC fifo (blocking function)
    2091     rpc_send( cxy , &rpc , true );
     2101    rpc_send( cxy , &rpc );
    20922102
    20932103    // get output values from RPC descriptor
     
    21512161    rpc.index    = RPC_VMM_CREATE_VSEG;
    21522162    rpc.response = 1;
     2163    rpc.blocking = true;
    21532164
    21542165    // set input arguments in RPC descriptor
     
    21632174
    21642175    // register RPC request in remote RPC fifo (blocking function)
    2165     rpc_send( cxy , &rpc , true );
     2176    rpc_send( cxy , &rpc );
    21662177
    21672178    // get output values from RPC descriptor
     
    22302241    rpc.index    = RPC_SCHED_DISPLAY;
    22312242    rpc.response = 1;
     2243    rpc.blocking = true;
    22322244
    22332245    // set input arguments in RPC descriptor
     
    22352247
    22362248    // register RPC request in remote RPC fifo (blocking function)
    2237     rpc_send( cxy , &rpc , true );
     2249    rpc_send( cxy , &rpc );
    22382250
    22392251    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    22822294    rpc.index    = RPC_VMM_SET_COW;
    22832295    rpc.response = 1;
     2296    rpc.blocking = true;
    22842297
    22852298    // set input arguments in RPC descriptor
     
    22872300
    22882301    // register RPC request in remote RPC fifo (blocking function)
    2289     rpc_send( cxy , &rpc , true );
     2302    rpc_send( cxy , &rpc );
    22902303
    22912304    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
  • trunk/kernel/kern/rpc.h

    r409 r416  
    109109{
    110110        rpc_index_t         index;       /*! index of requested RPC service           */
    111         volatile uint32_t   response;    /*! response valid when 0                    */
     111        volatile uint32_t   response;    /*! all responses received when 0            */
    112112    struct thread_s   * thread;      /*! local pointer on client thread           */
    113113    uint32_t            lid;         /*! index of core running the calling thread */
     114    bool_t              blocking;    /*! blocking RPC when true                   */
    114115    uint64_t            args[10];    /*! input/output arguments buffer            */
    115116}
     
    127128 * the caller. It exit with a Panic message if remote fifo is still full after
    128129 * (CONFIG_RPC_PUT_MAX_ITERATIONS) retries.
    129  * - When the <block> argument is true, this function blocks and deschedule.
     130 * - When the RPC <blocking> field is true, this function blocks and deschedule.
    130131 *   It returns only when the server acknowledges the RPC by writing in the RPC
    131132 *   "response" field, and unblocks the client.
    132  * - When the <block> argument is false, this function returns as soon as the RPC
     133 * - When the <blocking> field is false, this function returns as soon as the RPC
    133134 *   has been registered in the FIFO, and the server thread must directly signal
    134135 *   completion to the client thread.
     
    136137 * @ cxy   : server cluster identifier
    137138 * @ desc  : local pointer on RPC descriptor in client cluster
    138  * @ block : boolean true when blocking behaviour is required.
    139139 **********************************************************************************/
    140140void rpc_send( cxy_t        cxy,   
    141                rpc_desc_t * desc,
    142                bool_t       block );
     141               rpc_desc_t * desc );
    143142
    144143
     
    252251/***********************************************************************************
    253252 * [4] The RPC_PROCESS_MAKE_EXIT can be called by any thread to request the owner
    254  * cluster to execute the process_make_exit() function for a calling process.
    255  ***********************************************************************************
    256  * @ cxy      : server cluster identifier.
    257  * @ process  : local pointer on calling process in owner cluster.
     253 * cluster to execute the process_make_exit() function for the target process.
     254 ***********************************************************************************
     255 * @ cxy      : owner cluster identifier.
     256 * @ pid      : target process identifier.
    258257 * @ status   : calling process exit status.
    259258 **********************************************************************************/
    260259void rpc_process_make_exit_client( cxy_t              cxy,
    261                                    struct process_s * process,
     260                                   pid_t              pid,
    262261                                   uint32_t           status );
    263262
     
    268267 * cluster to execute the process_make_kill() function for a target process.
    269268 ***********************************************************************************
    270  * @ cxy      : server cluster identifier.
    271  * @ process  : local pointer on target process in owner cluster.
     269 * @ cxy      : owner cluster identifier.
     270 * @ pid      : target process identifier.
    272271 * @ seg_id   : signal type (only SIGKILL / SIGSTOP / SIGCONT are supported).
    273272 **********************************************************************************/
    274273void rpc_process_make_kill_client( cxy_t              cxy,
    275                                    struct process_s * process,
     274                                   pid_t              pid,
    276275                                   uint32_t           seg_id );
    277276
     
    339338 *
    340339 * WARNING : It is implemented as a NON BLOCKING multicast RPC, that can be sent
    341  * in parallel to all process copies. The various server threads must decrement the
    342  * responses counter defined by the <rsp_xp> argument, and the last server thread
    343  * must unblock the <client_xp> thread.
     340 * in parallel to all process copies. The rpc descriptor is allocated in the client
     341 * thread stack by the process_sigaction() function. The various server threads
     342 * must decrement the responses counter defined in the rsp descriptor, and the last
     343 * server thread unblock the client thread that blocked (after sending all RPC
     344 * requests) in the process_sigaction() function.
     345 * - The first RPC argument is the sigaction type (BLOCK / UNBLOCK / DELETE).
     346 * - The second RPC argument is the local pointer on target process.
    344347 ***********************************************************************************
    345348 * @ cxy       : server cluster identifier.
    346  * @ process   : [in]  local pointer on target process in server cluster.
    347  * @ sigaction : [in]  action type (BLOCK / UNBLOCK / DELETE).
    348  * @ rsp_xp    : [in]  extended pointer on response counter.
    349  * @ client_xp : [in]  extended pointer on client thread.
    350  **********************************************************************************/
    351 void rpc_process_sigaction_client( cxy_t               cxy,
    352                                    struct process_s  * process,
    353                                    uint32_t            sigaction,
    354                                    xptr_t              rsp_xp,
    355                                    xptr_t              client_xp );
     349 * @ rpc_ptr   : [in]  local pointer on rpc descriptor in client cluster.
     350 **********************************************************************************/
     351void rpc_process_sigaction_client( cxy_t        cxy,
     352                                   rpc_desc_t * rpc_ptr );
    356353                             
    357354void rpc_process_sigaction_server( xptr_t xp );
  • trunk/kernel/kern/scheduler.c

    r409 r416  
    5858    list_root_init( &sched->k_root );
    5959
    60     sched->sig_pending    = false;            // no pending signal
     60    sched->req_ack_pending = false;           // no pending request
    6161
    6262}  // end sched_init()
     
    8989
    9090}  // end sched_register_thread()
    91 
    92 /////////////////////////////////////////////
    93 void sched_remove_thread( thread_t * thread )
    94 {
    95     scheduler_t * sched = &thread->core->scheduler;
    96     thread_type_t type  = thread->type;
    97 
    98     // take lock protecting sheduler lists
    99     spinlock_lock( &sched->lock );
    100 
    101     if( type == THREAD_USER )
    102     {
    103         list_unlink( &thread->sched_list );
    104         sched->u_threads_nr--;
    105         if( sched->u_threads_nr == 0 ) sched->u_last = NULL;
    106     }
    107     else // kernel thread
    108     {
    109         list_unlink( &thread->sched_list );
    110         sched->k_threads_nr--;
    111         if( sched->k_threads_nr == 0 ) sched->k_last = NULL;
    112     }
    113 
    114     // release lock
    115     spinlock_unlock( &sched->lock );
    116 
    117 }  // end sched_remove_thread()
    11891
    11992//////////////////////////////////////////////
     
    203176}  // end sched_select()
    204177
    205 //////////////////////////////////////////
    206 void sched_handle_signals( core_t * core )
     178///////////////////////////////////////////
     179void sched_handle_requests( core_t * core )
    207180{
    208181    list_entry_t * iter;
    209182    thread_t     * thread;
    210183
     184// printk("\n@@@ %s : current thread %x enter at cycle %d\n",
     185// __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() );
     186
    211187    scheduler_t  * sched = &core->scheduler;
    212188
     
    214190    spinlock_lock( &sched->lock );
    215191
    216     // handle user threads
     192    // scan all user threads
    217193    LIST_FOREACH( &sched->u_root , iter )
    218194    {
    219195        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    220196
    221         if( thread->flags & THREAD_FLAG_SIGNAL )  // thread has signal
    222         {
    223             // decrement response counter to acknowledge signal
    224             hal_atomic_add( thread->sig_rsp_count , -1 );
    225 
    226             // reset signal
    227             thread_reset_signal( thread );
     197        // handle REQ_ACK
     198        if( thread->flags & THREAD_FLAG_REQ_ACK )
     199        {
     200            // check thread blocked
     201            assert( (thread->blocked & THREAD_BLOCKED_GLOBAL) ,
     202            __FUNCTION__ , "thread not blocked" );
     203 
     204            // decrement response counter
     205            hal_atomic_add( thread->ack_rsp_count , -1 );
     206
     207            // reset REQ_ACK in thread descriptor
     208            thread_reset_req_ack( thread );
     209        }
     210
     211        // handle REQ_DELETE
     212        if( thread->flags & THREAD_FLAG_REQ_DELETE )
     213        {
     214
     215sched_dmsg("\n[DBG] %s : current thread %x delete thread %x at cycle %d\n",
     216__FUNCTION__ , CURRENT_THREAD , thread , hal_time_stamp() );
     217
     218                // release FPU if required
     219                if( thread->core->fpu_owner == thread )  thread->core->fpu_owner = NULL;
     220
     221            // detach thread from parent if attached
     222            if( (thread->flags & THREAD_FLAG_DETACHED) == 0 )
     223            thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) );
     224
     225            // detach thread from process
     226            process_remove_thread( thread );
     227
     228            // remove thread from scheduler
     229            list_unlink( &thread->sched_list );
     230            sched->u_threads_nr--;
     231            if( sched->u_threads_nr == 0 ) sched->u_last = NULL;
     232
     233            // release memory allocated to thread
     234            thread_destroy( thread );
     235
     236            // destroy process descriptor if no more threads
     237            if (thread->process->th_nr == 0) process_destroy( thread->process );
    228238        }
    229239    }
     
    232242    spinlock_unlock( &sched->lock );
    233243
    234 } // end sched_handle_signals()
     244// printk("\n@@@ %s : current thread %x exit at cycle %d\n",
     245// __FUNCTION__ , CURRENT_THREAD , hal_time_stamp() );
     246
     247} // end sched_handle_requests()
    235248
    236249////////////////////////////////
     
    305318    }
    306319
    307     // handle signals for all threads executing on this core.
    308     sched_handle_signals( core );
     320    // handle pending requests for all threads executing on this core.
     321    sched_handle_requests( core );
    309322
    310323    // exit critical section / restore SR from next thread context
     
    354367        if (thread->type == THREAD_DEV)
    355368        {
    356             nolock_printk(" - %s / pid %X / trdid %X / desc %X / blocked %X / %s\n",
     369            nolock_printk(" - %s / pid %X / trdid %X / desc %X / block %X / flags %X / %s\n",
    357370            thread_type_str( thread->type ), thread->process->pid, thread->trdid,
    358             thread, thread->blocked , thread->chdev->name );
     371            thread, thread->blocked, thread->flags, thread->chdev->name );
    359372        }
    360373        else
    361374        {
    362             nolock_printk(" - %s / pid %X / trdid %X / desc %X / blocked %X\n",
     375            nolock_printk(" - %s / pid %X / trdid %X / desc %X / block %X / flags %X \n",
    363376            thread_type_str( thread->type ), thread->process->pid, thread->trdid,
    364             thread, thread->blocked );
     377            thread, thread->blocked, thread->flags );
    365378        }
    366379    }
     
    370383    {
    371384        thread = LIST_ELEMENT( iter , thread_t , sched_list );
    372         nolock_printk(" - %s / pid %X / trdid %X / desc %X / blocked %X\n",
     385        nolock_printk(" - %s / pid %X / trdid %X / desc %X / block %X / flags %X\n",
    373386        thread_type_str( thread->type ), thread->process->pid, thread->trdid,
    374         thread, thread->blocked );
     387        thread, thread->blocked, thread->flags );
    375388    }
    376389
  • trunk/kernel/kern/scheduler.h

    r409 r416  
    4040typedef struct scheduler_s
    4141{
    42     spinlock_t        lock;         /*! readlock protecting lists of threads                */
    43     uint16_t          u_threads_nr; /*! total numbre of attached user threads               */
    44     uint16_t          k_threads_nr; /*! total number of attached kernel threads             */
    45     list_entry_t      u_root;       /*! root of list of user threads for this scheduler     */
    46     list_entry_t      k_root;       /*! root of list of kernel threads for this scheduler   */
    47     list_entry_t    * u_last;       /*! pointer on list_entry for last executed k_thread    */
    48     list_entry_t    * k_last;       /*! pointer on list entry for last executed u_thread    */
    49     struct thread_s * idle;         /*! pointer on idle thread                              */
    50     struct thread_s * current;      /*! pointer on current running thread                   */
    51     bool_t            sig_pending;  /*! signal_handller must be called when true            */
     42    spinlock_t        lock;            /*! readlock protecting lists of threads             */
     43    uint16_t          u_threads_nr;    /*! total number of attached user threads            */
     44    uint16_t          k_threads_nr;    /*! total number of attached kernel threads          */
     45    list_entry_t      u_root;          /*! root of list of user threads                     */
     46    list_entry_t      k_root;          /*! root of list of kernel threads                   */
     47    list_entry_t    * u_last;          /*! pointer on list_entry for last executed k_thread */
     48    list_entry_t    * k_last;          /*! pointer on list entry for last executed u_thread */
     49    struct thread_s * idle;            /*! pointer on idle thread                           */
     50    struct thread_s * current;         /*! pointer on current running thread                */
     51    bool_t            req_ack_pending; /*! signal_handller must be called when true         */
    5252}
    5353scheduler_t;
     
    6767                            struct thread_s * thread );
    6868
    69 /*********************************************************************************************
    70  * This function remove a thread from its scheduler.re scheduler.
    71  *********************************************************************************************
    72  * @ thread  : local pointer on the thread descriptor.
    73  ********************************************************************************************/ 
    74 void sched_remove_thread( struct thread_s * thread );
    75 
    7669/*********************************************************************************************
    7770 * This function is the only method to make a context switch. It is called in cas of TICK,
     
    8780
    8881/*********************************************************************************************
    89  * This function scan all threads attached to a given core scheduler, and executes
    90  * the relevant actions for pending KILL or EXIT signals.
    91  * It is called in by the sched_yield() function, with IRQ disabled.
     82 * This function scan all threads attached to a given scheduler, and executes the relevant
     83 * actions for pending THREAD_FLAG_REQ_ACK or THREAD_FLAG_REQ_DELETE requests.
     84 * It is called in by the sched_yield() function, with IRQ disabled.
     85 * - REQ_ACK : it checks that target thread is blocked, decrements the response counter
     86 *   to acknowledge the client thread, and reset the pending request.
     87 * - REQ_DELETE : it detach the target thread from parent if attached, detach it from
     88 *   the process, remove it from scheduler, release memory allocated to thread descriptor,
     89 *   and destroy the process descriptor it the target thread was the last thread.
    9290 *********************************************************************************************
    9391 * @ core    : local pointer on the core descriptor.
    9492 ********************************************************************************************/
    95 void sched_handle_signals( struct core_s * core );
     93void sched_handle_requests( struct core_s * core );
    9694
    9795/*********************************************************************************************
     
    113111
    114112/*********************************************************************************************
    115  * This function unlink a thread identified by the <thread> pointer from its process.
    116  * It is called by the sched_handle_signals() function when one EXIT or KILL signal is set,
    117  * and it implement the first step of a thread destructionebut can also be directly called by a local killer thread signal.
    118  * - It detach the thread from the scheduler.
    119  * - It detach the thread from the process.
    120  * - It detach the thread from the parent thread when the thread is attached.
    121  * - It destroys the thread descriptor.
    122  * - It acknowledge the killer thread if it's a kill signal
    123  *********************************************************************************************
    124  * @ thread   : pointer on thread to be killed.
    125  ********************************************************************************************/
    126 void sched_kill_thread( struct thread_s * thread );
    127 
    128 /*********************************************************************************************
    129113 * This function display the internal state of the local core identified by its <lid>.
    130114 *********************************************************************************************
  • trunk/kernel/kern/thread.c

    r409 r416  
    696696}  // thread_child_parent_unlink()
    697697
    698 /////////////////////////////////////////////////
    699 inline void thread_set_signal( thread_t * thread,
    700                                uint32_t * sig_rsp_count )
     698//////////////////////////////////////////////////
     699inline void thread_set_req_ack( thread_t * target,
     700                                uint32_t * rsp_count )
    701701{
    702702    reg_t    save_sr;   // for critical section
    703703
    704     // get pointer on thread thread scheduler
    705     scheduler_t * thread_sched = &thread->core->scheduler;
    706 
    707     // wait scheduler ready to handle a new signal
    708     while( thread_sched->sig_pending ) asm volatile( "nop" );
     704    // get pointer on target thread scheduler
     705    scheduler_t * sched = &target->core->scheduler;
     706
     707    // wait scheduler ready to handle a new request
     708    while( sched->req_ack_pending ) asm volatile( "nop" );
    709709   
    710710    // enter critical section
    711711    hal_disable_irq( &save_sr );
    712712     
    713     // set signal in thread scheduler
    714     thread_sched->sig_pending = true;
    715 
    716     // set signal in thread thread "flags"
    717     hal_atomic_or( &thread->flags , THREAD_FLAG_SIGNAL );
    718 
    719     // set pointer on responses counter in thread thread
    720     thread->sig_rsp_count = sig_rsp_count;
     713    // set request in target thread scheduler
     714    sched->req_ack_pending = true;
     715
     716    // set ack request in target thread "flags"
     717    hal_atomic_or( &target->flags , THREAD_FLAG_REQ_ACK );
     718
     719    // set pointer on responses counter in target thread
     720    target->ack_rsp_count = rsp_count;
    721721   
    722722    // exit critical section
     
    725725    hal_fence();
    726726
    727 }  // thread_set_signal()
    728 
    729 ////////////////////////////////////////////////////
    730 inline void thread_reset_signal( thread_t * thread )
     727}  // thread_set_req_ack()
     728
     729/////////////////////////////////////////////////////
     730inline void thread_reset_req_ack( thread_t * target )
    731731{
    732732    reg_t    save_sr;   // for critical section
    733733
    734734    // get pointer on target thread scheduler
    735     scheduler_t * sched = &thread->core->scheduler;
     735    scheduler_t * sched = &target->core->scheduler;
    736736
    737737    // check signal pending in scheduler
    738     assert( sched->sig_pending , __FUNCTION__ , "no pending signal" );
     738    assert( sched->req_ack_pending , __FUNCTION__ , "no pending signal" );
    739739   
    740740    // enter critical section
     
    742742     
    743743    // reset signal in scheduler
    744     sched->sig_pending = false;
     744    sched->req_ack_pending = false;
    745745
    746746    // reset signal in thread "flags"
    747     hal_atomic_and( &thread->flags , ~THREAD_FLAG_SIGNAL );
     747    hal_atomic_and( &target->flags , ~THREAD_FLAG_REQ_ACK );
    748748
    749749    // reset pointer on responses counter
    750     thread->sig_rsp_count = NULL;
     750    target->ack_rsp_count = NULL;
    751751   
    752752    // exit critical section
     
    755755    hal_fence();
    756756
    757 }  // thread_reset_signal()
     757}  // thread_reset_req_ack()
    758758
    759759////////////////////////////////
     
    809809void thread_kill( thread_t * target )
    810810{
    811     volatile uint32_t  sig_rsp_count = 1;     // responses counter
     811    volatile uint32_t  rsp_count = 1;     // responses counter
    812812
    813813    thread_t * killer = CURRENT_THREAD;
    814814
    815 kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
     815thread_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
    816816__FUNCTION__, local_cxy, killer->trdid , target trdid );
    817817
     
    824824    {
    825825        // set signal in target thread descriptor and in target scheduler
    826         thread_set_signal( target , (uint32_t *)(&sig_rsp_count) );
     826        thread_set_req_ack( target , (void *)(&rsp_count) );
    827827
    828828        // send an IPI to the target thread core.
     
    833833        {
    834834            // exit when response received from scheduler
    835             if( sig_rsp_count == 0 )  break;
     835            if( rsp_count == 0 )  break;
    836836
    837837            // deschedule without blocking
     
    840840    }
    841841
    842         // release FPU if required
    843         if( target->core->fpu_owner == target )  target->core->fpu_owner = NULL;
    844 
    845     // detach thread from parent if attached
    846     if( (target->flags & THREAD_FLAG_DETACHED) == 0 )
    847     thread_child_parent_unlink( target->parent , XPTR( local_cxy , target ) );
    848 
    849     // detach thread from process
    850     process_remove_thread( target );
    851 
    852     // remove thread from scheduler
    853     sched_remove_thread( target );
    854 
    855     // release memory allocated to target thread
    856     thread_destroy( target );
    857 
    858 kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
     842        // set REQ_DELETE flag
     843        hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE );
     844
     845thread_dmsg("\n[DBG] %s : killer thread %x exit for target thread %x\n",
    859846__FUNCTION__, local_cxy, killer->trdid , target trdid );
    860847
  • trunk/kernel/kern/thread.h

    r409 r416  
    7272#define THREAD_FLAG_JOIN_DONE    0x0002  /*! Parent thread made a join                */
    7373#define THREAD_FLAG_SCHED        0x0004  /*! Scheduling required for this thread      */
    74 #define THREAD_FLAG_SIGNAL       0x0004  /*! Acknowledge of descheduling required     */
     74#define THREAD_FLAG_REQ_ACK      0x0008  /*! Acknowledge required from scheduler      */
     75#define THREAD_FLAG_REQ_DELETE   0x0010  /*! Destruction required by scheduler        */
    7576
    7677/***************************************************************************************
     
    119120 * - The TRDID 16 MSB bits contain the CXY of cluster containing the thread.
    120121 * - The LTID is used to index the th_tbl[] array in the local process descriptor.
    121  * This TRDID is computed by the process_register_thread() function, when the user
     122 _* This TRDID is computed by the process_register_thread() function, when the user
    122123 * thread is registered in the local copy of the process descriptor.
    123124 *
     
    153154    xptr_t              join_xp;         /*! extended pointer on joining thread       */
    154155
    155     uint32_t          * sig_rsp_count;   /*! pointer on signal response counter       */
     156    uint32_t          * ack_rsp_count;   /*! pointer on acknowledge response counter  */
    156157
    157158        intptr_t            u_stack_base;    /*! user stack base address                  */
     
    345346
    346347/***************************************************************************************
    347  * This function is used by a killer thread running in the same cluster as a target
    348  * thread to request the scheduler of the target to call the thread_handle_signal()
    349  * at the next context switch, to confirm that the target thread is blocked and
    350  * not currently running. This function executes atomically the following actions :
    351  * - it set the sig_pending flag in the target scheduler descriptor.
    352  * - it set the SIG flag in the "flags" field of the target thread descriptor.
     348 * This function is used by a "blocker" thread running in the same cluster as a "target"
     349 * thread to request the scheduler of the target thread to acknowledge that the target
     350 * thread is blocked and not running, at the next context switch.
     351 * This function executes atomically the following actions :
     352 * - it set the request_pending boolean in the target scheduler descriptor.
     353 * - it set the REQ_ACK flag in the "flags" field of the target thread descriptor.
    353354 * - It registers the responses counter pointer in the target thread descriptor.
    354  * The sig_pending flag is handled as a set/reset flip-flop by the killer thread
    355  * and by the target scheduler.
     355 * The request_pending flag is handled as a set/reset flip-flop by the "blocker" thread
     356 * and by the "target" scheduler.
    356357 ***************************************************************************************
    357358 * @ target        : local pointer on target thread.
    358  * @ sig_rsp_count : local pointer on responses counter.
    359  **************************************************************************************/
    360 void thread_set_signal( thread_t * thread,
    361                         uint32_t * sig_rsp_count );
    362 
    363 /***************************************************************************************
    364  * This function is used by the sched_handle_signal() function executed by a scheduler
    365  * to reset a pending signal in both a target <thread> descriptor, and in the target
    366  * thread scheduler.
    367  ***************************************************************************************
    368  * @ thread    : local pointer on target thread.
    369  **************************************************************************************/
    370 void thread_reset_signal( thread_t * thread );
     359 * @ ack_rsp_count : local pointer on responses counter.
     360 **************************************************************************************/
     361void thread_set_req_ack( thread_t * target,
     362                         uint32_t * ack_rsp_count );
     363
     364/***************************************************************************************
     365 * This function is used by the sched_handle_signal() function executed by the
     366 * scheduler of a "target" thread to reset a "blocked not running" acknowledge request
     367 * in both the target thread descriptor, and in the target  thread scheduler.
     368 ***************************************************************************************
     369 * @ target    : local pointer on target thread.
     370 **************************************************************************************/
     371void thread_reset_req_ack( thread_t * target );
    371372
    372373/***************************************************************************************
     
    390391 * If not, the client thread must use the RPC_THREAD_KILL.
    391392 * - When the killer thread is running on the same core as the target thread,
    392  *   This function simply detach the target thread from the scheduler,
    393  *   detach it from the parent thread if it is attached, detach it from the
    394  *   local process descriptor, and rrleases all memory allocated to the thread.
    395  * - When the killer thread is running on a different core than the target thread
    396  *   The killer send a signal to the target thread scheduler requesting this
    397  *   scheduler to confirm that the target thread is blocked and not running.
    398  *   Then, it executes the same actions as described above.
     393 *   this function simply set the BLOCKED_ GLOBAL bit and the REQ_DELETE flag
     394 *   in the target thread descriptor and return.
     395 * - When the killer thread is running on a different core than the target thread,
     396 *   the killer set the BLOCKED_GLOBAL bit and the REQ_ACK flag in target  thread,
     397 *   to ask the scheduler to confirm that the target is blocked and not running.
     398 *   Then, it set the REQ_DELETE flag in the target thread and return.
     399 * In both cases, the actual target thread destruction is done by the scheduler
     400 * at the next scheduling point.
    399401 ***************************************************************************************
    400402 * @ thread   : local pointer on the target thread.
Note: See TracChangeset for help on using the changeset viewer.