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

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

Introduce sigificant modifs in VFS to support the <ls> command,
and the . and .. directories entries.

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