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

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

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

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