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

Last change on this file since 569 was 564, checked in by alain, 6 years ago

Complete restructuration of kernel locks.

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