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

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

1) Fix a bug in KSH : after the "load" command,

the [ksh] prompt is now printed after completion
of the loaded application.

2) Fix a bug in vmm_handle_cow() : the copy-on-write

use now a hal_remote_memcpy() to replicate the page content.


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