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

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

Remove the "giant" rwlock protecting the GPT, and
use the GPT_LOCKED attribute in each PTE to prevent
concurrent modifications of one GPT entry.
The version number has been incremented to 2.1.

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
[629]106    "VFS_FS_NEW_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{
[628]1737#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]1738thread_t * this = CURRENT_THREAD;
1739uint32_t cycle = (uint32_t)hal_get_cycles();
[628]1740if( cycle > DEBUG_RPC_VFS_FS_NEW_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;
[628]1749    rpc.index    = RPC_VFS_FS_NEW_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
[628]1764#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]1765cycle = (uint32_t)hal_get_cycles();
[628]1766if( cycle > DEBUG_RPC_VFS_FS_NEW_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{
[628]1775#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]1776thread_t * this = CURRENT_THREAD;
1777uint32_t cycle = (uint32_t)hal_get_cycles();
[628]1778if( cycle > DEBUG_RPC_VFS_FS_NEW_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
[628]1809#if DEBUG_RPC_VFS_FS_NEW_DENTRY
[601]1810cycle = (uint32_t)hal_get_cycles();
[628]1811if( cycle > DEBUG_RPC_VFS_FS_NEW_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.