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

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

1) introduce a dev_ioc_sync_write() function in IOC API,

to improve the DEVFS synchronous update.

2) fix a big bug in both the user_dir_create() and user_dir_destroy()

functions: add an extended pointer on the reference client process
in the function's arguments.

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