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

Last change on this file since 615 was 614, checked in by alain, 6 years ago

1) introduce a dev_ioc_sync_write() function in IOC API,

to improve the DEVFS synchronous update.

2) fix a big bug in both the user_dir_create() and user_dir_destroy()

functions: add an extended pointer on the reference client process
in the function's arguments.

File size: 94.0 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
[614]56    &rpc_user_dir_create_server,           // 4
57    &rpc_user_dir_destroy_server,          // 5
[601]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
[614]92    "USER_DIR_CREATE",           // 4
93    "USER_DIR_DESTROY",          // 5
[601]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,
[614]659                                 xptr_t         ref_xp,
[612]660                                 user_dir_t  ** dir )
661{
662#if DEBUG_RPC_USER_DIR_CREATE
663thread_t * this = CURRENT_THREAD;
664uint32_t cycle = (uint32_t)hal_get_cycles();
665if( cycle > DEBUG_RPC_USER_DIR_CREATE)
666printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
667__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
668#endif
669
670    assert( (cxy != local_cxy) , "server cluster is not remote\n");
671
672    // initialise RPC descriptor header
673    rpc_desc_t  rpc;
674    rpc.index    = RPC_USER_DIR_CREATE;
675    rpc.blocking = true;
676    rpc.responses = 1;
677
678    // set input arguments in RPC descriptor
679    rpc.args[0] = (uint64_t)(intptr_t)inode;
[614]680    rpc.args[1] = (uint64_t)ref_xp;
[612]681
682    // register RPC request in remote RPC fifo
683    rpc_send( cxy , &rpc );
684
685    // get output argument from RPC descriptor
[614]686    *dir = (user_dir_t *)(intptr_t)rpc.args[2];
[612]687
688#if DEBUG_RPC_USER_DIR_CREATE
689cycle = (uint32_t)hal_get_cycles();
690if( cycle > DEBUG_RPC_USER_DIR_CREATE)
691printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
692__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
693#endif
694}
695
696////////////////////////////////////////////
697void rpc_user_dir_create_server( xptr_t xp )
698{
699#if DEBUG_RPC_USER_DIR_CREATE
700thread_t * this = CURRENT_THREAD;
701uint32_t cycle = (uint32_t)hal_get_cycles();
702if( cycle > DEBUG_RPC_USER_DIR_CREATE)
703printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
704__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
705#endif
706
707    vfs_inode_t * inode;          // pointer on inode in server cluster
[614]708    xptr_t        ref_xp;         // extended pointer on reference user process
[612]709    user_dir_t  * dir;            // pointer on user_dir structure in server cluster
710
711    // get client cluster identifier and pointer on RPC descriptor
712    cxy_t        client_cxy  = GET_CXY( xp );
713    rpc_desc_t * desc        = GET_PTR( xp );
714
715    // get input argument from RPC descriptor
[614]716    inode  = (vfs_inode_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
717    ref_xp = (xptr_t)                 hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[612]718
719    // call kernel function
[614]720    dir = user_dir_create( inode , ref_xp );
[612]721
722    // set output argument into RPC descriptor
[614]723    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (intptr_t)dir );
[612]724
725#if DEBUG_RPC_USER_DIR_CREATE
726cycle = (uint32_t)hal_get_cycles();
727if( cycle > DEBUG_RPC_USER_DIR_CREATE)
728printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
729__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
730#endif
731}
732
[409]733/////////////////////////////////////////////////////////////////////////////////////////
[612]734// [5]      Marshaling functions attached to RPC_USER_DIR_DESTROY (blocking)
[409]735/////////////////////////////////////////////////////////////////////////////////////////
736
[612]737////////////////////////////////////////////////////
738void rpc_user_dir_destroy_client( cxy_t         cxy,
[614]739                                  user_dir_t  * dir,
740                                  xptr_t        ref_xp )
[612]741{
742#if DEBUG_RPC_USER_DIR_DESTROY
743thread_t * this = CURRENT_THREAD;
744uint32_t cycle = (uint32_t)hal_get_cycles();
745if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
746printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
747__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
748#endif
749
750    assert( (cxy != local_cxy) , "server cluster is not remote\n");
751
752    // initialise RPC descriptor header
753    rpc_desc_t  rpc;
754    rpc.index    = RPC_USER_DIR_DESTROY;
755    rpc.blocking = true;
756    rpc.responses = 1;
757
758    // set input arguments in RPC descriptor
759    rpc.args[0] = (uint64_t)(intptr_t)dir;
[614]760    rpc.args[1] = (uint64_t)ref_xp;
[612]761
762    // register RPC request in remote RPC fifo
763    rpc_send( cxy , &rpc );
764
765#if DEBUG_RPC_USER_DIR_DESTROY
766cycle = (uint32_t)hal_get_cycles();
767if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
768printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
769__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
770#endif
771}
772
773/////////////////////////////////////////////
774void rpc_user_dir_destroy_server( xptr_t xp )
775{
776#if DEBUG_RPC_USER_DIR_DESTROY
777thread_t * this = CURRENT_THREAD;
778uint32_t cycle = (uint32_t)hal_get_cycles();
779if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
780printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
781__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
782#endif
783
784    user_dir_t * dir;            // pointer on user_dir structure in server cluster
[614]785    xptr_t       ref_xp;         // extended pointer on reference process
[612]786
787    // get client cluster identifier and pointer on RPC descriptor
788    cxy_t        client_cxy  = GET_CXY( xp );
789    rpc_desc_t * desc        = GET_PTR( xp );
790
791    // get input argument from RPC descriptor
[614]792    dir    = (user_dir_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
793    ref_xp = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[612]794
795    // call kernel function
[614]796    user_dir_destroy( dir , ref_xp );
[612]797
798#if DEBUG_RPC_USER_DIR_DESTROY
799cycle = (uint32_t)hal_get_cycles();
800if( cycle > DEBUG_RPC_USER_DIR_DESTROY)
801printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
802__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
803#endif
804}
805
[1]806/////////////////////////////////////////////////////////////////////////////////////////
[436]807// [6]      Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 
[1]808/////////////////////////////////////////////////////////////////////////////////////////
809
810/////////////////////////////////////////////////////////
811void rpc_thread_user_create_client( cxy_t            cxy, 
[23]812                                    pid_t            pid,         // in
813                                    void           * start_func,  // in
814                                    void           * start_arg,   // in
[1]815                                    pthread_attr_t * attr,        // in
816                                    xptr_t         * thread_xp,   // out
817                                    error_t        * error )      // out
818{
[564]819#if DEBUG_RPC_THREAD_USER_CREATE
820thread_t * this = CURRENT_THREAD;
821uint32_t cycle = (uint32_t)hal_get_cycles();
822if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]823printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
824__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]825#endif
826
[611]827    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]828
829    // initialise RPC descriptor header
830    rpc_desc_t  rpc;
[436]831    rpc.index    = RPC_THREAD_USER_CREATE;
[416]832    rpc.blocking = true;
[438]833    rpc.responses = 1;
[1]834
835    // set input arguments in RPC descriptor
[23]836    rpc.args[0] = (uint64_t)pid;
837    rpc.args[1] = (uint64_t)(intptr_t)start_func;
838    rpc.args[2] = (uint64_t)(intptr_t)start_arg;
839    rpc.args[3] = (uint64_t)(intptr_t)attr;
[1]840
[436]841    // register RPC request in remote RPC fifo
[416]842    rpc_send( cxy , &rpc );
[1]843
844    // get output arguments from RPC descriptor
[23]845    *thread_xp = (xptr_t)rpc.args[4];
846    *error     = (error_t)rpc.args[5];
[279]847
[564]848#if DEBUG_RPC_THREAD_USER_CREATE
849cycle = (uint32_t)hal_get_cycles();
850if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]851printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
852__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]853#endif
[1]854}
855
856///////////////////////////////////////////////
857void rpc_thread_user_create_server( xptr_t xp )
858{
[564]859#if DEBUG_RPC_THREAD_USER_CREATE
860thread_t * this = CURRENT_THREAD;
861uint32_t cycle = (uint32_t)hal_get_cycles();
862if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]863printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
864__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]865#endif
[409]866
[1]867    pthread_attr_t * attr_ptr;   // pointer on attributes structure in client cluster
868    pthread_attr_t   attr_copy;  // attributes structure  copy in server cluster
869    thread_t       * thread_ptr; // local pointer on thread descriptor
870    xptr_t           thread_xp;  // extended pointer on thread descriptor
[23]871
[1]872    pid_t            pid;        // process identifier
[23]873    void           * start_func;
874    void           * start_arg;
875    error_t          error;
[1]876
877    // get client cluster identifier and pointer on RPC descriptor
[436]878    cxy_t        client_cxy  = GET_CXY( xp );
[438]879    rpc_desc_t * desc        = GET_PTR( xp );
[1]880
[23]881    // get input arguments from RPC descriptor
[564]882    pid        = (pid_t)                     hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
883    start_func = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
884    start_arg  = (void *)(intptr_t)          hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
885    attr_ptr   = (pthread_attr_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[3]));
[23]886
[1]887    // makes a local copy of attributes structure
888    hal_remote_memcpy( XPTR( local_cxy , &attr_copy ),
889                       XPTR( client_cxy , attr_ptr ), 
890                       sizeof(pthread_attr_t) );
891   
[23]892    // call kernel function
893    error = thread_user_create( pid,
894                                start_func,
895                                start_arg,
896                                &attr_copy,
897                                &thread_ptr );
[1]898    // set output arguments
899    thread_xp = XPTR( local_cxy , thread_ptr );
[564]900    hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp );
901    hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
[296]902
[564]903#if DEBUG_RPC_THREAD_USER_CREATE
904cycle = (uint32_t)hal_get_cycles();
905if( cycle > DEBUG_RPC_THREAD_USER_CREATE)
[601]906printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
907__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]908#endif
[1]909}
910
911/////////////////////////////////////////////////////////////////////////////////////////
[436]912// [7]      Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking)
[1]913/////////////////////////////////////////////////////////////////////////////////////////
914
915////////////////////////////////////////////////////
916void rpc_thread_kernel_create_client( cxy_t     cxy,
917                                      uint32_t  type,        // in
918                                      void    * func,        // in
919                                      void    * args,        // in
920                                      xptr_t  * thread_xp,   // out
921                                      error_t * error )      // out
922{
[564]923#if DEBUG_RPC_THREAD_KERNEL_CREATE
924thread_t * this = CURRENT_THREAD;
925uint32_t cycle = (uint32_t)hal_get_cycles();
926if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]927printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
928__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]929#endif
930
[611]931    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]932
933    // initialise RPC descriptor header
934    rpc_desc_t  rpc;
935    rpc.index    = RPC_THREAD_KERNEL_CREATE;
[416]936    rpc.blocking = true;
[438]937    rpc.responses = 1;
[1]938
939    // set input arguments in RPC descriptor
940    rpc.args[0] = (uint64_t)type;
941    rpc.args[1] = (uint64_t)(intptr_t)func;
942    rpc.args[2] = (uint64_t)(intptr_t)args;
943   
[436]944    // register RPC request in remote RPC fifo
[416]945    rpc_send( cxy , &rpc );
[1]946
947    // get output arguments from RPC descriptor
948    *thread_xp = (xptr_t)rpc.args[3];
949    *error     = (error_t)rpc.args[4];
[279]950
[564]951#if DEBUG_RPC_THREAD_KERNEL_CREATE
952cycle = (uint32_t)hal_get_cycles();
953if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]954printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
955__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]956#endif
[1]957}
958
959/////////////////////////////////////////////////
960void rpc_thread_kernel_create_server( xptr_t xp )
961{
[564]962#if DEBUG_RPC_THREAD_KERNEL_CREATE
963thread_t * this = CURRENT_THREAD;
964uint32_t cycle = (uint32_t)hal_get_cycles();
965if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]966printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
967__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]968#endif
969
[1]970    thread_t       * thread_ptr;  // local pointer on thread descriptor
971    xptr_t           thread_xp;   // extended pointer on thread descriptor
972    lid_t            core_lid;    // core local index
973    error_t          error;   
974
975    // get client cluster identifier and pointer on RPC descriptor
[436]976    cxy_t        client_cxy  = GET_CXY( xp );
[438]977    rpc_desc_t * desc        = GET_PTR( xp );
[1]978
979    // get attributes from RPC descriptor
[564]980    uint32_t  type = (uint32_t)       hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
981    void    * func = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
982    void    * args = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
[1]983
984    // select one core
985    core_lid = cluster_select_local_core();
986
987    // call local kernel function
988    error = thread_kernel_create( &thread_ptr , type , func , args , core_lid );
989
990    // set output arguments
991    thread_xp = XPTR( local_cxy , thread_ptr );
[564]992    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
993    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp );
[296]994
[564]995#if DEBUG_RPC_THREAD_KERNEL_CREATE
996cycle = (uint32_t)hal_get_cycles();
997if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE)
[601]998printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
999__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[564]1000#endif
[1]1001}
1002
1003/////////////////////////////////////////////////////////////////////////////////////////
[436]1004// [8]   undefined slot
[1]1005/////////////////////////////////////////////////////////////////////////////////////////
1006
[296]1007
[23]1008/////////////////////////////////////////////////////////////////////////////////////////
[611]1009// [9]   Marshaling functions attached to RPC_PROCESS_SIGACTION (non blocking)
[23]1010/////////////////////////////////////////////////////////////////////////////////////////
1011
[416]1012////////////////////////////////////////////////////
1013void rpc_process_sigaction_client( cxy_t        cxy,
[436]1014                                   rpc_desc_t * rpc )
[409]1015{
[438]1016#if DEBUG_RPC_PROCESS_SIGACTION
[611]1017uint32_t  cycle = (uint32_t)hal_get_cycles();
[610]1018thread_t * this = CURRENT_THREAD;
[438]1019if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
[611]1020printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1021__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[436]1022#endif
[409]1023
[611]1024// check RPC "index" and "blocking" arguments
1025assert( (rpc->blocking == false) , "must be non-blocking\n");
1026assert( (rpc->index == RPC_PROCESS_SIGACTION ) , "bad RPC index\n" );
[409]1027
[436]1028    // register RPC request in remote RPC fifo and return
1029    rpc_send( cxy , rpc );
1030
[438]1031#if DEBUG_RPC_PROCESS_SIGACTION
[436]1032cycle = (uint32_t)hal_get_cycles();
[438]1033if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
[611]1034printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1035__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[436]1036#endif
1037}  // end rpc_process_sigaction_client()
1038
[409]1039//////////////////////////////////////////////
1040void rpc_process_sigaction_server( xptr_t xp )
1041{
[438]1042#if DEBUG_RPC_PROCESS_SIGACTION
[436]1043uint32_t cycle = (uint32_t)hal_get_cycles();
[610]1044thread_t * this = CURRENT_THREAD;
[438]1045if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
[611]1046printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1047__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[436]1048#endif
[435]1049
[611]1050    // get client cluster identifier and pointer on RPC descriptor
1051    cxy_t        client_cxy = GET_CXY( xp );
1052    rpc_desc_t * desc       = GET_PTR( xp );
1053
1054    // get arguments from RPC descriptor
1055    pid_t    pid    = (pid_t)   hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
1056    uint32_t action = (uint32_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
1057
[440]1058    // get client thread pointers
[611]1059    thread_t * client_ptr = hal_remote_lpt( XPTR( client_cxy , &desc->thread ) );
1060    xptr_t     client_xp  = XPTR( client_cxy , client_ptr );
[440]1061
[435]1062    // get local process descriptor
[611]1063    process_t * process = cluster_get_local_process_from_pid( pid );
[435]1064
[409]1065    // call relevant kernel function
[440]1066    if      ( action == DELETE_ALL_THREADS  ) process_delete_threads ( process , client_xp ); 
[591]1067    else if ( action == BLOCK_ALL_THREADS   ) process_block_threads  ( process ); 
[436]1068    else if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process );
[409]1069
[438]1070#if DEBUG_RPC_PROCESS_SIGACTION
[436]1071cycle = (uint32_t)hal_get_cycles();
[438]1072if( DEBUG_RPC_PROCESS_SIGACTION < cycle )
[611]1073printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1074__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[436]1075#endif
1076} // end rpc_process_sigaction_server()
1077
[409]1078/////////////////////////////////////////////////////////////////////////////////////////
[436]1079// [10]     Marshaling functions attached to RPC_VFS_INODE_CREATE  (blocking)
[409]1080/////////////////////////////////////////////////////////////////////////////////////////
1081
[1]1082/////////////////////////////////////////////////////
1083void rpc_vfs_inode_create_client( cxy_t          cxy,     
[23]1084                                  uint32_t       fs_type,    // in
1085                                  uint32_t       inode_type, // in
[1]1086                                  uint32_t       attr,       // in
[23]1087                                  uint32_t       rights,     // in
[1]1088                                  uint32_t       uid,        // in
1089                                  uint32_t       gid,        // in
1090                                  xptr_t       * inode_xp,   // out
1091                                  error_t      * error )     // out
1092{
[459]1093#if DEBUG_RPC_VFS_INODE_CREATE
[564]1094thread_t * this = CURRENT_THREAD;
[459]1095uint32_t cycle = (uint32_t)hal_get_cycles();
1096if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1097printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1098__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[459]1099#endif
1100
[611]1101    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]1102
1103    // initialise RPC descriptor header
1104    rpc_desc_t  rpc;
1105    rpc.index    = RPC_VFS_INODE_CREATE;
[416]1106    rpc.blocking = true;
[438]1107    rpc.responses = 1;
[1]1108
1109    // set input arguments in RPC descriptor
[610]1110    rpc.args[0] = (uint64_t)fs_type;
1111    rpc.args[1] = (uint64_t)inode_type;
1112    rpc.args[2] = (uint64_t)attr;
1113    rpc.args[3] = (uint64_t)rights;
1114    rpc.args[4] = (uint64_t)uid;
1115    rpc.args[5] = (uint64_t)gid;
[1]1116
[436]1117    // register RPC request in remote RPC fifo
[416]1118    rpc_send( cxy , &rpc );
[1]1119
1120    // get output values from RPC descriptor
[610]1121    *inode_xp = (xptr_t)rpc.args[6];
1122    *error    = (error_t)rpc.args[7];
[279]1123
[459]1124#if DEBUG_RPC_VFS_INODE_CREATE
[564]1125cycle = (uint32_t)hal_get_cycles();
[459]1126if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1127printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1128__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1129#endif
[1]1130}
1131
1132/////////////////////////////////////////////
1133void rpc_vfs_inode_create_server( xptr_t xp )
1134{
[459]1135#if DEBUG_RPC_VFS_INODE_CREATE
[564]1136thread_t * this = CURRENT_THREAD;
[459]1137uint32_t cycle = (uint32_t)hal_get_cycles();
1138if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1139printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1140__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1141#endif
1142
[23]1143    uint32_t         fs_type;
1144    uint32_t         inode_type;
[1]1145    uint32_t         attr;
[23]1146    uint32_t         rights;
[1]1147    uint32_t         uid;
1148    uint32_t         gid;
1149    xptr_t           inode_xp;
1150    error_t          error;
1151
1152    // get client cluster identifier and pointer on RPC descriptor
[436]1153    cxy_t        client_cxy  = GET_CXY( xp );
1154    rpc_desc_t * desc        = GET_PTR( xp );
[1]1155
1156    // get input arguments from client rpc descriptor
[610]1157    fs_type    = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1158    inode_type = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
1159    attr       = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
1160    rights     = (uint32_t)  hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
1161    uid        = (uid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) );
1162    gid        = (gid_t)     hal_remote_l64( XPTR( client_cxy , &desc->args[5] ) );
[1]1163
1164    // call local kernel function
[610]1165    error = vfs_inode_create( fs_type,
[23]1166                              inode_type,
[1]1167                              attr,
[23]1168                              rights,
[1]1169                              uid,
1170                              gid,
1171                              &inode_xp );
1172
1173    // set output arguments
[610]1174    hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)inode_xp );
1175    hal_remote_s64( XPTR( client_cxy , &desc->args[7] ) , (uint64_t)error );
[296]1176
[459]1177#if DEBUG_RPC_VFS_INODE_CREATE
[564]1178cycle = (uint32_t)hal_get_cycles();
[459]1179if( cycle > DEBUG_RPC_VFS_INODE_CREATE )
[601]1180printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1181__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1182#endif
[1]1183}
1184
1185/////////////////////////////////////////////////////////////////////////////////////////
[409]1186// [11]          Marshaling functions attached to RPC_VFS_INODE_DESTROY  (blocking)
[1]1187/////////////////////////////////////////////////////////////////////////////////////////
1188
1189/////////////////////////////////////////////////////////////
1190void rpc_vfs_inode_destroy_client( cxy_t                cxy,
[601]1191                                   struct vfs_inode_s * inode )
[1]1192{
[459]1193#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1194thread_t * this = CURRENT_THREAD;
[459]1195uint32_t cycle = (uint32_t)hal_get_cycles();
1196if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1197printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1198__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1199#endif
1200
[611]1201    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]1202
1203    // initialise RPC descriptor header
1204    rpc_desc_t  rpc;
1205    rpc.index    = RPC_VFS_INODE_DESTROY;
[416]1206    rpc.blocking = true;
[438]1207    rpc.responses = 1;
[1]1208
1209    // set input arguments in RPC descriptor
1210    rpc.args[0] = (uint64_t)(intptr_t)inode;
1211   
[436]1212    // register RPC request in remote RPC fifo
[416]1213    rpc_send( cxy , &rpc );
[279]1214
[459]1215#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1216cycle = (uint32_t)hal_get_cycles();
[459]1217if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1218printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1219__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1220#endif
[1]1221}
1222
1223//////////////////////////////////////////////
1224void rpc_vfs_inode_destroy_server( xptr_t xp )
1225{
[459]1226#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1227thread_t * this = CURRENT_THREAD;
[459]1228uint32_t cycle = (uint32_t)hal_get_cycles();
1229if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1230printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1231__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1232#endif
1233
[1]1234    vfs_inode_t * inode;
1235
1236    // get client cluster identifier and pointer on RPC descriptor
[436]1237    cxy_t        client_cxy  = GET_CXY( xp );
1238    rpc_desc_t * desc        = GET_PTR( xp );
[1]1239
[601]1240    // get argument "inode" from client RPC descriptor
[564]1241    inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[1]1242                       
1243    // call local kernel function
[601]1244    vfs_inode_destroy( inode );
[296]1245
[459]1246#if DEBUG_RPC_VFS_INODE_DESTROY
[564]1247cycle = (uint32_t)hal_get_cycles();
[459]1248if( cycle > DEBUG_RPC_VFS_INODE_DESTROY )
[601]1249printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1250__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[459]1251#endif
[1]1252}
1253
1254/////////////////////////////////////////////////////////////////////////////////////////
[409]1255// [12]          Marshaling functions attached to RPC_VFS_DENTRY_CREATE  (blocking)
[1]1256/////////////////////////////////////////////////////////////////////////////////////////
1257
1258//////////////////////////////////////////////////////////////
1259void rpc_vfs_dentry_create_client( cxy_t                  cxy,
1260                                   uint32_t               type,         // in
1261                                   char                 * name,         // in
1262                                   xptr_t               * dentry_xp,    // out
1263                                   error_t              * error )       // out
1264{
[438]1265#if DEBUG_RPC_VFS_DENTRY_CREATE
[564]1266thread_t * this = CURRENT_THREAD;
[438]1267uint32_t cycle = (uint32_t)hal_get_cycles();
1268if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1269printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1270__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1271#endif
[296]1272
[611]1273    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]1274
1275    // initialise RPC descriptor header
1276    rpc_desc_t  rpc;
1277    rpc.index    = RPC_VFS_DENTRY_CREATE;
[416]1278    rpc.blocking = true;
[438]1279    rpc.responses = 1;
[1]1280
1281    // set input arguments in RPC descriptor
1282    rpc.args[0] = (uint64_t)type;
1283    rpc.args[1] = (uint64_t)(intptr_t)name;
1284
[436]1285    // register RPC request in remote RPC fifo
[416]1286    rpc_send( cxy , &rpc );
[1]1287
1288    // get output values from RPC descriptor
[610]1289    *dentry_xp = (xptr_t)rpc.args[2];
1290    *error     = (error_t)rpc.args[3];
[279]1291
[438]1292#if DEBUG_RPC_VFS_DENTRY_CREATE
1293cycle = (uint32_t)hal_get_cycles();
1294if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1295printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1296__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1297#endif
[1]1298}
1299
1300//////////////////////////////////////////////
1301void rpc_vfs_dentry_create_server( xptr_t xp )
1302{
[438]1303#if DEBUG_RPC_VFS_DENTRY_CREATE
[564]1304thread_t * this = CURRENT_THREAD;
[438]1305uint32_t cycle = (uint32_t)hal_get_cycles();
1306if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1307printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1308__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]1309#endif
1310
[1]1311    uint32_t      type;
1312    char        * name;
1313    xptr_t        dentry_xp;
1314    error_t       error;
[238]1315    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1316
[1]1317    // get client cluster identifier and pointer on RPC descriptor
[436]1318    cxy_t        client_cxy  = GET_CXY( xp );
1319    rpc_desc_t * desc        = GET_PTR( xp );
[1]1320
[238]1321    // get arguments "name", "type", and "parent" from client RPC descriptor
[610]1322    type   = (uint32_t)         hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1323    name   = (char *)(intptr_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[296]1324
[238]1325    // makes a local copy of  name
1326    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
1327                       XPTR( client_cxy , name ) );
1328
[1]1329    // call local kernel function
1330    error = vfs_dentry_create( type,
1331                               name_copy,
1332                               &dentry_xp );
1333    // set output arguments
[610]1334    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)dentry_xp );
1335    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1336
[438]1337#if DEBUG_RPC_VFS_DENTRY_CREATE
1338cycle = (uint32_t)hal_get_cycles();
1339if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE )
[601]1340printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1341__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1342#endif
[1]1343}
1344
1345/////////////////////////////////////////////////////////////////////////////////////////
[409]1346// [13]          Marshaling functions attached to RPC_VFS_DENTRY_DESTROY  (blocking)
[1]1347/////////////////////////////////////////////////////////////////////////////////////////
1348
1349///////////////////////////////////////////////////////
1350void rpc_vfs_dentry_destroy_client( cxy_t          cxy,
[601]1351                                    vfs_dentry_t * dentry )
[1]1352{
[440]1353#if DEBUG_RPC_VFS_DENTRY_DESTROY
[564]1354thread_t * this = CURRENT_THREAD;
[440]1355uint32_t cycle = (uint32_t)hal_get_cycles();
1356if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1357printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1358__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1359#endif
1360
[611]1361    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]1362
1363    // initialise RPC descriptor header
1364    rpc_desc_t  rpc;
1365    rpc.index    = RPC_VFS_DENTRY_DESTROY;
[416]1366    rpc.blocking = true;
[438]1367    rpc.responses = 1;
[1]1368
1369    // set input arguments in RPC descriptor
1370    rpc.args[0] = (uint64_t)(intptr_t)dentry;
1371   
[436]1372    // register RPC request in remote RPC fifo
[416]1373    rpc_send( cxy , &rpc );
[279]1374
[440]1375#if DEBUG_RPC_VFS_DENTRY_DESTROY
1376cycle = (uint32_t)hal_get_cycles();
1377if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1378printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1379__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1380#endif
[1]1381}
1382
1383///////////////////////////////////////////////
1384void rpc_vfs_dentry_destroy_server( xptr_t xp )
1385{
[440]1386#if DEBUG_RPC_VFS_DENTRY_DESTROY
[564]1387thread_t * this = CURRENT_THREAD;
[440]1388uint32_t cycle = (uint32_t)hal_get_cycles();
1389if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1390printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1391__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1392#endif
1393
[1]1394    vfs_dentry_t * dentry;
1395
1396    // get client cluster identifier and pointer on RPC descriptor
[436]1397    cxy_t        client_cxy  = GET_CXY( xp );
1398    rpc_desc_t * desc        = GET_PTR( xp );
[1]1399
1400    // get arguments "dentry" from client RPC descriptor
[564]1401    dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[1]1402                       
1403    // call local kernel function
[601]1404    vfs_dentry_destroy( dentry );
[296]1405
[440]1406#if DEBUG_RPC_VFS_DENTRY_DESTROY
1407cycle = (uint32_t)hal_get_cycles();
1408if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY )
[601]1409printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1410__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1411#endif
[1]1412}
1413
1414
1415/////////////////////////////////////////////////////////////////////////////////////////
[409]1416// [14]          Marshaling functions attached to RPC_VFS_FILE_CREATE  (blocking)
[1]1417/////////////////////////////////////////////////////////////////////////////////////////
1418
[23]1419//////////////////////////////////////////////////////////////
1420void rpc_vfs_file_create_client( cxy_t                  cxy,
1421                                 struct vfs_inode_s   * inode,       // in
1422                                 uint32_t               file_attr,   // in
1423                                 xptr_t               * file_xp,     // out
1424                                 error_t              * error )      // out
1425{
[438]1426#if DEBUG_RPC_VFS_FILE_CREATE
[564]1427thread_t * this = CURRENT_THREAD;
[438]1428uint32_t cycle = (uint32_t)hal_get_cycles();
1429if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]1430printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1431__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]1432#endif
1433
[611]1434    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[23]1435
1436    // initialise RPC descriptor header
1437    rpc_desc_t  rpc;
1438    rpc.index    = RPC_VFS_FILE_CREATE;
[416]1439    rpc.blocking = true;
[438]1440    rpc.responses = 1;
[23]1441
1442    // set input arguments in RPC descriptor
1443    rpc.args[0] = (uint64_t)(intptr_t)inode;
1444    rpc.args[1] = (uint64_t)file_attr;
1445
[436]1446    // register RPC request in remote RPC fifo
[416]1447    rpc_send( cxy , &rpc );
[23]1448
1449    // get output values from RPC descriptor
1450    *file_xp = (xptr_t)rpc.args[2];
1451    *error   = (error_t)rpc.args[3];
[279]1452
[438]1453#if DEBUG_RPC_VFS_FILE_CREATE
1454cycle = (uint32_t)hal_get_cycles();
1455if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]1456printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1457__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1458#endif
[23]1459}
1460
1461////////////////////////////////////////////
1462void rpc_vfs_file_create_server( xptr_t xp )
1463{
[438]1464#if DEBUG_RPC_VFS_FILE_CREATE
[564]1465thread_t * this = CURRENT_THREAD;
[438]1466uint32_t cycle = (uint32_t)hal_get_cycles();
1467if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]1468printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1469__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[438]1470#endif
1471
[23]1472    uint32_t      file_attr;
1473    vfs_inode_t * inode;
1474    xptr_t        file_xp;
1475    error_t       error;
1476
1477    // get client cluster identifier and pointer on RPC descriptor
[436]1478    cxy_t        client_cxy  = GET_CXY( xp );
1479    rpc_desc_t * desc        = GET_PTR( xp );
[23]1480
1481    // get arguments "file_attr" and "inode" from client RPC descriptor
[564]1482    inode     = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1483    file_attr = (uint32_t)               hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[23]1484                       
1485    // call local kernel function
1486    error = vfs_file_create( inode,
1487                             file_attr,
1488                             &file_xp );
1489 
1490    // set output arguments
[564]1491    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp );
1492    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1493
[438]1494#if DEBUG_RPC_VFS_FILE_CREATE
1495cycle = (uint32_t)hal_get_cycles();
1496if( cycle > DEBUG_RPC_VFS_FILE_CREATE )
[601]1497printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1498__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[438]1499#endif
[23]1500}
1501
1502/////////////////////////////////////////////////////////////////////////////////////////
[409]1503// [15]          Marshaling functions attached to RPC_VFS_FILE_DESTROY  (blocking)
[23]1504/////////////////////////////////////////////////////////////////////////////////////////
1505
1506///////////////////////////////////////////////////
1507void rpc_vfs_file_destroy_client( cxy_t        cxy,
1508                                  vfs_file_t * file )
1509{
[440]1510#if DEBUG_RPC_VFS_FILE_DESTROY
[564]1511thread_t * this = CURRENT_THREAD;
[440]1512uint32_t cycle = (uint32_t)hal_get_cycles();
1513if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]1514printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1515__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1516#endif
1517
[611]1518    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[23]1519
1520    // initialise RPC descriptor header
1521    rpc_desc_t  rpc;
1522    rpc.index    = RPC_VFS_FILE_DESTROY;
[416]1523    rpc.blocking = true;
[438]1524    rpc.responses = 1;
[23]1525
1526    // set input arguments in RPC descriptor
1527    rpc.args[0] = (uint64_t)(intptr_t)file;
1528   
[436]1529    // register RPC request in remote RPC fifo
[416]1530    rpc_send( cxy , &rpc );
[279]1531
[440]1532#if DEBUG_RPC_VFS_FILE_DESTROY
1533cycle = (uint32_t)hal_get_cycles();
1534if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]1535printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1536__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1537#endif
[23]1538}
1539
1540/////////////////////////////////////////////
1541void rpc_vfs_file_destroy_server( xptr_t xp )
1542{
[440]1543#if DEBUG_RPC_VFS_FILE_DESTROY
[564]1544thread_t * this = CURRENT_THREAD;
[440]1545uint32_t cycle = (uint32_t)hal_get_cycles();
1546if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]1547printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1548__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1549#endif
1550
[23]1551    vfs_file_t * file;
1552
1553    // get client cluster identifier and pointer on RPC descriptor
[436]1554    cxy_t        client_cxy  = GET_CXY( xp );
1555    rpc_desc_t * desc        = GET_PTR( xp );
[23]1556
1557    // get arguments "dentry" from client RPC descriptor
[564]1558    file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[23]1559                       
1560    // call local kernel function
1561    vfs_file_destroy( file );
[296]1562
[440]1563#if DEBUG_RPC_VFS_FILE_DESTROY
1564cycle = (uint32_t)hal_get_cycles();
1565if( cycle > DEBUG_RPC_VFS_FILE_DESTROY )
[601]1566printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1567__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
[440]1568#endif
[23]1569}
1570
1571/////////////////////////////////////////////////////////////////////////////////////////
[612]1572// [16]      Marshaling functions attached to RPC_VFS_FS_GET_DENTRY  (blocking)
[23]1573/////////////////////////////////////////////////////////////////////////////////////////
1574
[601]1575/////////////////////////////////////////////////////////
[612]1576void rpc_vfs_fs_get_dentry_client( cxy_t         cxy,
[601]1577                                   vfs_inode_t * parent_inode,    // in
1578                                   char        * name,            // in
1579                                   xptr_t        child_inode_xp,  // in
1580                                   error_t     * error )          // out
[238]1581{
[612]1582#if DEBUG_RPC_VFS_FS_GET_DENTRY
[601]1583thread_t * this = CURRENT_THREAD;
1584uint32_t cycle = (uint32_t)hal_get_cycles();
[612]1585if( cycle > DEBUG_RPC_VFS_FS_GET_DENTRY )
[601]1586printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1587__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1588#endif
1589
[611]1590    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[238]1591
1592    // initialise RPC descriptor header
1593    rpc_desc_t  rpc;
[612]1594    rpc.index    = RPC_VFS_FS_GET_DENTRY;
[416]1595    rpc.blocking = true;
[438]1596    rpc.responses = 1;
[238]1597
1598    // set input arguments in RPC descriptor
1599    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
1600    rpc.args[1] = (uint64_t)(intptr_t)name;
1601    rpc.args[2] = (uint64_t)child_inode_xp;
1602
[436]1603    // register RPC request in remote RPC fifo
[416]1604    rpc_send( cxy , &rpc );
[238]1605
1606    // get output values from RPC descriptor
1607    *error   = (error_t)rpc.args[3];
[279]1608
[612]1609#if DEBUG_RPC_VFS_FS_GET_DENTRY
[601]1610cycle = (uint32_t)hal_get_cycles();
[612]1611if( cycle > DEBUG_RPC_VFS_FS_GET_DENTRY )
[601]1612printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1613__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1614#endif
[238]1615}
1616
[601]1617//////////////////////////////////////////////
[612]1618void rpc_vfs_fs_get_dentry_server( xptr_t xp )
[238]1619{
[612]1620#if DEBUG_RPC_VFS_FS_GET_DENTRY
[601]1621thread_t * this = CURRENT_THREAD;
1622uint32_t cycle = (uint32_t)hal_get_cycles();
[612]1623if( cycle > DEBUG_RPC_VFS_FS_GET_DENTRY )
[601]1624printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1625__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1626#endif
1627
[238]1628    error_t       error;
1629    vfs_inode_t * parent;
1630    xptr_t        child_xp;
1631    char        * name;
1632
1633    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
1634
1635    // get client cluster identifier and pointer on RPC descriptor
[436]1636    cxy_t        client_cxy  = GET_CXY( xp );
1637    rpc_desc_t * desc        = GET_PTR( xp );
[238]1638
1639    // get arguments "parent", "name", and "child_xp"
[564]1640    parent     = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1641    name       = (char*)(intptr_t)       hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
1642    child_xp   = (xptr_t)                hal_remote_l64(XPTR(client_cxy , &desc->args[2]));
[238]1643
1644    // get name local copy
1645    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
1646                       XPTR( client_cxy , name ) );
1647
1648    // call the kernel function
[612]1649    error = vfs_fs_get_dentry( parent , name_copy , child_xp );
[238]1650
1651    // set output argument
[564]1652    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1653
[612]1654#if DEBUG_RPC_VFS_FS_GET_DENTRY
[601]1655cycle = (uint32_t)hal_get_cycles();
[612]1656if( cycle > DEBUG_RPC_VFS_FS_GET_DENTRY )
[601]1657printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1658__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1659#endif
[238]1660}
1661
1662/////////////////////////////////////////////////////////////////////////////////////////
[601]1663// [17]      Marshaling function attached to RPC_VFS_FS_ADD_DENTRY  (blocking)
[238]1664/////////////////////////////////////////////////////////////////////////////////////////
1665
[601]1666void rpc_vfs_fs_add_dentry_client( cxy_t          cxy,
1667                                   vfs_inode_t  * parent,     // in
1668                                   vfs_dentry_t * dentry,     // in
1669                                   error_t      * error )     // out
[238]1670{
[601]1671#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1672thread_t * this = CURRENT_THREAD;
1673uint32_t cycle = (uint32_t)hal_get_cycles();
1674if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1675printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1676__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1677#endif
1678
[611]1679    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[238]1680
1681    // initialise RPC descriptor header
1682    rpc_desc_t  rpc;
[601]1683    rpc.index    = RPC_VFS_FS_ADD_DENTRY;
[416]1684    rpc.blocking = true;
[438]1685    rpc.responses = 1;
[238]1686
1687    // set input arguments in RPC descriptor
[601]1688    rpc.args[0] = (uint64_t)(intptr_t)parent;
1689    rpc.args[1] = (uint64_t)(intptr_t)dentry;
[238]1690
[436]1691    // register RPC request in remote RPC fifo
[416]1692    rpc_send( cxy , &rpc );
[238]1693
1694    // get output values from RPC descriptor
[601]1695    *error   = (error_t)rpc.args[2];
[279]1696
[601]1697#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1698cycle = (uint32_t)hal_get_cycles();
1699if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1700printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1701__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1702#endif
[238]1703}
1704
[601]1705/////////////////////////////////////////////////
1706void rpc_vfs_fs_add_dentry_server( xptr_t xp )
[238]1707{
[601]1708#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1709thread_t * this = CURRENT_THREAD;
1710uint32_t cycle = (uint32_t)hal_get_cycles();
1711if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1712printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1713__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1714#endif
[238]1715
[601]1716    error_t        error;
1717    vfs_inode_t  * parent;
1718    vfs_dentry_t * dentry;
1719
[238]1720    // get client cluster identifier and pointer on RPC descriptor
[436]1721    cxy_t        client_cxy  = GET_CXY( xp );
1722    rpc_desc_t * desc        = GET_PTR( xp );
[238]1723
[601]1724    // get input arguments
1725    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1726    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[238]1727
1728    // call the kernel function
[601]1729    error = vfs_fs_add_dentry( parent , dentry );
[238]1730
1731    // set output argument
[601]1732    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
[296]1733
[601]1734#if DEBUG_RPC_VFS_FS_ADD_DENTRY
1735cycle = (uint32_t)hal_get_cycles();
1736if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY )
1737printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1738__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1739#endif
[238]1740}
1741
1742/////////////////////////////////////////////////////////////////////////////////////////
[601]1743// [18]      Marshaling function attached to RPC_VFS_FS_REMOVE_DENTRY  (blocking)
[238]1744/////////////////////////////////////////////////////////////////////////////////////////
1745
[601]1746void rpc_vfs_fs_remove_dentry_client( cxy_t          cxy,
1747                                      vfs_inode_t  * parent,     // in
1748                                      vfs_dentry_t * dentry,     // in
1749                                      error_t      * error )     // out
[23]1750{
[601]1751#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1752thread_t * this = CURRENT_THREAD;
1753uint32_t cycle = (uint32_t)hal_get_cycles();
1754if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1755printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1756__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1757#endif
1758
[611]1759    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[23]1760
1761    // initialise RPC descriptor header
1762    rpc_desc_t  rpc;
[601]1763    rpc.index    = RPC_VFS_FS_REMOVE_DENTRY;
[416]1764    rpc.blocking = true;
[438]1765    rpc.responses = 1;
[23]1766
1767    // set input arguments in RPC descriptor
[601]1768    rpc.args[0] = (uint64_t)(intptr_t)parent;
1769    rpc.args[1] = (uint64_t)(intptr_t)dentry;
[23]1770
[601]1771    // register RPC request in remote RPC fifo
[416]1772    rpc_send( cxy , &rpc );
[23]1773
[601]1774    // get output values from RPC descriptor
1775    *error   = (error_t)rpc.args[2];
[279]1776
[601]1777#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1778cycle = (uint32_t)hal_get_cycles();
1779if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1780printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1781__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1782#endif
[23]1783}
1784
[601]1785/////////////////////////////////////////////////
1786void rpc_vfs_fs_remove_dentry_server( xptr_t xp )
[23]1787{
[601]1788#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1789thread_t * this = CURRENT_THREAD;
1790uint32_t cycle = (uint32_t)hal_get_cycles();
1791if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1792printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1793__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1794#endif
[23]1795
[601]1796    error_t        error;
1797    vfs_inode_t  * parent;
1798    vfs_dentry_t * dentry;
1799
[23]1800    // get client cluster identifier and pointer on RPC descriptor
[436]1801    cxy_t        client_cxy  = GET_CXY( xp );
[438]1802    rpc_desc_t * desc        = GET_PTR( xp );
[23]1803
1804    // get input arguments
[601]1805    parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1806    dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1]));
[23]1807
1808    // call the kernel function
[601]1809    error = vfs_fs_remove_dentry( parent , dentry );
[23]1810
1811    // set output argument
[601]1812    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error );
[296]1813
[601]1814#if DEBUG_RPC_VFS_FS_REMOVE_DENTRY
1815cycle = (uint32_t)hal_get_cycles();
1816if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY )
1817printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1818__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1819#endif
[23]1820}
1821
1822/////////////////////////////////////////////////////////////////////////////////////////
[601]1823// [19]     Marshaling functions attached to RPC_VFS_INODE_LOAD_ALL_PAGES  (blocking)
1824/////////////////////////////////////////////////////////////////////////////////////////
1825
1826////////////////////////////////////////////////////////////
1827void rpc_vfs_inode_load_all_pages_client( cxy_t         cxy,
1828                                          vfs_inode_t * inode,      // in
1829                                          error_t     * error )     // out
1830{
1831#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
1832thread_t * this = CURRENT_THREAD;
1833uint32_t cycle = (uint32_t)hal_get_cycles();
1834if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
1835printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1836__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1837#endif
1838
[611]1839    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[601]1840
1841    // initialise RPC descriptor header
1842    rpc_desc_t  rpc;
1843    rpc.index    = RPC_VFS_INODE_LOAD_ALL_PAGES;
1844    rpc.blocking = true;
1845    rpc.responses = 1;
1846
1847    // set input arguments in RPC descriptor
1848    rpc.args[0] = (uint64_t)(intptr_t)inode;
1849
1850    // register RPC request in remote RPC fifo
1851    rpc_send( cxy , &rpc );
1852
1853    // get output values from RPC descriptor
1854    *error   = (error_t)rpc.args[1];
1855
1856#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
1857cycle = (uint32_t)hal_get_cycles();
1858if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
1859printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1860__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1861#endif
1862}
1863
1864/////////////////////////////////////////////////////
1865void rpc_vfs_inode_load_all_pages_server( xptr_t xp )
1866{
1867#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
1868thread_t * this = CURRENT_THREAD;
1869uint32_t cycle = (uint32_t)hal_get_cycles();
1870if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
1871printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1872__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1873#endif
1874
1875    error_t       error;
1876    vfs_inode_t * inode;
1877
1878    // get client cluster identifier and pointer on RPC descriptor
1879    cxy_t        client_cxy  = GET_CXY( xp );
1880    rpc_desc_t * desc        = GET_PTR( xp );
1881
1882    // get input argument
1883    inode = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0]));
1884
1885    // call the kernel function
1886    error = vfs_inode_load_all_pages( inode );
1887
1888    // set output argument
1889    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error );
1890
1891#if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES
1892cycle = (uint32_t)hal_get_cycles();
1893if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES )
1894printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1895__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
1896#endif
1897}
1898
1899/////////////////////////////////////////////////////////////////////////////////////////
[409]1900// [20]          Marshaling functions attached to RPC_VMM_GET_VSEG  (blocking)
[23]1901/////////////////////////////////////////////////////////////////////////////////////////
1902
1903//////////////////////////////////////////////////
[389]1904void rpc_vmm_get_vseg_client( cxy_t       cxy,     
1905                              process_t * process,     // in 
1906                              intptr_t    vaddr,       // in 
1907                              xptr_t    * vseg_xp,     // out
1908                              error_t   * error )      // out
[1]1909{
[440]1910#if DEBUG_RPC_VMM_GET_VSEG
[564]1911thread_t * this = CURRENT_THREAD;
[440]1912uint32_t cycle = (uint32_t)hal_get_cycles();
1913if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]1914printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1915__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1916#endif
1917
[611]1918    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]1919
1920    // initialise RPC descriptor header
1921    rpc_desc_t  rpc;
[389]1922    rpc.index    = RPC_VMM_GET_VSEG;
[416]1923    rpc.blocking = true;
[438]1924    rpc.responses = 1;
[1]1925
1926    // set input arguments in RPC descriptor
1927    rpc.args[0] = (uint64_t)(intptr_t)process;
1928    rpc.args[1] = (uint64_t)vaddr;
1929
[436]1930    // register RPC request in remote RPC fifo
[416]1931    rpc_send( cxy , &rpc );
[1]1932
1933    // get output argument from rpc descriptor
1934    *vseg_xp = rpc.args[2];
[389]1935    *error   = (error_t)rpc.args[3];
[279]1936
[440]1937#if DEBUG_RPC_VMM_GET_VSEG
1938cycle = (uint32_t)hal_get_cycles();
1939if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]1940printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1941__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1942#endif
[1]1943}
1944
[389]1945/////////////////////////////////////////
1946void rpc_vmm_get_vseg_server( xptr_t xp )
[1]1947{
[440]1948#if DEBUG_RPC_VMM_GET_VSEG
[564]1949thread_t * this = CURRENT_THREAD;
[440]1950uint32_t cycle = (uint32_t)hal_get_cycles();
1951if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]1952printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
1953__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1954#endif
1955
[1]1956    process_t   * process;
1957    intptr_t      vaddr;
1958    vseg_t      * vseg_ptr;
1959    xptr_t        vseg_xp;
[389]1960    error_t       error;
[1]1961
1962    // get client cluster identifier and pointer on RPC descriptor
[436]1963    cxy_t        client_cxy  = GET_CXY( xp );
1964    rpc_desc_t * desc        = GET_PTR( xp );
[1]1965
1966    // get input argument from client RPC descriptor
[564]1967    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
1968    vaddr   = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[1]1969   
1970    // call local kernel function
[389]1971    error = vmm_get_vseg( process , vaddr , &vseg_ptr );
[1]1972
[389]1973    // set output arguments to client RPC descriptor
1974    vseg_xp = XPTR( local_cxy , vseg_ptr );
[564]1975    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp );
1976    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[296]1977
[440]1978#if DEBUG_RPC_VMM_GET_VSEG
1979cycle = (uint32_t)hal_get_cycles();
1980if( cycle > DEBUG_RPC_VMM_GET_VSEG )
[601]1981printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
1982__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]1983#endif
[1]1984}
1985
1986
1987/////////////////////////////////////////////////////////////////////////////////////////
[583]1988// [21]    Marshaling functions attached to RPC_VMM_GLOBAL_UPDATE_PTE  (blocking)
[1]1989/////////////////////////////////////////////////////////////////////////////////////////
1990
[583]1991///////////////////////////////////////////////////////
1992void rpc_vmm_global_update_pte_client( cxy_t       cxy,   
1993                                       process_t * process,  // in
1994                                       vpn_t       vpn,      // in
1995                                       uint32_t    attr,     // in
1996                                       ppn_t       ppn )     // in
[1]1997{
[583]1998#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
[564]1999thread_t * this = CURRENT_THREAD;
[440]2000uint32_t cycle = (uint32_t)hal_get_cycles();
[583]2001if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
[601]2002printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2003__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2004#endif
2005
[611]2006    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]2007
2008    // initialise RPC descriptor header
2009    rpc_desc_t  rpc;
[583]2010    rpc.index    = RPC_VMM_GLOBAL_UPDATE_PTE;
[416]2011    rpc.blocking = true;
[438]2012    rpc.responses = 1;
[1]2013
2014    // set input arguments in RPC descriptor
2015    rpc.args[0] = (uint64_t)(intptr_t)process;
2016    rpc.args[1] = (uint64_t)vpn;
[583]2017    rpc.args[2] = (uint64_t)attr;
2018    rpc.args[3] = (uint64_t)ppn;
[1]2019
[436]2020    // register RPC request in remote RPC fifo
[416]2021    rpc_send( cxy , &rpc );
[1]2022
[583]2023#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
[440]2024cycle = (uint32_t)hal_get_cycles();
[583]2025if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
[601]2026printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2027__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2028#endif
[1]2029}
2030
[583]2031//////////////////////////////////////////////////
2032void rpc_vmm_global_update_pte_server( xptr_t xp )
[1]2033{
[583]2034#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
[564]2035thread_t * this = CURRENT_THREAD;
[440]2036uint32_t cycle = (uint32_t)hal_get_cycles();
[583]2037if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
[601]2038printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2039__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2040#endif
2041
[1]2042    process_t   * process;
2043    vpn_t         vpn;
2044    uint32_t      attr;
2045    ppn_t         ppn;
2046
2047    // get client cluster identifier and pointer on RPC descriptor
[436]2048    cxy_t        client_cxy  = GET_CXY( xp );
2049    rpc_desc_t * desc        = GET_PTR( xp );
[1]2050
2051    // get input argument "process" & "vpn" from client RPC descriptor
[564]2052    process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2053    vpn     = (vpn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[583]2054    attr    = (uint32_t)             hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) );
2055    ppn     = (ppn_t)                hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) );
[1]2056   
2057    // call local kernel function
[583]2058    vmm_global_update_pte( process , vpn , attr , ppn ); 
[1]2059
[583]2060#if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE
[440]2061cycle = (uint32_t)hal_get_cycles();
[583]2062if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE )
[601]2063printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2064__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[440]2065#endif
[1]2066}
2067
2068/////////////////////////////////////////////////////////////////////////////////////////
[409]2069// [22]          Marshaling functions attached to RPC_KCM_ALLOC  (blocking)
[1]2070/////////////////////////////////////////////////////////////////////////////////////////
2071
[23]2072//////////////////////////////////////////
2073void rpc_kcm_alloc_client( cxy_t      cxy,
2074                           uint32_t   kmem_type,   // in
2075                           xptr_t *   buf_xp )     // out
[1]2076{
[564]2077#if DEBUG_RPC_KCM_ALLOC
2078thread_t * this = CURRENT_THREAD;
2079uint32_t cycle = (uint32_t)hal_get_cycles();
2080if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2081printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2082__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2083#endif
2084
[611]2085    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]2086
2087    // initialise RPC descriptor header
2088    rpc_desc_t  rpc;
[441]2089    rpc.index    = RPC_KCM_ALLOC;
[416]2090    rpc.blocking = true;
[438]2091    rpc.responses = 1;
[1]2092
[23]2093    // set input arguments in RPC descriptor
2094    rpc.args[0] = (uint64_t)kmem_type;
2095
[436]2096    // register RPC request in remote RPC fifo
[416]2097    rpc_send( cxy , &rpc );
[1]2098
2099    // get output arguments from RPC descriptor
[23]2100    *buf_xp = (xptr_t)rpc.args[1];
[279]2101
[564]2102#if DEBUG_RPC_KCM_ALLOC
2103cycle = (uint32_t)hal_get_cycles();
2104if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2105printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2106__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2107#endif
[1]2108}
2109
[23]2110//////////////////////////////////////
2111void rpc_kcm_alloc_server( xptr_t xp )
[1]2112{
[564]2113#if DEBUG_RPC_KCM_ALLOC
2114thread_t * this = CURRENT_THREAD;
2115uint32_t cycle = (uint32_t)hal_get_cycles();
2116if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2117printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2118__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2119#endif
2120
[1]2121    // get client cluster identifier and pointer on RPC descriptor
[436]2122    cxy_t        client_cxy  = GET_CXY( xp );
[438]2123    rpc_desc_t * desc        = GET_PTR( xp );
[1]2124
[23]2125    // get input argument "kmem_type" from client RPC descriptor
[564]2126    uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
[23]2127
2128    // allocates memory for kcm
[1]2129    kmem_req_t  req;
[23]2130    req.type  = kmem_type;
[1]2131    req.flags = AF_ZERO;
[23]2132    void * buf_ptr = kmem_alloc( &req );
[1]2133
2134    // set output argument
[23]2135    xptr_t buf_xp = XPTR( local_cxy , buf_ptr );
[564]2136    hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp );
[296]2137
[564]2138#if DEBUG_RPC_KCM_ALLOC
2139cycle = (uint32_t)hal_get_cycles();
2140if( cycle > DEBUG_RPC_KCM_ALLOC )
[601]2141printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2142__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2143#endif
[1]2144}   
2145
2146/////////////////////////////////////////////////////////////////////////////////////////
[409]2147// [23]          Marshaling functions attached to RPC_KCM_FREE  (blocking)
[1]2148/////////////////////////////////////////////////////////////////////////////////////////
2149
[23]2150/////////////////////////////////////////
2151void rpc_kcm_free_client( cxy_t      cxy,
2152                          void     * buf,          // in
2153                          uint32_t   kmem_type )   // in
[1]2154{
[564]2155#if DEBUG_RPC_KCM_FREE
2156thread_t * this = CURRENT_THREAD;
2157uint32_t cycle = (uint32_t)hal_get_cycles();
2158if( cycle > DEBUG_RPC_KCM_FREE )
[601]2159printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2160__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2161#endif
2162
[611]2163    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[1]2164
2165    // initialise RPC descriptor header
2166    rpc_desc_t  rpc;
[441]2167    rpc.index    = RPC_KCM_FREE;
[416]2168    rpc.blocking = true;
[438]2169    rpc.responses = 1;
[1]2170
2171    // set input arguments in RPC descriptor
[23]2172    rpc.args[0] = (uint64_t)(intptr_t)buf;
2173    rpc.args[1] = (uint64_t)kmem_type;
[1]2174
[436]2175    // register RPC request in remote RPC fifo
[416]2176    rpc_send( cxy , &rpc );
[279]2177
[564]2178#if DEBUG_RPC_KCM_FREE
2179cycle = (uint32_t)hal_get_cycles();
2180if( cycle > DEBUG_RPC_KCM_FREE )
[601]2181printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2182__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2183#endif
[1]2184}
2185
[23]2186/////////////////////////////////////
2187void rpc_kcm_free_server( xptr_t xp )
[1]2188{
[564]2189#if DEBUG_RPC_KCM_FREE
2190thread_t * this = CURRENT_THREAD;
2191uint32_t cycle = (uint32_t)hal_get_cycles();
2192if( cycle > DEBUG_RPC_KCM_FREE )
[601]2193printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2194__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2195#endif
2196
[1]2197    // get client cluster identifier and pointer on RPC descriptor
[436]2198    cxy_t        client_cxy  = GET_CXY( xp );
[438]2199    rpc_desc_t * desc        = GET_PTR( xp );
[1]2200
[23]2201    // get input arguments "buf" and "kmem_type" from client RPC descriptor
[564]2202    void     * buf = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2203    uint32_t   kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[1]2204
2205    // releases memory
2206    kmem_req_t  req;
[23]2207    req.type = kmem_type;
2208    req.ptr  = buf;
2209    kmem_free( &req );
[296]2210
[564]2211#if DEBUG_RPC_KCM_FREE
2212cycle = (uint32_t)hal_get_cycles();
2213if( cycle > DEBUG_RPC_KCM_FREE )
[601]2214printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2215__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
[564]2216#endif
[1]2217}   
2218
2219/////////////////////////////////////////////////////////////////////////////////////////
[610]2220// [24]          undefined slot
[1]2221/////////////////////////////////////////////////////////////////////////////////////////
2222
[313]2223/////////////////////////////////////////////////////////////////////////////////////////
[601]2224// [25]          Marshaling functions attached to RPC_MAPPER_HANDLE_MISS (blocking)
[313]2225/////////////////////////////////////////////////////////////////////////////////////////
2226
[601]2227//////////////////////////////////////////////////////////
2228void rpc_mapper_handle_miss_client( cxy_t             cxy,
2229                                    struct mapper_s * mapper,
2230                                    uint32_t          page_id,
2231                                    xptr_t          * page_xp,
2232                                    error_t         * error )
[313]2233{
[601]2234#if DEBUG_RPC_MAPPER_HANDLE_MISS
[611]2235thread_t * this = CURRENT_THREAD;
[601]2236uint32_t cycle = (uint32_t)hal_get_cycles();
2237if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2238printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2239__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2240#endif
2241
[611]2242    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[313]2243
2244    // initialise RPC descriptor header
2245    rpc_desc_t  rpc;
[601]2246    rpc.index    = RPC_MAPPER_HANDLE_MISS;
[416]2247    rpc.blocking = true;
[438]2248    rpc.responses = 1;
[313]2249
2250    // set input arguments in RPC descriptor
2251    rpc.args[0] = (uint64_t)(intptr_t)mapper;
[601]2252    rpc.args[1] = (uint64_t)page_id;
[313]2253
[436]2254    // register RPC request in remote RPC fifo
[416]2255    rpc_send( cxy , &rpc );
[313]2256
2257    // get output values from RPC descriptor
[601]2258    *page_xp = (xptr_t)rpc.args[2];
2259    *error   = (error_t)rpc.args[3];
[313]2260
[601]2261#if DEBUG_RPC_MAPPER_HANDLE_MISS
2262cycle = (uint32_t)hal_get_cycles();
2263if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2264printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2265__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2266#endif
[313]2267}
2268
[601]2269///////////////////////////////////////////////
2270void rpc_mapper_handle_miss_server( xptr_t xp )
[313]2271{
[601]2272#if DEBUG_RPC_MAPPER_HANDLE_MISS
[611]2273thread_t * this = CURRENT_THREAD;
[601]2274uint32_t cycle = (uint32_t)hal_get_cycles();
2275if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2276printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2277__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2278#endif
2279
2280    mapper_t * mapper;
2281    uint32_t   page_id;
2282    xptr_t     page_xp;
2283    error_t    error;
2284
[313]2285    // get client cluster identifier and pointer on RPC descriptor
[601]2286    cxy_t        client_cxy  = GET_CXY( xp );
2287    rpc_desc_t * desc        = GET_PTR( xp );
[313]2288
[601]2289    // get arguments from client RPC descriptor
2290    mapper  = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) );
2291    page_id =                       hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) );
[313]2292
[601]2293    // call local kernel function
2294    error = mapper_handle_miss( mapper,
2295                                page_id,
2296                                &page_xp );
[313]2297
[601]2298    // set output argument to client RPC descriptor
[610]2299    hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)page_xp );
2300    hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
[601]2301
2302#if DEBUG_RPC_MAPPER_HANDLE_MISS
2303cycle = (uint32_t)hal_get_cycles();
2304if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS )
2305printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2306__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2307#endif
[313]2308}
2309
[407]2310/////////////////////////////////////////////////////////////////////////////////////////
[611]2311// [26]  Marshaling functions attached to RPC_VMM_DELETE_VSEG (parallel / non blocking)
[407]2312/////////////////////////////////////////////////////////////////////////////////////////
[313]2313
[611]2314//////////////////////////////////////////////////
2315void rpc_vmm_delete_vseg_client( cxy_t        cxy,
2316                                 rpc_desc_t * rpc )
2317{
2318#if DEBUG_RPC_VMM_DELETE_VSEG
2319thread_t * this  = CURRENT_THREAD;
2320uint32_t   cycle = (uint32_t)hal_get_cycles();
2321if( cycle > DEBUG_RPC_VMM_DELETE_VSEG )
2322printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2323__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2324#endif
2325
2326// check RPC "index" and "blocking" arguments
2327assert( (rpc->blocking == false) , "must be non-blocking\n");
2328assert( (rpc->index == RPC_VMM_DELETE_VSEG ) , "bad RPC index\n" );
2329
2330    // register RPC request in remote RPC fifo
2331    rpc_send( cxy , rpc );
2332
2333#if DEBUG_RPC_VMM_DELETE_VSEG
2334cycle = (uint32_t)hal_get_cycles();
2335if( cycle > DEBUG_RPC_VMM_DELETE_VSEG )
2336printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2337__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2338#endif
2339}
2340
2341////////////////////////////////////////////
2342void rpc_vmm_delete_vseg_server( xptr_t xp )
2343{
2344#if DEBUG_RPC_VMM_DELETE_VSEG
2345uint32_t cycle = (uint32_t)hal_get_cycles();
2346thread_t * this = CURRENT_THREAD;
2347if( DEBUG_RPC_VMM_DELETE_VSEG < cycle )
2348printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2349__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2350#endif
2351
2352    // get client cluster identifier and pointer on RPC descriptor
2353    cxy_t        client_cxy = GET_CXY( xp );
2354    rpc_desc_t * desc       = GET_PTR( xp );
2355
2356    // get arguments from RPC descriptor
2357    pid_t    pid   = (pid_t)   hal_remote_l64( XPTR(client_cxy , &desc->args[0]) );
2358    intptr_t vaddr = (intptr_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) );
2359
2360    // call relevant kernel function
2361    vmm_delete_vseg( pid , vaddr );
2362
2363#if DEBUG_RPC_VMM_DELETE_VSEG
2364cycle = (uint32_t)hal_get_cycles();
2365if( DEBUG_RPC_VMM_DELETE_VSEG < cycle )
2366printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2367__FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle );
2368#endif
2369} 
2370
[601]2371/////////////////////////////////////////////////////////////////////////////////////////
2372// [27]          Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking)
2373/////////////////////////////////////////////////////////////////////////////////////////
2374
[407]2375////////////////////////////////////////////////////////
2376void rpc_vmm_create_vseg_client( cxy_t              cxy,
2377                                 struct process_s * process,
2378                                 vseg_type_t        type,
2379                                 intptr_t           base,
2380                                 uint32_t           size,
2381                                 uint32_t           file_offset,
2382                                 uint32_t           file_size,
2383                                 xptr_t             mapper_xp,
2384                                 cxy_t              vseg_cxy,
2385                                 struct vseg_s   ** vseg )
2386{
[611]2387#if DEBUG_RPC_VMM_CREATE_VSEG
2388thread_t * this = CURRENT_THREAD;
2389uint32_t cycle = (uint32_t)hal_get_cycles();
2390if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2391printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2392__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2393#endif
[407]2394
[611]2395    assert( (cxy != local_cxy) , "server cluster is not remote\n");
2396
[407]2397    // initialise RPC descriptor header
2398    rpc_desc_t  rpc;
2399    rpc.index    = RPC_VMM_CREATE_VSEG;
[416]2400    rpc.blocking = true;
[438]2401    rpc.responses = 1;
[407]2402
2403    // set input arguments in RPC descriptor
2404    rpc.args[0] = (uint64_t)(intptr_t)process;
2405    rpc.args[1] = (uint64_t)type;
2406    rpc.args[2] = (uint64_t)base;
2407    rpc.args[3] = (uint64_t)size;
2408    rpc.args[4] = (uint64_t)file_offset;
2409    rpc.args[5] = (uint64_t)file_size;
2410    rpc.args[6] = (uint64_t)mapper_xp;
2411    rpc.args[7] = (uint64_t)vseg_cxy;
2412
[436]2413    // register RPC request in remote RPC fifo
[416]2414    rpc_send( cxy , &rpc );
[407]2415
2416    // get output values from RPC descriptor
2417    *vseg = (vseg_t *)(intptr_t)rpc.args[8];
2418
[611]2419#if DEBUG_RPC_VMM_CREATE_VSEG
2420cycle = (uint32_t)hal_get_cycles();
2421if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2422printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2423__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2424#endif
[407]2425}
2426
2427////////////////////////////////////////////
2428void rpc_vmm_create_vseg_server( xptr_t xp )
2429{
[611]2430#if DEBUG_RPC_VMM_CREATE_VSEG
2431thread_t * this = CURRENT_THREAD;
2432uint32_t cycle = (uint32_t)hal_get_cycles();
2433if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2434printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n",
2435__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2436#endif
2437
[407]2438    // get client cluster identifier and pointer on RPC descriptor
[436]2439    cxy_t        cxy  = GET_CXY( xp );
2440    rpc_desc_t * desc = GET_PTR( xp );
[407]2441
2442    // get input arguments from client RPC descriptor
[564]2443    process_t * process     = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2444    vseg_type_t type        = (vseg_type_t)(uint32_t)hal_remote_l64( XPTR(cxy , &desc->args[1]));
2445    intptr_t    base        = (intptr_t)             hal_remote_l64( XPTR(cxy , &desc->args[2]));
2446    uint32_t    size        = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[3]));
2447    uint32_t    file_offset = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[4]));
2448    uint32_t    file_size   = (uint32_t)             hal_remote_l64( XPTR(cxy , &desc->args[5]));
2449    xptr_t      mapper_xp   = (xptr_t)               hal_remote_l64( XPTR(cxy , &desc->args[6]));
2450    cxy_t       vseg_cxy    = (cxy_t)(uint32_t)      hal_remote_l64( XPTR(cxy , &desc->args[7]));
[407]2451   
2452    // call local kernel function
2453    vseg_t * vseg = vmm_create_vseg( process,
2454                                     type,
2455                                     base,
2456                                     size,
2457                                     file_offset,
2458                                     file_size,
2459                                     mapper_xp,
2460                                     vseg_cxy ); 
2461
2462    // set output arguments into client RPC descriptor
[564]2463    hal_remote_s64( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg );
[407]2464
[611]2465#if DEBUG_RPC_VMM_CREATE_VSEG
2466cycle = (uint32_t)hal_get_cycles();
2467if( cycle > DEBUG_RPC_VMM_CREATE_VSEG )
2468printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n",
2469__FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle );
2470#endif
[407]2471}
2472
2473/////////////////////////////////////////////////////////////////////////////////////////
[409]2474// [28]          Marshaling functions attached to RPC_VMM_SET_COW (blocking)
[408]2475/////////////////////////////////////////////////////////////////////////////////////////
2476
2477/////////////////////////////////////////////
2478void rpc_vmm_set_cow_client( cxy_t       cxy,
2479                             process_t * process )
2480{
[611]2481    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[408]2482
2483    // initialise RPC descriptor header
2484    rpc_desc_t  rpc;
2485    rpc.index    = RPC_VMM_SET_COW;
[416]2486    rpc.blocking = true;
[438]2487    rpc.responses = 1;
[408]2488
2489    // set input arguments in RPC descriptor
2490    rpc.args[0] = (uint64_t)(intptr_t)process;
2491
[436]2492    // register RPC request in remote RPC fifo
[416]2493    rpc_send( cxy , &rpc );
[408]2494
2495}
2496
2497////////////////////////////////////////
2498void rpc_vmm_set_cow_server( xptr_t xp )
2499{
2500    process_t * process;
2501
2502    // get client cluster identifier and pointer on RPC descriptor
[436]2503    cxy_t        cxy  = GET_CXY( xp );
2504    rpc_desc_t * desc = GET_PTR( xp );
[408]2505
2506    // get input arguments from client RPC descriptor
[564]2507    process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
[408]2508   
2509    // call local kernel function
2510    vmm_set_cow( process );
2511
2512}
2513
[428]2514/////////////////////////////////////////////////////////////////////////////////////////
2515// [29]          Marshaling functions attached to RPC_VMM_DISPLAY (blocking)
2516/////////////////////////////////////////////////////////////////////////////////////////
[1]2517
[428]2518/////////////////////////////////////////////
2519void rpc_vmm_display_client( cxy_t       cxy,
2520                             process_t * process,
2521                             bool_t      detailed )
2522{
[611]2523    assert( (cxy != local_cxy) , "server cluster is not remote\n");
[428]2524
2525    // initialise RPC descriptor header
2526    rpc_desc_t  rpc;
2527    rpc.index    = RPC_VMM_DISPLAY;
2528    rpc.blocking = true;
[438]2529    rpc.responses = 1;
[428]2530
2531    // set input arguments in RPC descriptor
2532    rpc.args[0] = (uint64_t)(intptr_t)process;
2533    rpc.args[1] = (uint64_t)detailed;
2534
[436]2535    // register RPC request in remote RPC fifo
[428]2536    rpc_send( cxy , &rpc );
2537
2538}
2539
2540////////////////////////////////////////
2541void rpc_vmm_display_server( xptr_t xp )
2542{
2543    process_t * process;
2544    bool_t      detailed;
2545
2546    // get client cluster identifier and pointer on RPC descriptor
[436]2547    cxy_t        cxy  = GET_CXY( xp );
2548    rpc_desc_t * desc = GET_PTR( xp );
[428]2549
2550    // get input arguments from client RPC descriptor
[564]2551    process  = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0]));
2552    detailed = (bool_t)               hal_remote_l64( XPTR(cxy , &desc->args[1]));
[428]2553   
2554    // call local kernel function
2555    vmm_display( process , detailed );
2556
2557}
2558
2559
Note: See TracBrowser for help on using the repository browser.