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

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

Fix several bugs in VFS to support the following
ksh commandis : cp, mv, rm, mkdir, cd, pwd

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