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

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

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

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