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

Last change on this file since 627 was 625, checked in by alain, 6 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

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