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

Last change on this file since 638 was 637, checked in by alain, 5 years ago

Introduce the non-standard pthread_parallel_create() system call
and re-write the <fft> and <sort> applications to improve the
intrinsic paralelism in applications.

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