source: trunk/kernel/kern/rpc.c @ 429

Last change on this file since 429 was 428, checked in by alain, 7 years ago

blip

File size: 93.4 KB
RevLine 
[1]1/*
2 * rpc.c - RPC related operations implementation.
3 *
[23]4 * Author    Alain Greiner (2016,2017)
[1]5 *
6 * Copyright (c)  UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[14]24#include <kernel_config.h>
[1]25#include <hal_types.h>
26#include <hal_atomic.h>
27#include <hal_remote.h>
28#include <hal_irqmask.h>
29#include <hal_special.h>
30#include <printk.h>
31#include <remote_sem.h>
32#include <core.h>
33#include <mapper.h>
[5]34#include <chdev.h>
[1]35#include <bits.h>
36#include <thread.h>
37#include <cluster.h>
38#include <process.h>
39#include <vfs.h>
40#include <fatfs.h>
[23]41#include <signal.h>
[1]42#include <rpc.h>
43
44/////////////////////////////////////////////////////////////////////////////////////////
45//      array of function pointers  (must be consistent with enum in rpc.h)
46/////////////////////////////////////////////////////////////////////////////////////////
47
48rpc_server_t * rpc_server[RPC_MAX_INDEX] =
49{
50    &rpc_pmem_get_pages_server,         // 0
[409]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
[1]60
61    &rpc_vfs_inode_create_server,       // 10 
62    &rpc_vfs_inode_destroy_server,      // 11 
63    &rpc_vfs_dentry_create_server,      // 12 
64    &rpc_vfs_dentry_destroy_server,     // 13 
[23]65    &rpc_vfs_file_create_server,        // 14
66    &rpc_vfs_file_destroy_server,       // 15
[238]67    &rpc_vfs_inode_load_server,         // 16
68    &rpc_vfs_mapper_load_all_server,    // 17
69    &rpc_fatfs_get_cluster_server,      // 18
[1]70    &rpc_undefined,                     // 19
71
[389]72    &rpc_vmm_get_vseg_server,           // 20
[1]73    &rpc_vmm_get_pte_server,            // 21
[23]74    &rpc_kcm_alloc_server,              // 22
75    &rpc_kcm_free_server,               // 23
[265]76    &rpc_mapper_move_buffer_server,     // 24
[313]77    &rpc_mapper_get_page_server,        // 25
[407]78    &rpc_vmm_create_vseg_server,        // 26
79    &rpc_sched_display_server,          // 27
[408]80    &rpc_vmm_set_cow_server,            // 28
[428]81    &rpc_vmm_display_server,            // 29
[1]82};
83
84//////////////////////////////////////////////
85void __attribute__((noinline)) rpc_undefined()
86{
[428]87        assert( false , __FUNCTION__ , "called in cluster %x", local_cxy );
[1]88}
89
[409]90/***************************************************************************************/
91/************ Generic functions supporting RPCs : client side **************************/
92/***************************************************************************************/
93
94///////////////////////////////////////
95void rpc_send( cxy_t        server_cxy, 
[416]96               rpc_desc_t * rpc )
[409]97{
98    error_t    error;
99
100    thread_t * this = CURRENT_THREAD;
101    core_t   * core = this->core;
102
103    // register client thread pointer and core lid in RPC descriptor
104    rpc->thread    = this;
105    rpc->lid       = core->lid;
106
107    // build an extended pointer on the RPC descriptor
108        xptr_t   desc_xp = XPTR( local_cxy , rpc );
109
110    // get local pointer on rpc_fifo in remote cluster, with the
111    // assumption that local pointers are identical in all clusters
112    remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
113
114        // try to post an item in remote fifo
115    // deschedule and retry if remote fifo full
116    do
117    { 
118        error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ),
119                                      (uint64_t )desc_xp );
120            if ( error ) 
121        {
122            printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n",
123            __FUNCTION__ , local_cxy , server_cxy );
124
125            if( thread_can_yield() ) sched_yield("RPC fifo full");
126        }
127    }
128    while( error );
129 
130    hal_fence();
131       
132    // send IPI to the remote core corresponding to the client core
133        dev_pic_send_ipi( server_cxy , core->lid );
134
[416]135    // wait RPC completion before returning if blocking RPC
[409]136    // - busy waiting policy during kernel_init, or if threads cannot yield
137    // - block and deschedule in all other cases
[416]138    if ( rpc->blocking )
[409]139    {
140        if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting
141        {
142
143grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n"
144"        rpc = %d / server = %x / cycle %d\n",
145__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
146rpc->index , server_cxy , hal_time_stamp() );
147
148            while( rpc->response ) hal_fixed_delay( 100 );
149   
150grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n",
151__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
152
153        } 
154        else                                                              // block & deschedule
155        {
156
157grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n"
158"        rpc = %d / server = %x / cycle %d\n",
159__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ,
160rpc->index , server_cxy , hal_time_stamp() );
161
162            thread_block( this , THREAD_BLOCKED_RPC );
163            sched_yield("BLOCKED on RPC");
164
165grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n",
166__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) );
167
168        }
169
170        // check response available
171        assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" );
172
173        // acknowledge the IPI sent by the server
174        dev_pic_ack_ipi();
175    }
176}  // end rpc_send()
177
178
179/***************************************************************************************/
180/************ Generic functions supporting RPCs : server side **************************/
181/***************************************************************************************/
182
183////////////////
184void rpc_check()
185{
186    error_t         error;
187    thread_t      * thread; 
188    uint32_t        sr_save;
189
190    bool_t          found    = false;
191        thread_t      * this     = CURRENT_THREAD;
192    core_t        * core     = this->core;
193    scheduler_t   * sched    = &core->scheduler;
194        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
195
196grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n",
197__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
198
199    // interrupted thread not preemptable during RPC chek
200        hal_disable_irq( &sr_save );
201
202    // check RPC FIFO not empty and no RPC thread handling it 
203        if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) )
204    {
205        // search one non blocked RPC thread   
206        list_entry_t * iter;
207        LIST_FOREACH( &sched->k_root , iter )
208        {
209            thread = LIST_ELEMENT( iter , thread_t , sched_list );
210            if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 
211            {
212                found = true;
213                break;
214            }
215        }
216
217        // create new RPC thread if not found   
218        if( found == false )                   
219        {
220            error = thread_kernel_create( &thread,
221                                          THREAD_RPC, 
222                                                      &rpc_thread_func, 
223                                          NULL,
224                                                      this->core->lid );
225                if( error ) 
226            {
227                printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n",
228                __FUNCTION__ , local_cxy );
229            }
230            else
231            {
232                // unblock created RPC thread
233                thread->blocked = 0;
234
235                // update core descriptor counter 
236                    hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 );
237
[416]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() );
[409]240
241            }
242        }
243    }
244
245grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n", 
246__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
247
248    // interrupted thread deschedule always           
249        sched_yield("IPI received");
250
251grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", 
252__FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() );
253
254    // interrupted thread restore IRQs after resume
255        hal_restore_irq( sr_save );
256
257} // end rpc_check()
258
259
260//////////////////////
261void rpc_thread_func()
262{
263    uint32_t     count;       // handled RPC requests counter
264    error_t      empty;       // local RPC fifo state
265    xptr_t       desc_xp;     // extended pointer on RPC request
266    cxy_t        desc_cxy;    // RPC request cluster (client)
267    rpc_desc_t * desc_ptr;    // RPC request local pointer
268    uint32_t     index;       // RPC request index
269    thread_t   * thread_ptr;  // local pointer on client thread
270    lid_t        core_lid;    // local index of client core
[416]271    bool_t       blocking;    // blocking RPC when true
[409]272 
273    // makes RPC thread not preemptable
274        hal_disable_irq( NULL );
275 
276        thread_t      * this     = CURRENT_THREAD;
277        remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo;
278
279    // two embedded loops:
280    // - external loop : "infinite" RPC thread
281    // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests
282 
283        while(1)  // external loop
284        {
285        // try to take RPC_FIFO ownership
286        if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) )
287        {
288            // initializes RPC requests counter
289            count = 0;
290
291            // acknowledge local IPI
292            dev_pic_ack_ipi();
293
294                    // exit internal loop in three cases:
295            // - RPC fifo is empty
296            // - ownership has been lost (because descheduling)
297            // - max number of RPCs is reached
298                while( 1 )  // internal loop
299            {
[415]300
[409]301                    empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp );
302
303                    if ( empty == 0 ) // one RPC request found
304                {
305                    // get client cluster and pointer on RPC descriptor
306                    desc_cxy = (cxy_t)GET_CXY( desc_xp );
307                    desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp );
308
[416]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 ) );
[409]312
313grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n",
[415]314__FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , (uint32_t)hal_get_cycles() );
[409]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
[416]322                    // increment handled RPCs counter
[409]323                        count++;
324
[416]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);
[409]330
[416]331                        // unblock client thread
[409]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
[416]352        }  // end if RPC fifo
353
[409]354        // sucide if too many RPC threads in cluster
355        if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX )
356            {
357
358grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n", 
359__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
360
361            // update RPC threads counter
362                hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 );
363
364            // suicide
365                thread_kill( this );
366            }
367
368grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n", 
369__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
370
371        // deschedule without blocking
372        sched_yield("RPC fifo empty or too much work");
373
374grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", 
375__FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() );
376
377        } // end external loop
378
379} // end rpc_thread_func()
380
381
[1]382/////////////////////////////////////////////////////////////////////////////////////////
[409]383// [0]           Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking)
[1]384/////////////////////////////////////////////////////////////////////////////////////////
385
386///////////////////////////////////////////////
387void rpc_pmem_get_pages_client( cxy_t      cxy,
388                                uint32_t   order,      // in
[313]389                                page_t  ** page )      // out
[1]390{
[409]391rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
392__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
393CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]394
[238]395    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]396
397    // initialise RPC descriptor header
398    rpc_desc_t  rpc;
399    rpc.index    = RPC_PMEM_GET_PAGES;
400    rpc.response = 1;
[416]401    rpc.blocking = true;
[1]402
403    // set input arguments in RPC descriptor
404    rpc.args[0] = (uint64_t)order;
405
406    // register RPC request in remote RPC fifo (blocking function)
[416]407    rpc_send( cxy , &rpc );
[1]408
[313]409    // get output arguments from RPC descriptor
[407]410    *page = (page_t *)(intptr_t)rpc.args[1];
[279]411
[409]412rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
413__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
414CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]415}
416
417///////////////////////////////////////////
418void rpc_pmem_get_pages_server( xptr_t xp )
419{
[409]420rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
421__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
422CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]423
[1]424    // get client cluster identifier and pointer on RPC descriptor
425    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
426    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
427
428    // get input arguments from client RPC descriptor
[409]429    uint32_t order = (uint32_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
[1]430   
431    // call local pmem allocator
432    page_t * page = ppm_alloc_pages( order ); 
433
434    // set output arguments into client RPC descriptor
[313]435    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
[296]436
[409]437rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
438__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
439CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]440}
441
442/////////////////////////////////////////////////////////////////////////////////////////
[409]443// [1]       Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking)
[1]444/////////////////////////////////////////////////////////////////////////////////////////
445
[409]446//////////////////////////////////////////////////
447void rpc_pmem_release_pages_client( cxy_t     cxy,
448                                    page_t  * page )      // out
449{
450rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
451__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
452CURRENT_THREAD->core->lid , hal_time_stamp() );
453
454    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
455
456    // initialise RPC descriptor header
457    rpc_desc_t  rpc;
458    rpc.index    = RPC_PMEM_RELEASE_PAGES;
459    rpc.response = 1;
[416]460    rpc.blocking = true;
[409]461
462    // set input arguments in RPC descriptor
463    rpc.args[0] = (uint64_t)(intptr_t)page;
464
465    // register RPC request in remote RPC fifo (blocking function)
[416]466    rpc_send( cxy , &rpc );
[409]467
468rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
469__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
470CURRENT_THREAD->core->lid , hal_time_stamp() );
471}
472
473///////////////////////////////////////////////
474void rpc_pmem_release_pages_server( xptr_t xp )
475{
476rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
477__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
478CURRENT_THREAD->core->lid , hal_time_stamp() );
479
480    // get client cluster identifier and pointer on RPC descriptor
481    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
482    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
483
484    // get input arguments from client RPC descriptor
485    page_t * page = (page_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
486   
487    // release memory to local pmem
488    kmem_req_t req;
489    req.type = KMEM_PAGE;
490    req.ptr  = page;
491    kmem_free( &req );
492
493rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
494__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
495CURRENT_THREAD->core->lid , hal_time_stamp() );
496}
497
498/////////////////////////////////////////////////////////////////////////////////////////
499// [2]           Marshaling functions attached to RPC_PROCESS_MAKE_EXEC (blocking)
500/////////////////////////////////////////////////////////////////////////////////////////
501
[408]502/////////////////////////////////////////////////////
503void rpc_process_make_exec_client( cxy_t         cxy,
504                                   exec_info_t * info,     // in
505                                   error_t     * error )   // out
[1]506{
[409]507rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
508__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
509CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]510
[238]511    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]512
513    // initialise RPC descriptor header
514    rpc_desc_t  rpc;
[408]515    rpc.index    = RPC_PROCESS_MAKE_EXEC;
[1]516    rpc.response = 1;
[416]517    rpc.blocking = true;
[1]518
[408]519    // set input arguments in RPC descriptor 
520    rpc.args[0] = (uint64_t)(intptr_t)info;
[1]521
522    // register RPC request in remote RPC fifo (blocking function)
[416]523    rpc_send( cxy , &rpc );
[1]524
[408]525    // get output arguments from RPC descriptor
526    *error  = (error_t)rpc.args[1];     
[279]527
[409]528rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
529__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
530CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]531}
532
533//////////////////////////////////////////////
[408]534void rpc_process_make_exec_server( xptr_t xp )
[1]535{
[409]536rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
537__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
538CURRENT_THREAD->core->lid , hal_time_stamp() );
539
[408]540    exec_info_t * ptr;       // local pointer on remote exec_info structure
541    exec_info_t   info;      // local copy of exec_info structure
542    error_t       error;     // local error error status
[1]543
544    // get client cluster identifier and pointer on RPC descriptor
545    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
546    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
547
[408]548    // get pointer on exec_info structure in client cluster from RPC descriptor
549    ptr = (exec_info_t*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
[1]550
[408]551    // copy exec_info structure from client buffer to server buffer
552    hal_remote_memcpy( XPTR( client_cxy , ptr ),
553                       XPTR( local_cxy , &info ),
554                       sizeof(exec_info_t) );
[296]555
[408]556    // call local kernel function
557    error = process_make_exec( &info ); 
558
559    // set output argument into client RPC descriptor
560    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
561
[409]562rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
563__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
564CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]565}
566
567/////////////////////////////////////////////////////////////////////////////////////////
[409]568// [3]           Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking)
[1]569/////////////////////////////////////////////////////////////////////////////////////////
570
[408]571///////////////////////////////////////////////////
572void rpc_process_make_fork_client( cxy_t       cxy,
573                                   xptr_t      ref_process_xp,      // in
574                                   xptr_t      parent_thread_xp,    // in
575                                   pid_t     * child_pid,           // out
576                                   thread_t ** child_thread_ptr,    // out     
577                                   error_t   * error )              // out
[1]578{
[409]579rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
580__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
581CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]582
[238]583    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]584
585    // initialise RPC descriptor header
586    rpc_desc_t  rpc;
[408]587    rpc.index    = RPC_PROCESS_MAKE_FORK;
[1]588    rpc.response = 1;
[416]589    rpc.blocking = true;
[1]590
591    // set input arguments in RPC descriptor 
[408]592    rpc.args[0] = (uint64_t)(intptr_t)ref_process_xp;
593    rpc.args[1] = (uint64_t)(intptr_t)parent_thread_xp;
[1]594
595    // register RPC request in remote RPC fifo (blocking function)
[416]596    rpc_send( cxy , &rpc );
[1]597
598    // get output arguments from RPC descriptor
[408]599    *child_pid         = (pid_t)rpc.args[2];
600    *child_thread_ptr  = (thread_t *)(intptr_t)rpc.args[3];
601    *error             = (error_t)rpc.args[4];     
[279]602
[409]603rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
604__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
605CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]606}
607
[408]608//////////////////////////////////////////////
609void rpc_process_make_fork_server( xptr_t xp )
[1]610{
[409]611rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
612__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
613CURRENT_THREAD->core->lid , hal_time_stamp() );
614
[408]615    xptr_t     ref_process_xp;     // extended pointer on reference parent process
616    xptr_t     parent_thread_xp;   // extended pointer on parent thread
617    pid_t      child_pid;          // child process identifier
618    thread_t * child_thread_ptr;   // local copy of exec_info structure
619    error_t    error;              // local error status
[1]620
621    // get client cluster identifier and pointer on RPC descriptor
622    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
623    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
624
[408]625    // get input arguments from cient RPC descriptor
626    ref_process_xp   = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
627    parent_thread_xp = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
[1]628
629    // call local kernel function
[408]630    error = process_make_fork( ref_process_xp,
631                               parent_thread_xp,
632                               &child_pid,
633                               &child_thread_ptr ); 
[1]634
635    // set output argument into client RPC descriptor
[408]636    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid );
637    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr );
638    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
[296]639
[409]640rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
641__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
642CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]643}
644
645/////////////////////////////////////////////////////////////////////////////////////////
[409]646// [4]      Marshaling functions attached to RPC_PROCESS_MAKE_EXIT (blocking)
[1]647/////////////////////////////////////////////////////////////////////////////////////////
648
649///////////////////////////////////////////////////
[409]650void rpc_process_make_exit_client( cxy_t       cxy,
[416]651                                   pid_t       pid,
[409]652                                   uint32_t    status ) 
[1]653{
[409]654rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
655__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
656CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]657
[409]658    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]659
[409]660    // initialise RPC descriptor header
661    rpc_desc_t  rpc;
662    rpc.index    = RPC_PROCESS_MAKE_EXIT;
663    rpc.response = 1;
[416]664    rpc.blocking = true;
[1]665
[409]666    // set input arguments in RPC descriptor 
[416]667    rpc.args[0] = (uint64_t)pid;
[409]668    rpc.args[1] = (uint64_t)status;
[1]669
[409]670    // register RPC request in remote RPC fifo (blocking function)
[416]671    rpc_send( cxy , &rpc );
[1]672
[409]673rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
674__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
675CURRENT_THREAD->core->lid , hal_time_stamp() );
676} 
677
678//////////////////////////////////////////////
679void rpc_process_make_exit_server( xptr_t xp )
680{
681rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
682__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
683CURRENT_THREAD->core->lid , hal_time_stamp() );
684
[416]685    pid_t     pid;
686    uint32_t  status; 
[409]687
688    // get client cluster identifier and pointer on RPC descriptor
689    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
690    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
691
692    // get arguments from RPC descriptor
[416]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] ) );
[409]695
696    // call local kernel function
[416]697    process_make_exit( pid , status ); 
[409]698
699rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
700__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
701CURRENT_THREAD->core->lid , hal_time_stamp() );
702} 
703
704/////////////////////////////////////////////////////////////////////////////////////////
705// [5]      Marshaling functions attached to RPC_PROCESS_MAKE_KILL (blocking)
706/////////////////////////////////////////////////////////////////////////////////////////
707
708///////////////////////////////////////////////////
709void rpc_process_make_kill_client( cxy_t       cxy,
[416]710                                   pid_t       pid,
[409]711                                   uint32_t    sig_id ) 
712{
713rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
714__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
715CURRENT_THREAD->core->lid , hal_time_stamp() );
716
717    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
718
719    // initialise RPC descriptor header
[1]720    rpc_desc_t  rpc;
[409]721    rpc.index    = RPC_PROCESS_MAKE_KILL;
722    rpc.response = 1;
[416]723    rpc.blocking = true;
[1]724
[409]725    // set input arguments in RPC descriptor 
[416]726    rpc.args[0] = (uint64_t)pid;
[409]727    rpc.args[1] = (uint64_t)sig_id;
[1]728
[409]729    // register RPC request in remote RPC fifo (blocking function)
[416]730    rpc_send( cxy , &rpc );
[279]731
[409]732rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
733__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
734CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]735} 
736
[409]737//////////////////////////////////////////////
738void rpc_process_make_kill_server( xptr_t xp )
[1]739{
[409]740rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
741__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
742CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]743
[416]744    pid_t       pid;
[409]745    uint32_t    sig_id;
[296]746
[1]747    // get client cluster identifier and pointer on RPC descriptor
748    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
749    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
750
[409]751    // get arguments from RPC descriptor
[416]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] ) );
[1]754
[409]755    // call local kernel function
[416]756    process_make_exit( pid , sig_id ); 
[1]757
[409]758rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
759__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
760CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]761} 
762
763/////////////////////////////////////////////////////////////////////////////////////////
[409]764// [6]           Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking)               
[1]765/////////////////////////////////////////////////////////////////////////////////////////
766
767/////////////////////////////////////////////////////////
768void rpc_thread_user_create_client( cxy_t            cxy, 
[23]769                                    pid_t            pid,         // in
770                                    void           * start_func,  // in
771                                    void           * start_arg,   // in
[1]772                                    pthread_attr_t * attr,        // in
773                                    xptr_t         * thread_xp,   // out
774                                    error_t        * error )      // out
775{
[409]776rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
777__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
778CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]779
[238]780    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]781
782    // initialise RPC descriptor header
783    rpc_desc_t  rpc;
[407]784    rpc.index     = RPC_THREAD_USER_CREATE;
785    rpc.response  = 1;
[416]786    rpc.blocking = true;
[1]787
788    // set input arguments in RPC descriptor
[23]789    rpc.args[0] = (uint64_t)pid;
790    rpc.args[1] = (uint64_t)(intptr_t)start_func;
791    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
792    rpc.args[3] = (uint64_t)(intptr_t)attr;
[1]793
[409]794    // register RPC request in remote RPC fifo (blocking function)
[416]795    rpc_send( cxy , &rpc );
[1]796
797    // get output arguments from RPC descriptor
[23]798    *thread_xp = (xptr_t)rpc.args[4];
799    *error     = (error_t)rpc.args[5];
[279]800
[409]801rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
802__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
803CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]804}
805
806///////////////////////////////////////////////
807void rpc_thread_user_create_server( xptr_t xp )
808{
[409]809rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
810__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
811CURRENT_THREAD->core->lid , hal_time_stamp() );
812
[1]813    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
814    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
815    thread_t       * thread_ptr; // local pointer on thread descriptor
816    xptr_t           thread_xp;  // extended pointer on thread descriptor
[23]817
[1]818    pid_t            pid;        // process identifier
[23]819    void           * start_func;
820    void           * start_arg;
821    error_t          error;
[1]822
823    // get client cluster identifier and pointer on RPC descriptor
824    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
825    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
826
827    // get pointer on attributes structure in client cluster from RPC descriptor
828
[23]829    // get input arguments from RPC descriptor
830    pid        = (pid_t)                     hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
831    start_func = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
832    start_arg  = (void *)(intptr_t)          hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
833    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[3]));
834
[1]835    // makes a local copy of attributes structure
836    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
837                       XPTR( client_cxy , attr_ptr ), 
838                       sizeof(pthread_attr_t) );
839   
[23]840    // call kernel function
841    error = thread_user_create( pid,
842                                start_func,
843                                start_arg,
844                                &attr_copy,
845                                &thread_ptr );
[1]846
847    // set output arguments
848    thread_xp = XPTR( local_cxy , thread_ptr );
[407]849    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
850    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
[296]851
[409]852rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
853__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
854CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]855}
856
857/////////////////////////////////////////////////////////////////////////////////////////
[409]858// [7]           Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
[1]859/////////////////////////////////////////////////////////////////////////////////////////
860
861////////////////////////////////////////////////////
862void rpc_thread_kernel_create_client( cxy_t     cxy,
863                                      uint32_t  type,        // in
864                                      void    * func,        // in
865                                      void    * args,        // in
866                                      xptr_t  * thread_xp,   // out
867                                      error_t * error )      // out
868{
[409]869rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
870__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
871CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]872
[238]873    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]874
875    // initialise RPC descriptor header
876    rpc_desc_t  rpc;
877    rpc.index    = RPC_THREAD_KERNEL_CREATE;
878    rpc.response = 1;
[416]879    rpc.blocking = true;
[1]880
881    // set input arguments in RPC descriptor
882    rpc.args[0] = (uint64_t)type;
883    rpc.args[1] = (uint64_t)(intptr_t)func;
884    rpc.args[2] = (uint64_t)(intptr_t)args;
885   
[409]886    // register RPC request in remote RPC fifo (blocking function)
[416]887    rpc_send( cxy , &rpc );
[1]888
889    // get output arguments from RPC descriptor
890    *thread_xp = (xptr_t)rpc.args[3];
891    *error     = (error_t)rpc.args[4];
[279]892
[409]893rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
894__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
895CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]896}
897
898/////////////////////////////////////////////////
899void rpc_thread_kernel_create_server( xptr_t xp )
900{
[409]901rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
902__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
903CURRENT_THREAD->core->lid , hal_time_stamp() );
904
[1]905    thread_t       * thread_ptr;  // local pointer on thread descriptor
906    xptr_t           thread_xp;   // extended pointer on thread descriptor
907    lid_t            core_lid;    // core local index
908    error_t          error;   
909
910    // get client cluster identifier and pointer on RPC descriptor
911    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
912    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
913
914    // get attributes from RPC descriptor
915    uint32_t  type = (uint32_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
916    void    * func = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
917    void    * args = (void*)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
918
919    // select one core
920    core_lid = cluster_select_local_core();
921
922    // call local kernel function
923    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
924
925    // set output arguments
926    thread_xp = XPTR( local_cxy , thread_ptr );
927    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
928    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
[296]929
[409]930rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
931__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
932CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]933}
934
935/////////////////////////////////////////////////////////////////////////////////////////
[409]936// [8]           Marshaling functions attached to RPC_THREAD_KILL (blocking)
[1]937/////////////////////////////////////////////////////////////////////////////////////////
938
[23]939/////////////////////////////////////////////
[409]940void rpc_thread_kill_client( cxy_t       cxy,
941                             thread_t  * thread )    // in
[23]942{
[409]943rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
944__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
945CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]946
[409]947    // this RPC can be called in local cluster
[23]948
949    // initialise RPC descriptor header
950    rpc_desc_t  rpc;
[409]951    rpc.index    = RPC_THREAD_KILL;
[23]952    rpc.response = 1;
[416]953    rpc.blocking = true;
[23]954
955    // set input arguments in RPC descriptor
[409]956    rpc.args[0] = (uint64_t)(intptr_t)thread;
[23]957   
[409]958    // register RPC request in remote RPC fifo (blocking function)
[416]959    rpc_send( cxy , &rpc );
[279]960
[409]961rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
962__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
963CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]964}
965
966////////////////////////////////////////                             
[409]967void rpc_thread_kill_server( xptr_t xp )
[23]968{
[409]969rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
970__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
971CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]972
[409]973    thread_t  * thread;  // local pointer on process descriptor
[296]974
[23]975    // get client cluster identifier and pointer on RPC descriptor
976    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
977    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
978
979    // get attributes from RPC descriptor
[409]980    thread = (thread_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
[23]981
982    // call local kernel function
[409]983    thread_kill( thread );
[296]984
[409]985rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
986__FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
987CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]988}
989
[409]990
[23]991/////////////////////////////////////////////////////////////////////////////////////////
[415]992// [9] Marshaling functions attached to RPC_PROCESS_SIGACTION (multicast / non blocking)
[23]993/////////////////////////////////////////////////////////////////////////////////////////
994
[416]995////////////////////////////////////////////////////
996void rpc_process_sigaction_client( cxy_t        cxy,
997                                   rpc_desc_t * rpc_ptr )
[409]998{
[416]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() );
[409]1002
[416]1003    // register RPC request in remote RPC fifo
1004    rpc_send( cxy , rpc_ptr );
[409]1005
[416]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() );
[409]1009} 
1010
1011//////////////////////////////////////////////
1012void rpc_process_sigaction_server( xptr_t xp )
1013{
[416]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
[409]1021
1022    // get client cluster identifier and pointer on RPC descriptor
[416]1023    client_cxy = (cxy_t)GET_CXY( xp );
1024    rpc        = (rpc_desc_t *)GET_PTR( xp );
[409]1025
1026    // get arguments from RPC descriptor
[416]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 ) );
[409]1030
[416]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() );
1036
[409]1037    // call relevant kernel function
[428]1038    if      (action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
1039    else if (action == BLOCK_ALL_THREADS   ) process_block_threads  ( process , client_xp ); 
1040    else if (action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process             );
[409]1041
[416]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() );
[409]1053} 
1054
1055/////////////////////////////////////////////////////////////////////////////////////////
1056// [10]          Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
1057/////////////////////////////////////////////////////////////////////////////////////////
1058
[1]1059/////////////////////////////////////////////////////
1060void rpc_vfs_inode_create_client( cxy_t          cxy,     
1061                                  xptr_t         dentry_xp,  // in
[23]1062                                  uint32_t       fs_type,    // in
1063                                  uint32_t       inode_type, // in
[188]1064                                  void         * extend,     // in
[1]1065                                  uint32_t       attr,       // in
[23]1066                                  uint32_t       rights,     // in
[1]1067                                  uint32_t       uid,        // in
1068                                  uint32_t       gid,        // in
1069                                  xptr_t       * inode_xp,   // out
1070                                  error_t      * error )     // out
1071{
[407]1072    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1073    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1074    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1075
[238]1076    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1077
1078    // initialise RPC descriptor header
1079    rpc_desc_t  rpc;
1080    rpc.index    = RPC_VFS_INODE_CREATE;
1081    rpc.response = 1;
[416]1082    rpc.blocking = true;
[1]1083
1084    // set input arguments in RPC descriptor
1085    rpc.args[0] = (uint64_t)dentry_xp;
[23]1086    rpc.args[1] = (uint64_t)fs_type;
1087    rpc.args[2] = (uint64_t)inode_type;
[188]1088    rpc.args[3] = (uint64_t)(intptr_t)extend;
1089    rpc.args[4] = (uint64_t)attr;
1090    rpc.args[5] = (uint64_t)rights;
1091    rpc.args[6] = (uint64_t)uid;
1092    rpc.args[7] = (uint64_t)gid;
[1]1093
1094    // register RPC request in remote RPC fifo (blocking function)
[416]1095    rpc_send( cxy , &rpc );
[1]1096
1097    // get output values from RPC descriptor
[188]1098    *inode_xp = (xptr_t)rpc.args[8];
1099    *error    = (error_t)rpc.args[9];
[279]1100
[407]1101    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1102    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1103    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1104}
1105
1106/////////////////////////////////////////////
1107void rpc_vfs_inode_create_server( xptr_t xp )
1108{
1109    xptr_t           dentry_xp;
[23]1110    uint32_t         fs_type;
1111    uint32_t         inode_type;
[188]1112    void           * extend;
[1]1113    uint32_t         attr;
[23]1114    uint32_t         rights;
[1]1115    uint32_t         uid;
1116    uint32_t         gid;
1117    xptr_t           inode_xp;
1118    error_t          error;
1119
[407]1120    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1121    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1122    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1123
[1]1124    // get client cluster identifier and pointer on RPC descriptor
1125    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1126    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1127
1128    // get input arguments from client rpc descriptor
[188]1129    dentry_xp  = (xptr_t)          hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1130    fs_type    = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1131    inode_type = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
1132    extend     = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
1133    attr       = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
1134    rights     = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
1135    uid        = (uid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[6] ) );
1136    gid        = (gid_t)           hal_remote_lwd( XPTR( client_cxy , &desc->args[7] ) );
[1]1137
1138    // call local kernel function
1139    error = vfs_inode_create( dentry_xp,
[23]1140                              fs_type,
1141                              inode_type,
[188]1142                              extend,
[1]1143                              attr,
[23]1144                              rights,
[1]1145                              uid,
1146                              gid,
1147                              &inode_xp );
1148
1149    // set output arguments
[188]1150    hal_remote_swd( XPTR( client_cxy , &desc->args[8] ) , (uint64_t)inode_xp );
1151    hal_remote_swd( XPTR( client_cxy , &desc->args[9] ) , (uint64_t)error );
[296]1152
[407]1153    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1154    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1155    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1156}
1157
1158/////////////////////////////////////////////////////////////////////////////////////////
[409]1159// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
[1]1160/////////////////////////////////////////////////////////////////////////////////////////
1161
1162/////////////////////////////////////////////////////////////
1163void rpc_vfs_inode_destroy_client( cxy_t                cxy,
1164                                   struct vfs_inode_s * inode )
1165{
[407]1166    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1167    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1168    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1169
[238]1170    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1171
1172    // initialise RPC descriptor header
1173    rpc_desc_t  rpc;
1174    rpc.index    = RPC_VFS_INODE_DESTROY;
1175    rpc.response = 1;
[416]1176    rpc.blocking = true;
[1]1177
1178    // set input arguments in RPC descriptor
1179    rpc.args[0] = (uint64_t)(intptr_t)inode;
1180   
1181    // register RPC request in remote RPC fifo (blocking function)
[416]1182    rpc_send( cxy , &rpc );
[279]1183
[407]1184    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1185    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1186    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1187}
1188
1189//////////////////////////////////////////////
1190void rpc_vfs_inode_destroy_server( xptr_t xp )
1191{
1192    vfs_inode_t * inode;
1193
[407]1194    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1195    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1196    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1197
[1]1198    // get client cluster identifier and pointer on RPC descriptor
1199    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1200    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1201
1202    // get arguments "inode" from client RPC descriptor
1203    inode = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1204                       
1205    // call local kernel function
1206    vfs_inode_destroy( inode );
[296]1207
[407]1208    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1209    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1210    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1211}
1212
1213/////////////////////////////////////////////////////////////////////////////////////////
[409]1214// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
[1]1215/////////////////////////////////////////////////////////////////////////////////////////
1216
1217//////////////////////////////////////////////////////////////
1218void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1219                                   uint32_t               type,         // in
1220                                   char                 * name,         // in
1221                                   struct vfs_inode_s   * parent,       // in
1222                                   xptr_t               * dentry_xp,    // out
1223                                   error_t              * error )       // out
1224{
[407]1225    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1226    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1227    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1228
[238]1229    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1230
1231    // initialise RPC descriptor header
1232    rpc_desc_t  rpc;
1233    rpc.index    = RPC_VFS_DENTRY_CREATE;
1234    rpc.response = 1;
[416]1235    rpc.blocking = true;
[1]1236
1237    // set input arguments in RPC descriptor
1238    rpc.args[0] = (uint64_t)type;
1239    rpc.args[1] = (uint64_t)(intptr_t)name;
[238]1240    rpc.args[2] = (uint64_t)(intptr_t)parent;
[1]1241
1242    // register RPC request in remote RPC fifo (blocking function)
[416]1243    rpc_send( cxy , &rpc );
[1]1244
1245    // get output values from RPC descriptor
[238]1246    *dentry_xp = (xptr_t)rpc.args[3];
1247    *error     = (error_t)rpc.args[4];
[279]1248
[407]1249    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1250    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1251    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1252}
1253
1254//////////////////////////////////////////////
1255void rpc_vfs_dentry_create_server( xptr_t xp )
1256{
1257    uint32_t      type;
1258    char        * name;
1259    vfs_inode_t * parent;
1260    xptr_t        dentry_xp;
1261    error_t       error;
1262
[238]1263    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1264
[407]1265    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1266    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1267    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1268
[1]1269    // get client cluster identifier and pointer on RPC descriptor
1270    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1271    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1272
[238]1273    // get arguments "name", "type", and "parent" from client RPC descriptor
[1]1274    type   = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
[238]1275    name   = (char *)(intptr_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1276    parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
[296]1277
[238]1278    // makes a local copy of  name
1279    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1280                       XPTR( client_cxy , name ) );
1281
[1]1282    // call local kernel function
1283    error = vfs_dentry_create( type,
1284                               name_copy,
1285                               parent,
1286                               &dentry_xp );
1287    // set output arguments
[238]1288    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp );
1289    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
[296]1290
[407]1291    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1292    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1293    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1294}
1295
1296/////////////////////////////////////////////////////////////////////////////////////////
[409]1297// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
[1]1298/////////////////////////////////////////////////////////////////////////////////////////
1299
[296]1300
[1]1301///////////////////////////////////////////////////////
1302void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
1303                                    vfs_dentry_t * dentry )
1304{
[407]1305    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1306    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1307    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1308
[238]1309    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1310
1311    // initialise RPC descriptor header
1312    rpc_desc_t  rpc;
1313    rpc.index    = RPC_VFS_DENTRY_DESTROY;
1314    rpc.response = 1;
[416]1315    rpc.blocking = true;
[1]1316
1317    // set input arguments in RPC descriptor
1318    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1319   
1320    // register RPC request in remote RPC fifo (blocking function)
[416]1321    rpc_send( cxy , &rpc );
[279]1322
[407]1323    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1324    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1325    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1326}
1327
1328///////////////////////////////////////////////
1329void rpc_vfs_dentry_destroy_server( xptr_t xp )
1330{
1331    vfs_dentry_t * dentry;
1332
[407]1333    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1334    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1335    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1336
[1]1337    // get client cluster identifier and pointer on RPC descriptor
1338    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1339    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1340
1341    // get arguments "dentry" from client RPC descriptor
1342    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1343                       
1344    // call local kernel function
1345    vfs_dentry_destroy( dentry );
[296]1346
[407]1347    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1348    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1349    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1350}
1351
1352
1353/////////////////////////////////////////////////////////////////////////////////////////
[409]1354// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
[1]1355/////////////////////////////////////////////////////////////////////////////////////////
1356
[23]1357//////////////////////////////////////////////////////////////
1358void rpc_vfs_file_create_client( cxy_t                  cxy,
1359                                 struct vfs_inode_s   * inode,       // in
1360                                 uint32_t               file_attr,   // in
1361                                 xptr_t               * file_xp,     // out
1362                                 error_t              * error )      // out
1363{
[407]1364    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1365    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1366    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1367
[238]1368    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1369
1370    // initialise RPC descriptor header
1371    rpc_desc_t  rpc;
1372    rpc.index    = RPC_VFS_FILE_CREATE;
1373    rpc.response = 1;
[416]1374    rpc.blocking = true;
[23]1375
1376    // set input arguments in RPC descriptor
1377    rpc.args[0] = (uint64_t)(intptr_t)inode;
1378    rpc.args[1] = (uint64_t)file_attr;
1379
1380    // register RPC request in remote RPC fifo (blocking function)
[416]1381    rpc_send( cxy , &rpc );
[23]1382
1383    // get output values from RPC descriptor
1384    *file_xp = (xptr_t)rpc.args[2];
1385    *error   = (error_t)rpc.args[3];
[279]1386
[407]1387    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1388    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1389    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1390}
1391
1392////////////////////////////////////////////
1393void rpc_vfs_file_create_server( xptr_t xp )
1394{
1395    uint32_t      file_attr;
1396    vfs_inode_t * inode;
1397    xptr_t        file_xp;
1398    error_t       error;
1399
[407]1400    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1401    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1402    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1403
[23]1404    // get client cluster identifier and pointer on RPC descriptor
1405    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1406    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1407
1408    // get arguments "file_attr" and "inode" from client RPC descriptor
1409    inode     = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1410    file_attr = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1411                       
1412    // call local kernel function
1413    error = vfs_file_create( inode,
1414                             file_attr,
1415                             &file_xp );
1416 
1417    // set output arguments
1418    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
1419    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1420
[407]1421    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1422    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1423    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1424}
1425
1426/////////////////////////////////////////////////////////////////////////////////////////
[409]1427// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
[23]1428/////////////////////////////////////////////////////////////////////////////////////////
1429
1430///////////////////////////////////////////////////
1431void rpc_vfs_file_destroy_client( cxy_t        cxy,
1432                                  vfs_file_t * file )
1433{
[407]1434    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1435    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1436    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1437
[238]1438    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1439
1440    // initialise RPC descriptor header
1441    rpc_desc_t  rpc;
1442    rpc.index    = RPC_VFS_FILE_DESTROY;
1443    rpc.response = 1;
[416]1444    rpc.blocking = true;
[23]1445
1446    // set input arguments in RPC descriptor
1447    rpc.args[0] = (uint64_t)(intptr_t)file;
1448   
1449    // register RPC request in remote RPC fifo (blocking function)
[416]1450    rpc_send( cxy , &rpc );
[279]1451
[407]1452    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1453    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1454    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1455}
1456
1457/////////////////////////////////////////////
1458void rpc_vfs_file_destroy_server( xptr_t xp )
1459{
1460    vfs_file_t * file;
1461
[407]1462    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1463    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1464    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1465
[23]1466    // get client cluster identifier and pointer on RPC descriptor
1467    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1468    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1469
1470    // get arguments "dentry" from client RPC descriptor
1471    file = (vfs_file_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1472                       
1473    // call local kernel function
1474    vfs_file_destroy( file );
[296]1475
[407]1476    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1477    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1478    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1479}
1480
1481/////////////////////////////////////////////////////////////////////////////////////////
[409]1482// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD   (blocking)
[23]1483/////////////////////////////////////////////////////////////////////////////////////////
1484
[1]1485//////////////////////////////////////////////////
[238]1486void rpc_vfs_inode_load_client( cxy_t         cxy,
1487                                vfs_inode_t * parent_inode,    // in
1488                                char        * name,            // in
1489                                xptr_t        child_inode_xp,  // in
1490                                error_t     * error )          // out
1491{
[407]1492    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1493    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1494    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1495
[238]1496    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1497
1498    // initialise RPC descriptor header
1499    rpc_desc_t  rpc;
1500    rpc.index    = RPC_VFS_INODE_LOAD;
1501    rpc.response = 1;
[416]1502    rpc.blocking = true;
[238]1503
1504    // set input arguments in RPC descriptor
1505    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
1506    rpc.args[1] = (uint64_t)(intptr_t)name;
1507    rpc.args[2] = (uint64_t)child_inode_xp;
1508
1509    // register RPC request in remote RPC fifo (blocking function)
[416]1510    rpc_send( cxy , &rpc );
[238]1511
1512    // get output values from RPC descriptor
1513    *error   = (error_t)rpc.args[3];
[279]1514
[407]1515    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1516    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1517    CURRENT_THREAD->core->lid , hal_time_stamp() );
[238]1518}
1519
1520///////////////////////////////////////////
1521void rpc_vfs_inode_load_server( xptr_t xp )
1522{
1523    error_t       error;
1524    vfs_inode_t * parent;
1525    xptr_t        child_xp;
1526    char        * name;
1527
1528    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1529
[407]1530    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1531    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1532    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1533
[238]1534    // get client cluster identifier and pointer on RPC descriptor
1535    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1536    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1537
1538    // get arguments "parent", "name", and "child_xp"
1539    parent     = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
1540    name       = (char*)(intptr_t)       hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
1541    child_xp   = (xptr_t)                hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
1542
1543    // get name local copy
1544    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
1545                       XPTR( client_cxy , name ) );
1546
1547    // call the kernel function
1548    error = vfs_inode_load( parent , name_copy , child_xp );
1549
1550    // set output argument
1551    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1552
[407]1553    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1554    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1555    CURRENT_THREAD->core->lid , hal_time_stamp() );
[238]1556}
1557
1558/////////////////////////////////////////////////////////////////////////////////////////
[409]1559// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL  (blocking)
[238]1560/////////////////////////////////////////////////////////////////////////////////////////
1561
1562///////////////////////////////////////////////////////
1563void rpc_vfs_mapper_load_all_client( cxy_t         cxy,
1564                                     vfs_inode_t * inode,      // in
1565                                     error_t     * error )     // out
1566{
[407]1567    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1568    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1569    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1570
[238]1571    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
1572
1573    // initialise RPC descriptor header
1574    rpc_desc_t  rpc;
[389]1575    rpc.index    = RPC_VFS_MAPPER_LOAD_ALL;
[238]1576    rpc.response = 1;
[416]1577    rpc.blocking = true;
[238]1578
1579    // set input arguments in RPC descriptor
1580    rpc.args[0] = (uint64_t)(intptr_t)inode;
1581
1582    // register RPC request in remote RPC fifo (blocking function)
[416]1583    rpc_send( cxy , &rpc );
[238]1584
1585    // get output values from RPC descriptor
1586    *error   = (error_t)rpc.args[1];
[279]1587
[407]1588    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1589    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1590    CURRENT_THREAD->core->lid , hal_time_stamp() );
[238]1591}
1592
1593////////////////////////////////////////////////
1594void rpc_vfs_mapper_load_all_server( xptr_t xp )
1595{
1596    error_t       error;
1597    vfs_inode_t * inode;
1598
[407]1599    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1600    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1601    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1602
[238]1603    // get client cluster identifier and pointer on RPC descriptor
1604    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1605    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1606
1607    // get arguments "parent", "name", and "child_xp"
1608    inode = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
1609
1610    // call the kernel function
1611    error = vfs_mapper_load_all( inode );
1612
1613    // set output argument
[389]1614    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
[296]1615
[407]1616    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1617    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1618    CURRENT_THREAD->core->lid , hal_time_stamp() );
[238]1619}
1620
1621/////////////////////////////////////////////////////////////////////////////////////////
[409]1622// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER  (blocking)
[238]1623/////////////////////////////////////////////////////////////////////////////////////////
1624
1625//////////////////////////////////////////////////
[23]1626void rpc_fatfs_get_cluster_client( cxy_t      cxy,
1627                                   mapper_t * mapper,    // in
1628                                   uint32_t   first,     // in
[407]1629                                   uint32_t   index,     // in
[23]1630                                   uint32_t * cluster,   // out
1631                                   error_t  * error )    // out
1632{
[407]1633    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1634    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1635    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1636
[238]1637    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[23]1638
1639    // initialise RPC descriptor header
1640    rpc_desc_t  rpc;
1641    rpc.index    = RPC_FATFS_GET_CLUSTER;
1642    rpc.response = 1;
[416]1643    rpc.blocking = true;
[23]1644
1645    // set input arguments in RPC descriptor
1646    rpc.args[0] = (uint64_t)(intptr_t)mapper;
1647    rpc.args[1] = (uint64_t)first;
[407]1648    rpc.args[2] = (uint64_t)index;
[23]1649
1650    // register RPC request in remote RPC fifo
[416]1651    rpc_send( cxy , &rpc );
[23]1652
1653    // get output argument from rpc descriptor
1654    *cluster = (uint32_t)rpc.args[3];
1655    *error   = (error_t)rpc.args[4];
[279]1656
[407]1657    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1658    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1659    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1660}
1661
1662//////////////////////////////////////////////
1663void rpc_fatfs_get_cluster_server( xptr_t xp )
1664{
1665    mapper_t    * mapper;
1666    uint32_t      first;
[407]1667    uint32_t      index;
[23]1668    uint32_t      cluster;
1669    error_t       error;
1670
[407]1671    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1672    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1673    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1674
[23]1675    // get client cluster identifier and pointer on RPC descriptor
1676    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1677    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
1678
1679    // get input arguments
1680    mapper = (mapper_t *)(intptr_t)hal_remote_lpt( XPTR( client_cxy , &desc->args[0] ) );
1681    first  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[1] ) );
[407]1682    index  = (uint32_t)            hal_remote_lw ( XPTR( client_cxy , &desc->args[2] ) );
[23]1683
1684    // call the kernel function
[407]1685    error = fatfs_get_cluster( mapper , first , index , &cluster );
[23]1686
1687    // set output argument
1688    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)cluster );
1689    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
[296]1690
[407]1691    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1692    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1693    CURRENT_THREAD->core->lid , hal_time_stamp() );
[23]1694}
1695
1696/////////////////////////////////////////////////////////////////////////////////////////
[409]1697// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
[23]1698/////////////////////////////////////////////////////////////////////////////////////////
1699
1700//////////////////////////////////////////////////
[389]1701void rpc_vmm_get_vseg_client( cxy_t       cxy,     
1702                              process_t * process,     // in 
1703                              intptr_t    vaddr,       // in 
1704                              xptr_t    * vseg_xp,     // out
1705                              error_t   * error )      // out
[1]1706{
[407]1707    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1708    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1709    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1710
[238]1711    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1712
1713    // initialise RPC descriptor header
1714    rpc_desc_t  rpc;
[389]1715    rpc.index    = RPC_VMM_GET_VSEG;
[1]1716    rpc.response = 1;
[416]1717    rpc.blocking = true;
[1]1718
1719    // set input arguments in RPC descriptor
1720    rpc.args[0] = (uint64_t)(intptr_t)process;
1721    rpc.args[1] = (uint64_t)vaddr;
1722
1723    // register RPC request in remote RPC fifo (blocking function)
[416]1724    rpc_send( cxy , &rpc );
[1]1725
1726    // get output argument from rpc descriptor
1727    *vseg_xp = rpc.args[2];
[389]1728    *error   = (error_t)rpc.args[3];
[279]1729
[407]1730    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1731    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1732    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1733}
1734
[389]1735/////////////////////////////////////////
1736void rpc_vmm_get_vseg_server( xptr_t xp )
[1]1737{
1738    process_t   * process;
1739    intptr_t      vaddr;
1740    vseg_t      * vseg_ptr;
1741    xptr_t        vseg_xp;
[389]1742    error_t       error;
[1]1743
[407]1744    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1745    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1746    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1747
[1]1748    // get client cluster identifier and pointer on RPC descriptor
1749    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1750    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1751
1752    // get input argument from client RPC descriptor
1753    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1754    vaddr   = (intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
1755   
1756    // call local kernel function
[389]1757    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
[1]1758
[389]1759    // set output arguments to client RPC descriptor
1760    vseg_xp = XPTR( local_cxy , vseg_ptr );
[1]1761    hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
[389]1762    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1763
[407]1764    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1765    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1766    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1767}
1768
1769
1770/////////////////////////////////////////////////////////////////////////////////////////
[409]1771// [21]          Marshaling functions attached to RPC_VMM_GET_PTE  (blocking)
[1]1772/////////////////////////////////////////////////////////////////////////////////////////
1773
1774////////////////////////////////////////////
1775void rpc_vmm_get_pte_client( cxy_t       cxy,   
1776                             process_t * process,  // in
1777                             vpn_t       vpn,      // in
[407]1778                             bool_t      cow,      // in
[1]1779                             uint32_t  * attr,     // out
1780                             ppn_t     * ppn,      // out
1781                             error_t   * error )   // out
1782{
[407]1783    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1784    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1785    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1786
[238]1787    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1788
1789    // initialise RPC descriptor header
1790    rpc_desc_t  rpc;
1791    rpc.index    = RPC_VMM_GET_PTE;
1792    rpc.response = 1;
[416]1793    rpc.blocking = true;
[1]1794
1795    // set input arguments in RPC descriptor
1796    rpc.args[0] = (uint64_t)(intptr_t)process;
1797    rpc.args[1] = (uint64_t)vpn;
[407]1798    rpc.args[2] = (uint64_t)cow;
[1]1799
1800    // register RPC request in remote RPC fifo (blocking function)
[416]1801    rpc_send( cxy , &rpc );
[1]1802
1803    // get output argument from rpc descriptor
[407]1804    *attr  = (uint32_t)rpc.args[3];
1805    *ppn   = (ppn_t)rpc.args[4];
1806    *error = (error_t)rpc.args[5];
[279]1807
[407]1808    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1809    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1810    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1811}
1812
1813////////////////////////////////////////
1814void rpc_vmm_get_pte_server( xptr_t xp )
1815{
1816    process_t   * process;
1817    vpn_t         vpn;
[407]1818    bool_t        cow;
[1]1819    uint32_t      attr;
1820    ppn_t         ppn;
1821    error_t       error;
1822
[407]1823    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1824    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1825    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1826
[1]1827    // get client cluster identifier and pointer on RPC descriptor
1828    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1829    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
1830
1831    // get input argument "process" & "vpn" from client RPC descriptor
1832    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1833    vpn     = (vpn_t)                hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
[407]1834    cow     = (bool_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
[1]1835   
1836    // call local kernel function
[407]1837    error = vmm_get_pte( process , vpn , cow , &attr , &ppn ); 
[1]1838
1839    // set output argument "attr" & "ppn" to client RPC descriptor
[407]1840    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)attr );
1841    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)ppn );
1842    hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
[296]1843
[407]1844    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1845    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1846    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1847}
1848
1849/////////////////////////////////////////////////////////////////////////////////////////
[409]1850// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
[1]1851/////////////////////////////////////////////////////////////////////////////////////////
1852
[23]1853//////////////////////////////////////////
1854void rpc_kcm_alloc_client( cxy_t      cxy,
1855                           uint32_t   kmem_type,   // in
1856                           xptr_t *   buf_xp )     // out
[1]1857{
[407]1858    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1859    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1860    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1861
[238]1862    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1863
1864    // initialise RPC descriptor header
1865    rpc_desc_t  rpc;
1866    rpc.index    = RPC_THREAD_USER_CREATE;
1867    rpc.response = 1;
[416]1868    rpc.blocking = true;
[1]1869
[23]1870    // set input arguments in RPC descriptor
1871    rpc.args[0] = (uint64_t)kmem_type;
1872
[409]1873    // register RPC request in remote RPC fifo (blocking function)
[416]1874    rpc_send( cxy , &rpc );
[1]1875
1876    // get output arguments from RPC descriptor
[23]1877    *buf_xp = (xptr_t)rpc.args[1];
[279]1878
[407]1879    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1880    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1881    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1882}
1883
[23]1884//////////////////////////////////////
1885void rpc_kcm_alloc_server( xptr_t xp )
[1]1886{
[407]1887    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1888    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1889    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1890
[1]1891    // get client cluster identifier and pointer on RPC descriptor
1892    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1893    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
1894
[23]1895    // get input argument "kmem_type" from client RPC descriptor
1896    uint32_t kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1897
1898    // allocates memory for kcm
[1]1899    kmem_req_t  req;
[23]1900    req.type  = kmem_type;
[1]1901    req.flags = AF_ZERO;
[23]1902    void * buf_ptr = kmem_alloc( &req );
[1]1903
1904    // set output argument
[23]1905    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
1906    hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
[296]1907
[407]1908    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1909    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1910    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1911}   
1912
1913/////////////////////////////////////////////////////////////////////////////////////////
[409]1914// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
[1]1915/////////////////////////////////////////////////////////////////////////////////////////
1916
[23]1917/////////////////////////////////////////
1918void rpc_kcm_free_client( cxy_t      cxy,
1919                          void     * buf,          // in
1920                          uint32_t   kmem_type )   // in
[1]1921{
[407]1922    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1923    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1924    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1925
[238]1926    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1927
1928    // initialise RPC descriptor header
1929    rpc_desc_t  rpc;
1930    rpc.index    = RPC_THREAD_USER_CREATE;
1931    rpc.response = 1;
[416]1932    rpc.blocking = true;
[1]1933
1934    // set input arguments in RPC descriptor
[23]1935    rpc.args[0] = (uint64_t)(intptr_t)buf;
1936    rpc.args[1] = (uint64_t)kmem_type;
[1]1937
[409]1938    // register RPC request in remote RPC fifo (blocking function)
[416]1939    rpc_send( cxy , &rpc );
[279]1940
[407]1941    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1942    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1943    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1944}
1945
[23]1946/////////////////////////////////////
1947void rpc_kcm_free_server( xptr_t xp )
[1]1948{
[407]1949    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1950    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1951    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1952
[1]1953    // get client cluster identifier and pointer on RPC descriptor
1954    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
1955    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
1956
[23]1957    // get input arguments "buf" and "kmem_type" from client RPC descriptor
1958    void     * buf = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
1959    uint32_t   kmem_type = (uint32_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
[1]1960
1961    // releases memory
1962    kmem_req_t  req;
[23]1963    req.type = kmem_type;
1964    req.ptr  = buf;
1965    kmem_free( &req );
[296]1966
[407]1967    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]1968    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1969    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]1970}   
1971
1972/////////////////////////////////////////////////////////////////////////////////////////
[265]1973// [24]          Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER
[1]1974/////////////////////////////////////////////////////////////////////////////////////////
1975
[265]1976///////////////////////////////////////////////////
1977void rpc_mapper_move_buffer_client( cxy_t      cxy,
1978                                    mapper_t * mapper,        // in
1979                                    bool_t     to_buffer,     // in
1980                                    bool_t     is_user,       // in
1981                                    uint32_t   file_offset,   // in
[313]1982                                    uint64_t   buffer,        // in
[265]1983                                    uint32_t   size,          // in
1984                                    error_t  * error )        // out
[1]1985{
[407]1986    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]1987    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
1988    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]1989
[238]1990    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
[1]1991
1992    // initialise RPC descriptor header
1993    rpc_desc_t  rpc;
[265]1994    rpc.index    = RPC_MAPPER_MOVE_BUFFER;
[1]1995    rpc.response = 1;
[416]1996    rpc.blocking = true;
[1]1997
1998    // set input arguments in RPC descriptor
1999    rpc.args[0] = (uint64_t)(intptr_t)mapper;
[23]2000    rpc.args[1] = (uint64_t)to_buffer;
[265]2001    rpc.args[2] = (uint64_t)is_user;
2002    rpc.args[3] = (uint64_t)file_offset;
[313]2003    rpc.args[4] = (uint64_t)buffer;
[265]2004    rpc.args[5] = (uint64_t)size;
[1]2005
[23]2006    // register RPC request in remote RPC fifo (blocking function)
[416]2007    rpc_send( cxy , &rpc );
[1]2008
[23]2009    // get output values from RPC descriptor
[265]2010    *error     = (error_t)rpc.args[6];
[279]2011
[407]2012    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]2013    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2014    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]2015}
2016
[265]2017///////////////////////////////////////////////
2018void rpc_mapper_move_buffer_server( xptr_t xp )
[1]2019{
[23]2020    mapper_t * mapper;
[265]2021    bool_t     to_buffer;
2022    bool_t     is_user;
[23]2023    uint32_t   file_offset;
[313]2024    void     * user_buffer;
2025    xptr_t     kern_buffer;
[23]2026    uint32_t   size;
2027    error_t    error;
[1]2028
[407]2029    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]2030    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2031    CURRENT_THREAD->core->lid , hal_time_stamp() );
[296]2032
[1]2033    // get client cluster identifier and pointer on RPC descriptor
2034    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
[23]2035    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
[1]2036
[23]2037    // get arguments from client RPC descriptor
2038    mapper      = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
2039    to_buffer   =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
[265]2040    is_user     =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
2041    file_offset =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
2042    size        =                       hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) );
[1]2043
[23]2044    // call local kernel function
[313]2045    if( is_user )
2046    {
2047        user_buffer = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
[1]2048
[315]2049        error = mapper_move_user( mapper,
2050                                  to_buffer,
2051                                  file_offset,
2052                                  user_buffer,
2053                                  size );
[313]2054    }
2055    else
2056    {
2057        kern_buffer = (xptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) );
2058
[315]2059        error = mapper_move_kernel( mapper,
2060                                    to_buffer,
2061                                    file_offset,
2062                                    kern_buffer,
2063                                    size );
[313]2064    }
2065
[23]2066    // set output argument to client RPC descriptor
[265]2067    hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error );
[296]2068
[407]2069    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]2070    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2071    CURRENT_THREAD->core->lid , hal_time_stamp() );
[1]2072}
2073
[313]2074/////////////////////////////////////////////////////////////////////////////////////////
[409]2075// [25]          Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking)
[313]2076/////////////////////////////////////////////////////////////////////////////////////////
2077
2078///////////////////////////////////////////////////////
2079void rpc_mapper_get_page_client( cxy_t             cxy,
2080                                 struct mapper_s * mapper,     // in
2081                                 uint32_t          index,      // in
2082                                 page_t         ** page )      // out
2083{
[407]2084    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]2085    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2086    CURRENT_THREAD->core->lid , hal_time_stamp() );
[313]2087
2088    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
2089
2090    // initialise RPC descriptor header
2091    rpc_desc_t  rpc;
2092    rpc.index    = RPC_MAPPER_GET_PAGE;
2093    rpc.response = 1;
[416]2094    rpc.blocking = true;
[313]2095
2096    // set input arguments in RPC descriptor
2097    rpc.args[0] = (uint64_t)(intptr_t)mapper;
2098    rpc.args[1] = (uint64_t)index;
2099
2100    // register RPC request in remote RPC fifo (blocking function)
[416]2101    rpc_send( cxy , &rpc );
[313]2102
2103    // get output values from RPC descriptor
2104    *page = (page_t *)(intptr_t)rpc.args[2];
2105
[407]2106    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]2107    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2108    CURRENT_THREAD->core->lid , hal_time_stamp() );
[313]2109}
2110
2111////////////////////////////////////////////
2112void rpc_mapper_get_page_server( xptr_t xp )
2113{
[407]2114    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
[337]2115    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2116    CURRENT_THREAD->core->lid , hal_time_stamp() );
[313]2117
2118    // get client cluster identifier and pointer on RPC descriptor
2119    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
2120    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
2121
2122    // get input arguments from client RPC descriptor
2123    mapper_t * mapper = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) );
2124    uint32_t   index  = (uint32_t)            hal_remote_lwd( XPTR( cxy , &desc->args[1] ) );
2125   
2126    // call local pmem allocator
2127    page_t * page = mapper_get_page( mapper , index ); 
2128
2129    // set output arguments into client RPC descriptor
2130    hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page );
2131
[407]2132    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
[337]2133    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2134    CURRENT_THREAD->core->lid , hal_time_stamp() );
[313]2135}
2136
[407]2137/////////////////////////////////////////////////////////////////////////////////////////
[409]2138// [26]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
[407]2139/////////////////////////////////////////////////////////////////////////////////////////
[313]2140
[407]2141////////////////////////////////////////////////////////
2142void rpc_vmm_create_vseg_client( cxy_t              cxy,
2143                                 struct process_s * process,
2144                                 vseg_type_t        type,
2145                                 intptr_t           base,
2146                                 uint32_t           size,
2147                                 uint32_t           file_offset,
2148                                 uint32_t           file_size,
2149                                 xptr_t             mapper_xp,
2150                                 cxy_t              vseg_cxy,
2151                                 struct vseg_s   ** vseg )
2152{
2153    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2154    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2155    CURRENT_THREAD->core->lid , hal_time_stamp() );
2156
2157    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
2158
2159    // initialise RPC descriptor header
2160    rpc_desc_t  rpc;
2161    rpc.index    = RPC_VMM_CREATE_VSEG;
2162    rpc.response = 1;
[416]2163    rpc.blocking = true;
[407]2164
2165    // set input arguments in RPC descriptor
2166    rpc.args[0] = (uint64_t)(intptr_t)process;
2167    rpc.args[1] = (uint64_t)type;
2168    rpc.args[2] = (uint64_t)base;
2169    rpc.args[3] = (uint64_t)size;
2170    rpc.args[4] = (uint64_t)file_offset;
2171    rpc.args[5] = (uint64_t)file_size;
2172    rpc.args[6] = (uint64_t)mapper_xp;
2173    rpc.args[7] = (uint64_t)vseg_cxy;
2174
2175    // register RPC request in remote RPC fifo (blocking function)
[416]2176    rpc_send( cxy , &rpc );
[407]2177
2178    // get output values from RPC descriptor
2179    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
2180
2181    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2182    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2183    CURRENT_THREAD->core->lid , hal_time_stamp() );
2184}
2185
2186////////////////////////////////////////////
2187void rpc_vmm_create_vseg_server( xptr_t xp )
2188{
2189    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2190    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2191    CURRENT_THREAD->core->lid , hal_time_stamp() );
2192
2193    // get client cluster identifier and pointer on RPC descriptor
2194    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
2195    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
2196
2197    // get input arguments from client RPC descriptor
2198    process_t * process     = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
2199    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_lwd( XPTR(cxy , &desc->args[1]));
2200    intptr_t    base        = (intptr_t)             hal_remote_lwd( XPTR(cxy , &desc->args[2]));
2201    uint32_t    size        = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[3]));
2202    uint32_t    file_offset = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[4]));
2203    uint32_t    file_size   = (uint32_t)             hal_remote_lwd( XPTR(cxy , &desc->args[5]));
2204    xptr_t      mapper_xp   = (xptr_t)               hal_remote_lwd( XPTR(cxy , &desc->args[6]));
2205    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_lwd( XPTR(cxy , &desc->args[7]));
2206   
2207    // call local kernel function
2208    vseg_t * vseg = vmm_create_vseg( process,
2209                                     type,
2210                                     base,
2211                                     size,
2212                                     file_offset,
2213                                     file_size,
2214                                     mapper_xp,
2215                                     vseg_cxy ); 
2216
2217    // set output arguments into client RPC descriptor
2218    hal_remote_swd( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
2219
2220    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2221    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2222    CURRENT_THREAD->core->lid , hal_time_stamp() );
2223}
2224
2225/////////////////////////////////////////////////////////////////////////////////////////
[409]2226// [27]          Marshaling functions attached to RPC_SCHED_DISPLAY (blocking)
[407]2227/////////////////////////////////////////////////////////////////////////////////////////
2228
2229////////////////////////////////////////////////////////
2230void rpc_sched_display_client( cxy_t              cxy,
2231                               lid_t              lid)
2232{
2233    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2234    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2235    CURRENT_THREAD->core->lid , hal_time_stamp() );
2236
2237    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
2238
2239    // initialise RPC descriptor header
2240    rpc_desc_t  rpc;
2241    rpc.index    = RPC_SCHED_DISPLAY;
2242    rpc.response = 1;
[416]2243    rpc.blocking = true;
[407]2244
2245    // set input arguments in RPC descriptor
2246    rpc.args[0] = (uint64_t)lid;
2247
2248    // register RPC request in remote RPC fifo (blocking function)
[416]2249    rpc_send( cxy , &rpc );
[407]2250
2251    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2252    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2253    CURRENT_THREAD->core->lid , hal_time_stamp() );
2254}
2255
2256//////////////////////////////////////////
2257void rpc_sched_display_server( xptr_t xp )
2258{
2259    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2260    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2261    CURRENT_THREAD->core->lid , hal_time_stamp() );
2262
2263    // get client cluster identifier and pointer on RPC descriptor
2264    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
2265    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
2266
2267    // get input arguments from client RPC descriptor
[428]2268    lid_t lid = (lid_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
[407]2269   
2270    // call local kernel function
2271    sched_display( lid );
2272
2273    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2274    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2275    CURRENT_THREAD->core->lid , hal_time_stamp() );
2276}
2277
[408]2278/////////////////////////////////////////////////////////////////////////////////////////
[409]2279// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
[408]2280/////////////////////////////////////////////////////////////////////////////////////////
2281
2282/////////////////////////////////////////////
2283void rpc_vmm_set_cow_client( cxy_t       cxy,
2284                             process_t * process )
2285{
2286    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2287    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2288    CURRENT_THREAD->core->lid , hal_time_stamp() );
2289
2290    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
2291
2292    // initialise RPC descriptor header
2293    rpc_desc_t  rpc;
2294    rpc.index    = RPC_VMM_SET_COW;
2295    rpc.response = 1;
[416]2296    rpc.blocking = true;
[408]2297
2298    // set input arguments in RPC descriptor
2299    rpc.args[0] = (uint64_t)(intptr_t)process;
2300
2301    // register RPC request in remote RPC fifo (blocking function)
[416]2302    rpc_send( cxy , &rpc );
[408]2303
2304    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2305    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2306    CURRENT_THREAD->core->lid , hal_time_stamp() );
2307}
2308
2309////////////////////////////////////////
2310void rpc_vmm_set_cow_server( xptr_t xp )
2311{
2312    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2313    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2314    CURRENT_THREAD->core->lid , hal_time_stamp() );
2315
2316    process_t * process;
2317
2318    // get client cluster identifier and pointer on RPC descriptor
2319    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
2320    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
2321
2322    // get input arguments from client RPC descriptor
[428]2323    process = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
[408]2324   
2325    // call local kernel function
2326    vmm_set_cow( process );
2327
2328    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2329    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2330    CURRENT_THREAD->core->lid , hal_time_stamp() );
2331}
2332
[428]2333/////////////////////////////////////////////////////////////////////////////////////////
2334// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
2335/////////////////////////////////////////////////////////////////////////////////////////
[1]2336
[428]2337/////////////////////////////////////////////
2338void rpc_vmm_display_client( cxy_t       cxy,
2339                             process_t * process,
2340                             bool_t      detailed )
2341{
2342    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2343    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2344    CURRENT_THREAD->core->lid , hal_time_stamp() );
2345
2346    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
2347
2348    // initialise RPC descriptor header
2349    rpc_desc_t  rpc;
2350    rpc.index    = RPC_VMM_DISPLAY;
2351    rpc.response = 1;
2352    rpc.blocking = true;
2353
2354    // set input arguments in RPC descriptor
2355    rpc.args[0] = (uint64_t)(intptr_t)process;
2356    rpc.args[1] = (uint64_t)detailed;
2357
2358    // register RPC request in remote RPC fifo (blocking function)
2359    rpc_send( cxy , &rpc );
2360
2361    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2362    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2363    CURRENT_THREAD->core->lid , hal_time_stamp() );
2364}
2365
2366////////////////////////////////////////
2367void rpc_vmm_display_server( xptr_t xp )
2368{
2369    rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",
2370    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2371    CURRENT_THREAD->core->lid , hal_time_stamp() );
2372
2373    process_t * process;
2374    bool_t      detailed;
2375
2376    // get client cluster identifier and pointer on RPC descriptor
2377    cxy_t        cxy  = (cxy_t)GET_CXY( xp );
2378    rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp );
2379
2380    // get input arguments from client RPC descriptor
2381    process  = (process_t *)(intptr_t)hal_remote_lwd( XPTR(cxy , &desc->args[0]));
2382    detailed = (bool_t)               hal_remote_lwd( XPTR(cxy , &desc->args[1]));
2383   
2384    // call local kernel function
2385    vmm_display( process , detailed );
2386
2387    rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n",
2388    __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 
2389    CURRENT_THREAD->core->lid , hal_time_stamp() );
2390}
2391
2392
Note: See TracBrowser for help on using the repository browser.