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

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

Improve the FAT32 file system to support cat, rm, cp commands.

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