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

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

This version is a major evolution: The physical memory allocators,
defined in the kmem.c, ppm.c, and kcm.c files have been modified
to support remote accesses. The RPCs that were previously user
to allocate physical memory in a remote cluster have been removed.
This has been done to cure a dead-lock in case of concurrent page-faults.

This version 2.2 has been tested on a (4 clusters / 2 cores per cluster)
TSAR architecture, for both the "sort" and the "fft" applications.

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