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

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

Fix several bugs in vfs.c, fatfs.c, and devfs.c to support
the <.> and <..> directory entries.

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