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

Last change on this file since 593 was 591, checked in by alain, 6 years ago

Fix a bug in rpc_process_sigaction_server().

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