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

Last change on this file since 415 was 415, checked in by alain, 6 years ago

Few bugs.

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