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

Last change on this file since 611 was 611, checked in by alain, 3 years ago

Introduce sigificant modifs in VFS to support the <ls> command,
and the . and .. directories entries.

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