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

Fix bugs in exec

File:
1 edited

Legend:

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

    r408 r409  
    4949{
    5050    &rpc_pmem_get_pages_server,         // 0
    51     &rpc_process_make_exec_server,      // 1
    52     &rpc_process_make_fork_server,      // 2
    53     &rpc_process_kill_server,           // 3
    54     &rpc_thread_user_create_server,     // 4
    55     &rpc_thread_kernel_create_server,   // 5
    56     &rpc_signal_rise_server,            // 6                       
    57     &rpc_undefined,                     // 7
    58     &rpc_undefined,                     // 8
    59     &rpc_undefined,                     // 9
     51    &rpc_pmem_release_pages_server,     // 1
     52    &rpc_process_make_exec_server,      // 2
     53    &rpc_process_make_fork_server,      // 3
     54    &rpc_process_make_exit_server,      // 4
     55    &rpc_process_make_kill_server,      // 5
     56    &rpc_thread_user_create_server,     // 6
     57    &rpc_thread_kernel_create_server,   // 7
     58    &rpc_thread_kill_server,            // 8                       
     59    &rpc_process_sigaction_server,      // 9
    6060
    6161    &rpc_vfs_inode_create_server,       // 10 
     
    8888}
    8989
    90 /////////////////////////////////////////////////////////////////////////////////////////
    91 // [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES
     90/***************************************************************************************/
     91/************ Generic functions supporting RPCs : client side **************************/
     92/***************************************************************************************/
     93
     94///////////////////////////////////////
     95void rpc_send( cxy_t        server_cxy,
     96               rpc_desc_t * rpc,
     97               bool_t       block )
     98{
     99    error_t    error;
     100
     101    thread_t * this = CURRENT_THREAD;
     102    core_t   * core = this->core;
     103
     104    // register client thread pointer and core lid in RPC descriptor
     105    rpc->thread    = this;
     106    rpc->lid       = core->lid;
     107
     108    // build an extended pointer on the RPC descriptor
     109        xptr_t   desc_xp = XPTR( local_cxy , rpc );
     110
     111    // get local pointer on rpc_fifo in remote cluster, with the
     112    // assumption that local pointers are identical in all clusters
     113    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     114
     115        // try to post an item in remote fifo
     116    // deschedule and retry if remote fifo full
     117    do
     118    {
     119        error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ),
     120                                      (uint64_t )desc_xp );
     121            if ( error )
     122        {
     123            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
     124            __FUNCTION__ , local_cxy , server_cxy );
     125
     126            if( thread_can_yield() ) sched_yield("RPC fifo full");
     127        }
     128    }
     129    while( error );
     130 
     131    hal_fence();
     132       
     133    // send IPI to the remote core corresponding to the client core
     134        dev_pic_send_ipi( server_cxy , core->lid );
     135
     136    // wait RPC completion if blocking
     137    // - busy waiting policy during kernel_init, or if threads cannot yield
     138    // - block and deschedule in all other cases
     139    if ( block )
     140    {
     141        if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
     142        {
     143
     144grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n"
     145"        rpc = %d / server = %x / cycle %d\n",
     146__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
     147rpc->index , server_cxy , hal_time_stamp() );
     148
     149            while( rpc->response ) hal_fixed_delay( 100 );
     150   
     151grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n",
     152__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
     153
     154        }
     155        else                                                              // block & deschedule
     156        {
     157
     158grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n"
     159"        rpc = %d / server = %x / cycle %d\n",
     160__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
     161rpc->index , server_cxy , hal_time_stamp() );
     162
     163            thread_block( this , THREAD_BLOCKED_RPC );
     164            sched_yield("BLOCKED on RPC");
     165
     166grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n",
     167__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
     168
     169        }
     170
     171        // check response available
     172        assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" );
     173
     174        // acknowledge the IPI sent by the server
     175        dev_pic_ack_ipi();
     176    }
     177   
     178}  // end rpc_send()
     179
     180
     181/***************************************************************************************/
     182/************ Generic functions supporting RPCs : server side **************************/
     183/***************************************************************************************/
     184
     185////////////////
     186void rpc_check()
     187{
     188    error_t         error;
     189    thread_t      * thread; 
     190    uint32_t        sr_save;
     191
     192    bool_t          found    = false;
     193        thread_t      * this     = CURRENT_THREAD;
     194    core_t        * core     = this->core;
     195    scheduler_t   * sched    = &core->scheduler;
     196        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     197
     198grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n",
     199__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     200
     201    // interrupted thread not preemptable during RPC chek
     202        hal_disable_irq( &sr_save );
     203
     204    // check RPC FIFO not empty and no RPC thread handling it 
     205        if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
     206    {
     207        // search one non blocked RPC thread   
     208        list_entry_t * iter;
     209        LIST_FOREACH( &sched->k_root , iter )
     210        {
     211            thread = LIST_ELEMENT( iter , thread_t , sched_list );
     212            if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )
     213            {
     214                found = true;
     215                break;
     216            }
     217        }
     218
     219        // create new RPC thread if not found   
     220        if( found == false )                   
     221        {
     222            error = thread_kernel_create( &thread,
     223                                          THREAD_RPC,
     224                                                      &rpc_thread_func,
     225                                          NULL,
     226                                                      this->core->lid );
     227                if( error )
     228            {
     229                printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n",
     230                __FUNCTION__ , local_cxy );
     231            }
     232            else
     233            {
     234                // unblock created RPC thread
     235                thread->blocked = 0;
     236
     237                // update core descriptor counter 
     238                    hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
     239
     240grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n",
     241__FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
     242
     243            }
     244        }
     245    }
     246
     247grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n",
     248__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     249
     250    // interrupted thread deschedule always           
     251        sched_yield("IPI received");
     252
     253grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n",
     254__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
     255
     256    // interrupted thread restore IRQs after resume
     257        hal_restore_irq( sr_save );
     258
     259} // end rpc_check()
     260
     261
     262//////////////////////
     263void rpc_thread_func()
     264{
     265    uint32_t     count;       // handled RPC requests counter
     266    error_t      empty;       // local RPC fifo state
     267    xptr_t       desc_xp;     // extended pointer on RPC request
     268    cxy_t        desc_cxy;    // RPC request cluster (client)
     269    rpc_desc_t * desc_ptr;    // RPC request local pointer
     270    uint32_t     index;       // RPC request index
     271    uint32_t     responses;   // number of responses received by client
     272    thread_t   * thread_ptr;  // local pointer on client thread
     273    lid_t        core_lid;    // local index of client core
     274 
     275    // makes RPC thread not preemptable
     276        hal_disable_irq( NULL );
     277 
     278        thread_t      * this     = CURRENT_THREAD;
     279        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
     280
     281    // two embedded loops:
     282    // - external loop : "infinite" RPC thread
     283    // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
     284 
     285        while(1)  // external loop
     286        {
     287        // try to take RPC_FIFO ownership
     288        if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
     289        {
     290            // initializes RPC requests counter
     291            count = 0;
     292
     293            // acknowledge local IPI
     294            dev_pic_ack_ipi();
     295
     296                    // exit internal loop in three cases:
     297            // - RPC fifo is empty
     298            // - ownership has been lost (because descheduling)
     299            // - max number of RPCs is reached
     300                while( 1 )  // internal loop
     301            {
     302                    empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
     303
     304                    if ( empty == 0 ) // one RPC request found
     305                {
     306                    // get client cluster and pointer on RPC descriptor
     307                    desc_cxy = (cxy_t)GET_CXY( desc_xp );
     308                    desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp );
     309
     310                    // get rpc index from RPC descriptor
     311                        index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
     312
     313grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n",
     314__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
     315
     316                    // call the relevant server function
     317                    rpc_server[index]( desc_xp );
     318
     319grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n",
     320__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
     321
     322                    // increment handled RPC counter
     323                        count++;
     324
     325                    // decrement response counter in RPC descriptor
     326                    responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
     327
     328                    // unblock client thread  and send IPI to client core if last response
     329                    if( responses == 1 )
     330                    {
     331                        // get pointer on client thread and unblock it
     332                        thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread));
     333                        thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC );
     334
     335                        hal_fence();
     336
     337                        // get client core lid and send IPI
     338                        core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid));
     339                            dev_pic_send_ipi( desc_cxy , core_lid );
     340                    }
     341                        }
     342       
     343                // chek exit condition
     344                        if( local_fifo_is_empty( rpc_fifo )  ||
     345                    (rpc_fifo->owner != this->trdid) ||
     346                    (count >= CONFIG_RPC_PENDING_MAX) ) break;
     347                } // end internal loop
     348
     349            // release rpc_fifo ownership if not lost
     350            if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
     351        }
     352
     353        // sucide if too many RPC threads in cluster
     354        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
     355            {
     356
     357grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n",
     358__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     359
     360            // update RPC threads counter
     361                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
     362
     363            // suicide
     364                thread_kill( this );
     365            }
     366
     367grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n",
     368__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     369
     370        // deschedule without blocking
     371        sched_yield("RPC fifo empty or too much work");
     372
     373grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n",
     374__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
     375
     376        } // end external loop
     377
     378} // end rpc_thread_func()
     379
     380
     381/////////////////////////////////////////////////////////////////////////////////////////
     382// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
    92383/////////////////////////////////////////////////////////////////////////////////////////
    93384
     
    97388                                page_t  ** page )      // out
    98389{
    99     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    100     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    101     CURRENT_THREAD->core->lid , hal_time_stamp() );
     390rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     391__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     392CURRENT_THREAD->core->lid , hal_time_stamp() );
    102393
    103394    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     
    112403
    113404    // register RPC request in remote RPC fifo (blocking function)
    114     rpc_send_sync( cxy , &rpc );
     405    rpc_send( cxy , &rpc  , true );
    115406
    116407    // get output arguments from RPC descriptor
    117408    *page = (page_t *)(intptr_t)rpc.args[1];
    118409
    119     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    120     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    121     CURRENT_THREAD->core->lid , hal_time_stamp() );
     410rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     411__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     412CURRENT_THREAD->core->lid , hal_time_stamp() );
    122413}
    123414
     
    125416void rpc_pmem_get_pages_server( xptr_t xp )
    126417{
    127     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    128     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    129     CURRENT_THREAD->core->lid , hal_time_stamp() );
     418rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     419__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     420CURRENT_THREAD->core->lid , hal_time_stamp() );
    130421
    131422    // get client cluster identifier and pointer on RPC descriptor
     
    134425
    135426    // get input arguments from client RPC descriptor
    136     uint32_t order = hal_remote_lw( XPTR( cxy , &desc->args[0] ) );
     427    uint32_t order = (uint32_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
    137428   
    138429    // call local pmem allocator
     
    142433    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
    143434
    144     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    145     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    146     CURRENT_THREAD->core->lid , hal_time_stamp() );
    147 }
    148 
    149 /////////////////////////////////////////////////////////////////////////////////////////
    150 // [1]           Marshaling functions attached to RPC_PROCESS_MAKE_EXEC
     435rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     436__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     437CURRENT_THREAD->core->lid , hal_time_stamp() );
     438}
     439
     440/////////////////////////////////////////////////////////////////////////////////////////
     441// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking)
     442/////////////////////////////////////////////////////////////////////////////////////////
     443
     444//////////////////////////////////////////////////
     445void rpc_pmem_release_pages_client( cxy_t     cxy,
     446                                    page_t  * page )      // out
     447{
     448rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     449__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     450CURRENT_THREAD->core->lid , hal_time_stamp() );
     451
     452    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     453
     454    // initialise RPC descriptor header
     455    rpc_desc_t  rpc;
     456    rpc.index    = RPC_PMEM_RELEASE_PAGES;
     457    rpc.response = 1;
     458
     459    // set input arguments in RPC descriptor
     460    rpc.args[0] = (uint64_t)(intptr_t)page;
     461
     462    // register RPC request in remote RPC fifo (blocking function)
     463    rpc_send( cxy , &rpc  , true );
     464
     465rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     466__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     467CURRENT_THREAD->core->lid , hal_time_stamp() );
     468}
     469
     470///////////////////////////////////////////////
     471void rpc_pmem_release_pages_server( xptr_t xp )
     472{
     473rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     474__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     475CURRENT_THREAD->core->lid , hal_time_stamp() );
     476
     477    // get client cluster identifier and pointer on RPC descriptor
     478    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
     479    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
     480
     481    // get input arguments from client RPC descriptor
     482    page_t * page = (page_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
     483   
     484    // release memory to local pmem
     485    kmem_req_t req;
     486    req.type = KMEM_PAGE;
     487    req.ptr  = page;
     488    kmem_free( &req );
     489
     490rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     491__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     492CURRENT_THREAD->core->lid , hal_time_stamp() );
     493}
     494
     495/////////////////////////////////////////////////////////////////////////////////////////
     496// [2]           Marshaling functions attached to RPC_PROCESS_MAKE_EXEC (blocking)
    151497/////////////////////////////////////////////////////////////////////////////////////////
    152498
     
    156502                                   error_t     * error )   // out
    157503{
    158     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    159     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    160     CURRENT_THREAD->core->lid , hal_time_stamp() );
     504rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     505__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     506CURRENT_THREAD->core->lid , hal_time_stamp() );
    161507
    162508    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     
    171517
    172518    // register RPC request in remote RPC fifo (blocking function)
    173     rpc_send_sync( cxy , &rpc );
     519    rpc_send( cxy , &rpc  , true );
    174520
    175521    // get output arguments from RPC descriptor
    176522    *error  = (error_t)rpc.args[1];     
    177523
    178     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    179     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    180     CURRENT_THREAD->core->lid , hal_time_stamp() );
     524rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     525__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     526CURRENT_THREAD->core->lid , hal_time_stamp() );
    181527}
    182528
     
    184530void rpc_process_make_exec_server( xptr_t xp )
    185531{
     532rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     533__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     534CURRENT_THREAD->core->lid , hal_time_stamp() );
     535
    186536    exec_info_t * ptr;       // local pointer on remote exec_info structure
    187537    exec_info_t   info;      // local copy of exec_info structure
    188538    error_t       error;     // local error error status
    189 
    190     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    191     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    192     CURRENT_THREAD->core->lid , hal_time_stamp() );
    193539
    194540    // get client cluster identifier and pointer on RPC descriptor
     
    210556    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
    211557
    212     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    213     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    214     CURRENT_THREAD->core->lid , hal_time_stamp() );
    215 }
    216 
    217 /////////////////////////////////////////////////////////////////////////////////////////
    218 // [2]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK
     558rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     559__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     560CURRENT_THREAD->core->lid , hal_time_stamp() );
     561}
     562
     563/////////////////////////////////////////////////////////////////////////////////////////
     564// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking)
    219565/////////////////////////////////////////////////////////////////////////////////////////
    220566
     
    227573                                   error_t   * error )              // out
    228574{
    229     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    230     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    231     CURRENT_THREAD->core->lid , hal_time_stamp() );
     575rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     576__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     577CURRENT_THREAD->core->lid , hal_time_stamp() );
    232578
    233579    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     
    243589
    244590    // register RPC request in remote RPC fifo (blocking function)
    245     rpc_send_sync( cxy , &rpc );
     591    rpc_send( cxy , &rpc  , true );
    246592
    247593    // get output arguments from RPC descriptor
     
    250596    *error             = (error_t)rpc.args[4];     
    251597
    252     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    253     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    254     CURRENT_THREAD->core->lid , hal_time_stamp() );
     598rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     599__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     600CURRENT_THREAD->core->lid , hal_time_stamp() );
    255601}
    256602
     
    258604void rpc_process_make_fork_server( xptr_t xp )
    259605{
     606rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     607__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     608CURRENT_THREAD->core->lid , hal_time_stamp() );
     609
    260610    xptr_t     ref_process_xp;     // extended pointer on reference parent process
    261611    xptr_t     parent_thread_xp;   // extended pointer on parent thread
     
    264614    error_t    error;              // local error status
    265615
    266     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    267     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    268     CURRENT_THREAD->core->lid , hal_time_stamp() );
    269 
    270616    // get client cluster identifier and pointer on RPC descriptor
    271617    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     
    287633    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    288634
    289     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    290     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    291     CURRENT_THREAD->core->lid , hal_time_stamp() );
    292 }
    293 
    294 /////////////////////////////////////////////////////////////////////////////////////////
    295 // [3]           Marshaling functions attached to RPC_PROCESS_KILL
     635rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     636__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     637CURRENT_THREAD->core->lid , hal_time_stamp() );
     638}
     639
     640/////////////////////////////////////////////////////////////////////////////////////////
     641// [4]      Marshaling functions attached to RPC_PROCESS_MAKE_EXIT (blocking)
    296642/////////////////////////////////////////////////////////////////////////////////////////
    297643
    298644///////////////////////////////////////////////////
    299 void rpc_process_kill_client( process_t * process )
    300 {
    301     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    302     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    303     CURRENT_THREAD->core->lid , hal_time_stamp() );
    304 
    305     // only reference cluster can send this RPC
    306     assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ ,
    307             "caller must be reference process cluster\n");
    308 
    309     // get local process index in reference cluster
    310     lpid_t lpid = LPID_FROM_PID( process->pid );
    311 
    312     // get local process manager pointer
    313     pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr;
    314 
    315     // get number of copies
    316     uint32_t copies = pmgr->copies_nr[lpid];
    317 
    318     // initialise RPC descriptor
    319     rpc_desc_t  rpc;
    320     rpc.index    = RPC_PROCESS_KILL;
    321     rpc.response = copies;
    322     rpc.args[0]  = (uint64_t)process->pid;
    323 
    324     // loop on list of copies to send RPC
    325     xptr_t  iter;
    326     XLIST_FOREACH( XPTR( local_cxy , &pmgr->copies_root[lpid] ) , iter )
    327     {
    328         // get cluster_identifier for current copy
    329         cxy_t  target_cxy = GET_CXY( iter );
    330 
    331         // register RPC request in remote RPC fifo ... but the reference
    332         if( target_cxy != local_cxy ) rpc_send_sync( target_cxy , &rpc );
    333     }
    334 
    335     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    336     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    337     CURRENT_THREAD->core->lid , hal_time_stamp() );
     645void rpc_process_make_exit_client( cxy_t       cxy,
     646                                   process_t * process,
     647                                   uint32_t    status )
     648{
     649rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     650__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     651CURRENT_THREAD->core->lid , hal_time_stamp() );
     652
     653    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     654
     655    // initialise RPC descriptor header
     656    rpc_desc_t  rpc;
     657    rpc.index    = RPC_PROCESS_MAKE_EXIT;
     658    rpc.response = 1;
     659
     660    // set input arguments in RPC descriptor 
     661    rpc.args[0] = (uint64_t)(intptr_t)process;
     662    rpc.args[1] = (uint64_t)status;
     663
     664    // register RPC request in remote RPC fifo (blocking function)
     665    rpc_send( cxy , &rpc , true );
     666
     667rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     668__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     669CURRENT_THREAD->core->lid , hal_time_stamp() );
    338670
    339671
    340 /////////////////////////////////////////
    341 void rpc_process_kill_server( xptr_t xp )
    342 {
    343     pid_t       pid;
    344     process_t * process;
    345 
    346     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    347     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    348     CURRENT_THREAD->core->lid , hal_time_stamp() );
     672//////////////////////////////////////////////
     673void rpc_process_make_exit_server( xptr_t xp )
     674{
     675rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     676__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     677CURRENT_THREAD->core->lid , hal_time_stamp() );
     678
     679    process_t * process;
     680    uint32_t    status; 
    349681
    350682    // get client cluster identifier and pointer on RPC descriptor
     
    352684    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
    353685
    354     // get pid argument from RPC descriptor
    355     pid = (pid_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    356 
    357     // get process pointer to call local kernel function
    358     process = cluster_get_local_process_from_pid( pid );
    359 
    360     if( process == NULL )  // process not found => do nothing
    361     {
    362         printk("\n[WARNING] in %s : process %x not found in cluster %x\n",
    363                __FUNCTION__ , pid , local_cxy );
    364     }
    365     else                   // destroy process
    366     {
    367         process_kill( process );
    368     }
    369 
    370     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    371     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    372     CURRENT_THREAD->core->lid , hal_time_stamp() );
     686    // get arguments from RPC descriptor
     687    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     688    status  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     689
     690    // call local kernel function
     691    process_make_exit( process , status );
     692
     693rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     694__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     695CURRENT_THREAD->core->lid , hal_time_stamp() );
    373696}
    374697
    375 
    376 /////////////////////////////////////////////////////////////////////////////////////////
    377 // [4]           Marshaling functions attached to RPC_THREAD_USER_CREATE               
     698/////////////////////////////////////////////////////////////////////////////////////////
     699// [5]      Marshaling functions attached to RPC_PROCESS_MAKE_KILL (blocking)
     700/////////////////////////////////////////////////////////////////////////////////////////
     701
     702///////////////////////////////////////////////////
     703void rpc_process_make_kill_client( cxy_t       cxy,
     704                                   process_t * process,
     705                                   uint32_t    sig_id )
     706{
     707rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     708__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     709CURRENT_THREAD->core->lid , hal_time_stamp() );
     710
     711    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     712
     713    // initialise RPC descriptor header
     714    rpc_desc_t  rpc;
     715    rpc.index    = RPC_PROCESS_MAKE_KILL;
     716    rpc.response = 1;
     717
     718    // set input arguments in RPC descriptor 
     719    rpc.args[0] = (uint64_t)(intptr_t)process;
     720    rpc.args[1] = (uint64_t)sig_id;
     721
     722    // register RPC request in remote RPC fifo (blocking function)
     723    rpc_send( cxy , &rpc , true );
     724
     725rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     726__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     727CURRENT_THREAD->core->lid , hal_time_stamp() );
     728
     729
     730//////////////////////////////////////////////
     731void rpc_process_make_kill_server( xptr_t xp )
     732{
     733rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     734__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     735CURRENT_THREAD->core->lid , hal_time_stamp() );
     736
     737    process_t * process;
     738    uint32_t    sig_id;
     739
     740    // get client cluster identifier and pointer on RPC descriptor
     741    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     742    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     743
     744    // get arguments from RPC descriptor
     745    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     746    sig_id  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     747
     748    // call local kernel function
     749    process_make_exit( process , sig_id );
     750
     751rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     752__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     753CURRENT_THREAD->core->lid , hal_time_stamp() );
     754}
     755
     756/////////////////////////////////////////////////////////////////////////////////////////
     757// [6]           Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking)               
    378758/////////////////////////////////////////////////////////////////////////////////////////
    379759
     
    387767                                    error_t        * error )      // out
    388768{
    389     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    390     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    391     CURRENT_THREAD->core->lid , hal_time_stamp() );
     769rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     770__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     771CURRENT_THREAD->core->lid , hal_time_stamp() );
    392772
    393773    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     
    404784    rpc.args[3] = (uint64_t)(intptr_t)attr;
    405785
    406     // register RPC request in remote RPC fifo
    407     rpc_send_sync( cxy , &rpc );
     786    // register RPC request in remote RPC fifo (blocking function)
     787    rpc_send( cxy , &rpc , true );
    408788
    409789    // get output arguments from RPC descriptor
     
    411791    *error     = (error_t)rpc.args[5];
    412792
    413     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    414     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    415     CURRENT_THREAD->core->lid , hal_time_stamp() );
     793rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     794__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     795CURRENT_THREAD->core->lid , hal_time_stamp() );
    416796}
    417797
     
    419799void rpc_thread_user_create_server( xptr_t xp )
    420800{
     801rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     802__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     803CURRENT_THREAD->core->lid , hal_time_stamp() );
     804
    421805    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
    422806    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
     
    428812    void           * start_arg;
    429813    error_t          error;
    430 
    431     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    432     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    433     CURRENT_THREAD->core->lid , hal_time_stamp() );
    434814
    435815    // get client cluster identifier and pointer on RPC descriptor
     
    462842    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
    463843
    464     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    465     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    466     CURRENT_THREAD->core->lid , hal_time_stamp() );
    467 }
    468 
    469 /////////////////////////////////////////////////////////////////////////////////////////
    470 // [5]           Marshaling functions attached to RPC_THREAD_KERNEL_CREATE
     844rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     845__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     846CURRENT_THREAD->core->lid , hal_time_stamp() );
     847}
     848
     849/////////////////////////////////////////////////////////////////////////////////////////
     850// [7]           Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
    471851/////////////////////////////////////////////////////////////////////////////////////////
    472852
     
    479859                                      error_t * error )      // out
    480860{
    481     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    482     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    483     CURRENT_THREAD->core->lid , hal_time_stamp() );
     861rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     862__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     863CURRENT_THREAD->core->lid , hal_time_stamp() );
    484864
    485865    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     
    495875    rpc.args[2] = (uint64_t)(intptr_t)args;
    496876   
    497     // register RPC request in remote RPC fifo
    498     rpc_send_sync( cxy , &rpc );
     877    // register RPC request in remote RPC fifo (blocking function)
     878    rpc_send( cxy , &rpc , true );
    499879
    500880    // get output arguments from RPC descriptor
     
    502882    *error     = (error_t)rpc.args[4];
    503883
    504     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    505     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    506     CURRENT_THREAD->core->lid , hal_time_stamp() );
     884rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     885__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     886CURRENT_THREAD->core->lid , hal_time_stamp() );
    507887}
    508888
     
    510890void rpc_thread_kernel_create_server( xptr_t xp )
    511891{
     892rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     893__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     894CURRENT_THREAD->core->lid , hal_time_stamp() );
     895
    512896    thread_t       * thread_ptr;  // local pointer on thread descriptor
    513897    xptr_t           thread_xp;   // extended pointer on thread descriptor
     
    515899    error_t          error;   
    516900
    517     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    518     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    519     CURRENT_THREAD->core->lid , hal_time_stamp() );
    520 
    521901    // get client cluster identifier and pointer on RPC descriptor
    522902    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     
    539919    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
    540920
    541     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    542     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    543     CURRENT_THREAD->core->lid , hal_time_stamp() );
    544 }
    545 
    546 /////////////////////////////////////////////////////////////////////////////////////////
    547 // [6]           Marshaling functions attached to RPC_SIGNAL_RISE
     921rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     922__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     923CURRENT_THREAD->core->lid , hal_time_stamp() );
     924}
     925
     926/////////////////////////////////////////////////////////////////////////////////////////
     927// [8]           Marshaling functions attached to RPC_THREAD_KILL (blocking)
    548928/////////////////////////////////////////////////////////////////////////////////////////
    549929
    550930/////////////////////////////////////////////
    551 void rpc_signal_rise_client( cxy_t       cxy,
    552                              process_t * process,    // in
    553                              uint32_t    sig_id )    // in
    554 {
    555     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    556     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    557     CURRENT_THREAD->core->lid , hal_time_stamp() );
    558 
    559     assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    560 
    561     // initialise RPC descriptor header
    562     rpc_desc_t  rpc;
    563     rpc.index    = RPC_SIGNAL_RISE;
     931void rpc_thread_kill_client( cxy_t       cxy,
     932                             thread_t  * thread )    // in
     933{
     934rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     935__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     936CURRENT_THREAD->core->lid , hal_time_stamp() );
     937
     938    // this RPC can be called in local cluster
     939
     940    // initialise RPC descriptor header
     941    rpc_desc_t  rpc;
     942    rpc.index    = RPC_THREAD_KILL;
    564943    rpc.response = 1;
    565944
    566945    // set input arguments in RPC descriptor
    567     rpc.args[0] = (uint64_t)(intptr_t)process;
    568     rpc.args[1] = (uint64_t)sig_id;
     946    rpc.args[0] = (uint64_t)(intptr_t)thread;
    569947   
    570     // register RPC request in remote RPC fifo
    571     rpc_send_sync( cxy , &rpc );
    572 
    573     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    574     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    575     CURRENT_THREAD->core->lid , hal_time_stamp() );
     948    // register RPC request in remote RPC fifo (blocking function)
     949    rpc_send( cxy , &rpc , true );
     950
     951rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     952__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     953CURRENT_THREAD->core->lid , hal_time_stamp() );
    576954}
    577955
    578956////////////////////////////////////////                             
    579 void rpc_signal_rise_server( xptr_t xp )
    580 {
    581     process_t  * process;  // local pointer on process descriptor
    582     uint32_t     sig_id;   // signal index
    583 
    584     rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
    585     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    586     CURRENT_THREAD->core->lid , hal_time_stamp() );
     957void rpc_thread_kill_server( xptr_t xp )
     958{
     959rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
     960__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     961CURRENT_THREAD->core->lid , hal_time_stamp() );
     962
     963    thread_t  * thread;  // local pointer on process descriptor
    587964
    588965    // get client cluster identifier and pointer on RPC descriptor
     
    591968
    592969    // get attributes from RPC descriptor
    593     process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    594     sig_id  = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     970    thread = (thread_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    595971
    596972    // call local kernel function
    597     signal_rise( process , sig_id );
    598 
    599     rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
    600     __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
    601     CURRENT_THREAD->core->lid , hal_time_stamp() );
    602 }
    603 
    604 /////////////////////////////////////////////////////////////////////////////////////////
    605 // [10]          Marshaling functions attached to RPC_VFS_INODE_CREATE
     973    thread_kill( thread );
     974
     975rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     976__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,
     977CURRENT_THREAD->core->lid , hal_time_stamp() );
     978}
     979
     980
     981/////////////////////////////////////////////////////////////////////////////////////////
     982// [9]     Marshaling functions attached to RPC_PROCESS_KILL  (multicast / non blocking)
     983/////////////////////////////////////////////////////////////////////////////////////////
     984
     985///////////////////////////////////////////////////
     986void rpc_process_sigaction_client( cxy_t       cxy,
     987                                   process_t * process,        // in
     988                                   uint32_t    sigaction,      // in
     989                                   xptr_t      rsp_xp,         // in
     990                                   xptr_t      client_xp )     // in
     991{
     992signal_dmsg("\n[DBG] %s : enter for %s / thread %x on core[%x,%d] / cycle %d\n",
     993__FUNCTION__ , process_action_str( sigaction ) , CURRENT_THREAD ,
     994local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     995
     996    // initialise RPC descriptor header
     997    rpc_desc_t  rpc;
     998    rpc.index    = RPC_PROCESS_SIGACTION;
     999
     1000    // set input arguments in RPC descriptor 
     1001    rpc.args[0] = (uint64_t)(intptr_t)process;
     1002    rpc.args[1] = (uint64_t)sigaction;
     1003    rpc.args[2] = (uint64_t)rsp_xp;
     1004    rpc.args[3] = (uint64_t)client_xp;
     1005
     1006    // register RPC request in remote RPC fifo (non blocking)
     1007    rpc_send( cxy , &rpc , false );
     1008
     1009signal_dmsg("\n[DBG] %s : exit for %s / thread %x on core[%x,%d] / cycle %d\n",
     1010__FUNCTION__ , process_action_str( sigaction ) , CURRENT_THREAD ,
     1011local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     1012
     1013
     1014//////////////////////////////////////////////
     1015void rpc_process_sigaction_server( xptr_t xp )
     1016{
     1017    process_t * process;
     1018    uint32_t    action; 
     1019    xptr_t      rsp_xp;
     1020    xptr_t      client_xp;
     1021
     1022    // get client cluster identifier and pointer on RPC descriptor
     1023    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     1024    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     1025
     1026    // get arguments from RPC descriptor
     1027    process   = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
     1028    action    = (uint32_t)             hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     1029    rsp_xp    = (xptr_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
     1030    client_xp = (xptr_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
     1031   
     1032signal_dmsg("\n[DBG] %s : enter for %s / thread %x on core[%x,%d] / cycle %d\n",
     1033__FUNCTION__ , process_action_str( action ) , CURRENT_THREAD ,
     1034local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     1035
     1036    // call relevant kernel function
     1037    if      (action == DELETE_ALL_THREADS  ) process_delete ( process , rsp_xp , client_xp );
     1038    else if (action == BLOCK_ALL_THREADS   ) process_block  ( process , rsp_xp , client_xp );
     1039    else if (action == UNBLOCK_ALL_THREADS ) process_unblock( process , rsp_xp , client_xp );
     1040
     1041signal_dmsg("\n[DBG] %s : exit for %s / thread %x on core[%x,%d] / cycle %d\n",
     1042__FUNCTION__ , process_action_str( action ) , CURRENT_THREAD ,
     1043local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() );
     1044}
     1045
     1046/////////////////////////////////////////////////////////////////////////////////////////
     1047// [10]          Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
    6061048/////////////////////////////////////////////////////////////////////////////////////////
    6071049
     
    6411083
    6421084    // register RPC request in remote RPC fifo (blocking function)
    643     rpc_send_sync( cxy , &rpc );
     1085    rpc_send( cxy , &rpc , true );
    6441086
    6451087    // get output values from RPC descriptor
     
    7051147
    7061148/////////////////////////////////////////////////////////////////////////////////////////
    707 // [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY
     1149// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
    7081150/////////////////////////////////////////////////////////////////////////////////////////
    7091151
     
    7271169   
    7281170    // register RPC request in remote RPC fifo (blocking function)
    729     rpc_send_sync( cxy , &rpc );
     1171    rpc_send( cxy , &rpc , true );
    7301172
    7311173    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    7591201
    7601202/////////////////////////////////////////////////////////////////////////////////////////
    761 // [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE
     1203// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
    7621204/////////////////////////////////////////////////////////////////////////////////////////
    7631205
     
    7871229
    7881230    // register RPC request in remote RPC fifo (blocking function)
    789     rpc_send_sync( cxy , &rpc );
     1231    rpc_send( cxy , &rpc , true );
    7901232
    7911233    // get output values from RPC descriptor
     
    8411283
    8421284/////////////////////////////////////////////////////////////////////////////////////////
    843 // [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY
     1285// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
    8441286/////////////////////////////////////////////////////////////////////////////////////////
    8451287
     
    8641306   
    8651307    // register RPC request in remote RPC fifo (blocking function)
    866     rpc_send_sync( cxy , &rpc );
     1308    rpc_send( cxy , &rpc , true );
    8671309
    8681310    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    8971339
    8981340/////////////////////////////////////////////////////////////////////////////////////////
    899 // [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE
     1341// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
    9001342/////////////////////////////////////////////////////////////////////////////////////////
    9011343
     
    9231365
    9241366    // register RPC request in remote RPC fifo (blocking function)
    925     rpc_send_sync( cxy , &rpc );
     1367    rpc_send( cxy , &rpc , true );
    9261368
    9271369    // get output values from RPC descriptor
     
    9691411
    9701412/////////////////////////////////////////////////////////////////////////////////////////
    971 // [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY
     1413// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
    9721414/////////////////////////////////////////////////////////////////////////////////////////
    9731415
     
    9911433   
    9921434    // register RPC request in remote RPC fifo (blocking function)
    993     rpc_send_sync( cxy , &rpc );
     1435    rpc_send( cxy , &rpc , true );
    9941436
    9951437    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    10231465
    10241466/////////////////////////////////////////////////////////////////////////////////////////
    1025 // [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD 
     1467// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   (blocking)
    10261468/////////////////////////////////////////////////////////////////////////////////////////
    10271469
     
    10501492
    10511493    // register RPC request in remote RPC fifo (blocking function)
    1052     rpc_send_sync( cxy , &rpc );
     1494    rpc_send( cxy , &rpc , true );
    10531495
    10541496    // get output values from RPC descriptor
     
    10991541
    11001542/////////////////////////////////////////////////////////////////////////////////////////
    1101 // [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL
     1543// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL  (blocking)
    11021544/////////////////////////////////////////////////////////////////////////////////////////
    11031545
     
    11221564
    11231565    // register RPC request in remote RPC fifo (blocking function)
    1124     rpc_send_sync( cxy , &rpc );
     1566    rpc_send( cxy , &rpc , true );
    11251567
    11261568    // get output values from RPC descriptor
     
    11611603
    11621604/////////////////////////////////////////////////////////////////////////////////////////
    1163 // [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER
     1605// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  (blocking)
    11641606/////////////////////////////////////////////////////////////////////////////////////////
    11651607
     
    11891631
    11901632    // register RPC request in remote RPC fifo
    1191     rpc_send_sync( cxy , &rpc );
     1633    rpc_send( cxy , &rpc , true );
    11921634
    11931635    // get output argument from rpc descriptor
     
    12351677
    12361678/////////////////////////////////////////////////////////////////////////////////////////
    1237 // [20]          Marshaling functions attached to RPC_VMM_GET_VSEG
     1679// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
    12381680/////////////////////////////////////////////////////////////////////////////////////////
    12391681
     
    12611703
    12621704    // register RPC request in remote RPC fifo (blocking function)
    1263     rpc_send_sync( cxy , &rpc );
     1705    rpc_send( cxy , &rpc , true );
    12641706
    12651707    // get output argument from rpc descriptor
     
    13081750
    13091751/////////////////////////////////////////////////////////////////////////////////////////
    1310 // [21]          Marshaling functions attached to RPC_VMM_GET_PTE
     1752// [21]          Marshaling functions attached to RPC_VMM_GET_PTE  (blocking)
    13111753/////////////////////////////////////////////////////////////////////////////////////////
    13121754
     
    13371779
    13381780    // register RPC request in remote RPC fifo (blocking function)
    1339     rpc_send_sync( cxy , &rpc );
     1781    rpc_send( cxy , &rpc , true );
    13401782
    13411783    // get output argument from rpc descriptor
     
    13861828
    13871829/////////////////////////////////////////////////////////////////////////////////////////
    1388 // [22]          Marshaling functions attached to RPC_KCM_ALLOC
     1830// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
    13891831/////////////////////////////////////////////////////////////////////////////////////////
    13901832
     
    14081850    rpc.args[0] = (uint64_t)kmem_type;
    14091851
    1410     // register RPC request in remote RPC fifo
    1411     rpc_send_sync( cxy , &rpc );
     1852    // register RPC request in remote RPC fifo (blocking function)
     1853    rpc_send( cxy , &rpc , true );
    14121854
    14131855    // get output arguments from RPC descriptor
     
    14491891
    14501892/////////////////////////////////////////////////////////////////////////////////////////
    1451 // [23]          Marshaling functions attached to RPC_KCM_FREE
     1893// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
    14521894/////////////////////////////////////////////////////////////////////////////////////////
    14531895
     
    14721914    rpc.args[1] = (uint64_t)kmem_type;
    14731915
    1474     // register RPC request in remote RPC fifo
    1475     rpc_send_sync( cxy , &rpc );
     1916    // register RPC request in remote RPC fifo (blocking function)
     1917    rpc_send( cxy , &rpc , true );
    14761918
    14771919    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    15401982
    15411983    // register RPC request in remote RPC fifo (blocking function)
    1542     rpc_send_sync( cxy , &rpc );
     1984    rpc_send( cxy , &rpc , true );
    15431985
    15441986    // get output values from RPC descriptor
     
    16082050
    16092051/////////////////////////////////////////////////////////////////////////////////////////
    1610 // [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE
     2052// [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking)
    16112053/////////////////////////////////////////////////////////////////////////////////////////
    16122054
     
    16332075
    16342076    // register RPC request in remote RPC fifo (blocking function)
    1635     rpc_send_sync( cxy , &rpc );
     2077    rpc_send( cxy , &rpc , true );
    16362078
    16372079    // get output values from RPC descriptor
     
    16702112
    16712113/////////////////////////////////////////////////////////////////////////////////////////
    1672 // [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG
     2114// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
    16732115/////////////////////////////////////////////////////////////////////////////////////////
    16742116
     
    17072149
    17082150    // register RPC request in remote RPC fifo (blocking function)
    1709     rpc_send_sync( cxy , &rpc );
     2151    rpc_send( cxy , &rpc , true );
    17102152
    17112153    // get output values from RPC descriptor
     
    17572199
    17582200/////////////////////////////////////////////////////////////////////////////////////////
    1759 // [27]          Marshaling functions attached to RPC_SCHED_DISPLAY
     2201// [27]          Marshaling functions attached to RPC_SCHED_DISPLAY (blocking)
    17602202/////////////////////////////////////////////////////////////////////////////////////////
    17612203
     
    17792221
    17802222    // register RPC request in remote RPC fifo (blocking function)
    1781     rpc_send_sync( cxy , &rpc );
     2223    rpc_send( cxy , &rpc , true );
    17822224
    17832225    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    18092251
    18102252/////////////////////////////////////////////////////////////////////////////////////////
    1811 // [28]          Marshaling functions attached to RPC_VMM_SET_COW
     2253// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
    18122254/////////////////////////////////////////////////////////////////////////////////////////
    18132255
     
    18312273
    18322274    // register RPC request in remote RPC fifo (blocking function)
    1833     rpc_send_sync( cxy , &rpc );
     2275    rpc_send( cxy , &rpc , true );
    18342276
    18352277    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
     
    18622304}
    18632305
    1864 /***************************************************************************************/
    1865 /************ Generic functions supporting RPCs : client side **************************/
    1866 /***************************************************************************************/
    1867 
    1868 ////////////////////////////////////////////
    1869 void rpc_send_sync( cxy_t        server_cxy,
    1870                     rpc_desc_t * rpc )
    1871 {
    1872     error_t    error;
    1873 
    1874     thread_t * this = CURRENT_THREAD;
    1875     core_t   * core = this->core;
    1876 
    1877     // register client thread pointer and core lid in RPC descriptor
    1878     rpc->thread    = this;
    1879     rpc->lid       = core->lid;
    1880 
    1881     // build an extended pointer on the RPC descriptor
    1882         xptr_t   desc_xp = XPTR( local_cxy , rpc );
    1883 
    1884     // get local pointer on rpc_fifo in remote cluster, with the
    1885     // assumption that local pointers are identical in all clusters
    1886     remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    1887 
    1888         // try to post an item in remote fifo
    1889     // deschedule and retry if remote fifo full
    1890     do
    1891     {
    1892         error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ),
    1893                                       (uint64_t )desc_xp );
    1894             if ( error )
    1895         {
    1896             printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
    1897             __FUNCTION__ , local_cxy , server_cxy );
    1898 
    1899             if( thread_can_yield() ) sched_yield("RPC fifo full");
    1900         }
    1901     }
    1902     while( error );
    1903  
    1904     hal_fence();
    1905        
    1906     // send IPI to the remote core corresponding to the client core
    1907         dev_pic_send_ipi( server_cxy , core->lid );
    1908 
    1909     // wait RPC completion:
    1910     // - busy waiting policy during kernel_init, or if threads cannot yield
    1911     // - block and deschedule in all other cases
    1912 
    1913     if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
    1914     {
    1915 
    1916 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n"
    1917 "        rpc = %d / server = %x / cycle %d\n",
    1918 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
    1919 rpc->index , server_cxy , hal_time_stamp() );
    1920 
    1921         while( rpc->response ) hal_fixed_delay( 100 );
    1922    
    1923 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n",
    1924 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
    1925 
    1926     }
    1927     else                                                              // block & deschedule
    1928     {
    1929 
    1930 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n"
    1931 "        rpc = %d / server = %x / cycle %d\n",
    1932 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
    1933 rpc->index , server_cxy , hal_time_stamp() );
    1934 
    1935         thread_block( this , THREAD_BLOCKED_RPC );
    1936         sched_yield("client blocked on RPC");
    1937 
    1938 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n",
    1939 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
    1940 
    1941     }
    1942 
    1943     // check response available
    1944     assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" );
    1945 
    1946     // acknowledge the IPI sent by the server
    1947     dev_pic_ack_ipi();
    1948    
    1949 }  // end rpc_send_sync()
    1950 
    1951 
    1952 
    1953 /***************************************************************************************/
    1954 /************ Generic functions supporting RPCs : server side **************************/
    1955 /***************************************************************************************/
    1956 
    1957 ////////////////
    1958 void rpc_check()
    1959 {
    1960     error_t         error;
    1961     thread_t      * thread; 
    1962     uint32_t        sr_save;
    1963 
    1964     bool_t          found    = false;
    1965         thread_t      * this     = CURRENT_THREAD;
    1966     core_t        * core     = this->core;
    1967     scheduler_t   * sched    = &core->scheduler;
    1968         remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    1969 
    1970 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n",
    1971 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
    1972 
    1973     // interrupted thread not preemptable during RPC chek
    1974         hal_disable_irq( &sr_save );
    1975 
    1976     // check RPC FIFO not empty and no RPC thread handling it 
    1977         if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
    1978     {
    1979         // search one non blocked RPC thread   
    1980         list_entry_t * iter;
    1981         LIST_FOREACH( &sched->k_root , iter )
    1982         {
    1983             thread = LIST_ELEMENT( iter , thread_t , sched_list );
    1984             if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) )
    1985             {
    1986                 found = true;
    1987                 break;
    1988             }
    1989         }
    1990 
    1991         // create new RPC thread if not found   
    1992         if( found == false )                   
    1993         {
    1994             error = thread_kernel_create( &thread,
    1995                                           THREAD_RPC,
    1996                                                       &rpc_thread_func,
    1997                                           NULL,
    1998                                                       this->core->lid );
    1999                 if( error )
    2000             {
    2001                 printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n",
    2002                 __FUNCTION__ , local_cxy );
    2003             }
    2004             else
    2005             {
    2006                 // unblock created RPC thread
    2007                 thread->blocked = 0;
    2008 
    2009                 // update core descriptor counter 
    2010                     hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
    2011 
    2012 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n",
    2013 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() );
    2014 
    2015             }
    2016         }
    2017     }
    2018 
    2019 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n",
    2020 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
    2021 
    2022     // interrupted thread deschedule always           
    2023         sched_yield("IPI received");
    2024 
    2025 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n",
    2026 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
    2027 
    2028     // interrupted thread restore IRQs after resume
    2029         hal_restore_irq( sr_save );
    2030 
    2031 } // end rpc_check()
    2032 
    2033 
    2034 //////////////////////
    2035 void rpc_thread_func()
    2036 {
    2037     uint32_t     count;       // handled RPC requests counter
    2038     error_t      empty;       // local RPC fifo state
    2039     xptr_t       desc_xp;     // extended pointer on RPC request
    2040     cxy_t        desc_cxy;    // RPC request cluster (client)
    2041     rpc_desc_t * desc_ptr;    // RPC request local pointer
    2042     uint32_t     index;       // RPC request index
    2043     uint32_t     responses;   // number of responses received by client
    2044     thread_t   * thread_ptr;  // local pointer on client thread
    2045     lid_t        core_lid;    // local index of client core
    2046  
    2047     // makes RPC thread not preemptable
    2048         hal_disable_irq( NULL );
    2049  
    2050         thread_t      * this     = CURRENT_THREAD;
    2051         remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
    2052 
    2053     // two embedded loops:
    2054     // - external loop : "infinite" RPC thread
    2055     // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
    2056  
    2057         while(1)  // external loop
    2058         {
    2059         // try to take RPC_FIFO ownership
    2060         if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
    2061         {
    2062             // initializes RPC requests counter
    2063             count = 0;
    2064 
    2065             // acknowledge local IPI
    2066             dev_pic_ack_ipi();
    2067 
    2068                     // exit internal loop in three cases:
    2069             // - RPC fifo is empty
    2070             // - ownership has been lost (because descheduling)
    2071             // - max number of RPCs is reached
    2072                 while( 1 )  // internal loop
    2073             {
    2074                     empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
    2075 
    2076                     if ( empty == 0 ) // one RPC request found
    2077                 {
    2078                     // get client cluster and pointer on RPC descriptor
    2079                     desc_cxy = (cxy_t)GET_CXY( desc_xp );
    2080                     desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp );
    2081 
    2082                     // get rpc index from RPC descriptor
    2083                         index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) );
    2084 
    2085 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n",
    2086 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
    2087 
    2088                     // call the relevant server function
    2089                     rpc_server[index]( desc_xp );
    2090 
    2091 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n",
    2092 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() );
    2093 
    2094                     // increment handled RPC counter
    2095                         count++;
    2096 
    2097                     // decrement response counter in RPC descriptor
    2098                     responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1);
    2099 
    2100                     // unblock client thread  and send IPI to client core if last response
    2101                     if( responses == 1 )
    2102                     {
    2103                         // get pointer on client thread and unblock it
    2104                         thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread));
    2105                         thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC );
    2106 
    2107                         hal_fence();
    2108 
    2109                         // get client core lid and send IPI
    2110                         core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid));
    2111                             dev_pic_send_ipi( desc_cxy , core_lid );
    2112                     }
    2113                         }
    2114        
    2115                 // chek exit condition
    2116                         if( local_fifo_is_empty( rpc_fifo )  ||
    2117                     (rpc_fifo->owner != this->trdid) ||
    2118                     (count >= CONFIG_RPC_PENDING_MAX) ) break;
    2119                 } // end internal loop
    2120 
    2121             // release rpc_fifo ownership if not lost
    2122             if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0;
    2123         }
    2124 
    2125         // sucide if too many RPC threads in cluster
    2126         if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
    2127             {
    2128 
    2129 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n",
    2130 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2131 
    2132             // update RPC threads counter
    2133                 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
    2134 
    2135             // suicide
    2136                 thread_exit();
    2137             }
    2138 
    2139 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n",
    2140 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2141 
    2142         // deschedule without blocking
    2143         sched_yield("RPC fifo empty or too much work");
    2144 
    2145 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n",
    2146 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
    2147 
    2148         } // end external loop
    2149 
    2150 } // end rpc_thread_func()
    2151 
    2152 
     2306
Note: See TracChangeset for help on using the changeset viewer.