/* * rpc.c - RPC operations implementation. * * Author Alain Greiner (2016,2017,2018,2019) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////////////////////////////////// // Array of function pointers and array of printable strings. // These arrays must be kept consistent with enum in rpc.h file. ///////////////////////////////////////////////////////////////////////////////////////// rpc_server_t * rpc_server[RPC_MAX_INDEX] = { &rpc_pmem_get_pages_server, // 0 &rpc_pmem_release_pages_server, // 1 &rpc_ppm_display_server, // 2 &rpc_process_make_fork_server, // 3 &rpc_user_dir_create_server, // 4 &rpc_user_dir_destroy_server, // 5 &rpc_thread_user_create_server, // 6 &rpc_thread_kernel_create_server, // 7 &rpc_vfs_fs_update_dentry_server, // 8 &rpc_process_sigaction_server, // 9 &rpc_vfs_inode_create_server, // 10 &rpc_vfs_inode_destroy_server, // 11 &rpc_vfs_dentry_create_server, // 12 &rpc_vfs_dentry_destroy_server, // 13 &rpc_vfs_file_create_server, // 14 &rpc_vfs_file_destroy_server, // 15 &rpc_vfs_fs_new_dentry_server, // 16 &rpc_vfs_fs_add_dentry_server, // 17 &rpc_vfs_fs_remove_dentry_server, // 18 &rpc_vfs_inode_load_all_pages_server, // 19 &rpc_vmm_get_vseg_server, // 20 &rpc_vmm_global_update_pte_server, // 21 &rpc_kcm_alloc_server, // 22 &rpc_kcm_free_server, // 23 &rpc_mapper_sync_server, // 24 &rpc_mapper_handle_miss_server, // 25 &rpc_vmm_delete_vseg_server, // 26 &rpc_vmm_create_vseg_server, // 27 &rpc_vmm_set_cow_server, // 28 &rpc_hal_vmm_display_server, // 29 }; char * rpc_str[RPC_MAX_INDEX] = { "PMEM_GET_PAGES", // 0 "PMEM_RELEASE_PAGES", // 1 "PPM_DISPLAY", // 2 "PROCESS_MAKE_FORK", // 3 "USER_DIR_CREATE", // 4 "USER_DIR_DESTROY", // 5 "THREAD_USER_CREATE", // 6 "THREAD_KERNEL_CREATE", // 7 "VFS_FS_UPDATE_DENTRY", // 8 "PROCESS_SIGACTION", // 9 "VFS_INODE_CREATE", // 10 "VFS_INODE_DESTROY", // 11 "VFS_DENTRY_CREATE", // 12 "VFS_DENTRY_DESTROY", // 13 "VFS_FILE_CREATE", // 14 "VFS_FILE_DESTROY", // 15 "VFS_FS_GET_DENTRY", // 16 "VFS_FS_ADD_DENTRY", // 17 "VFS_FS_REMOVE_DENTRY", // 18 "VFS_INODE_LOAD_ALL_PAGES", // 19 "GET_VSEG", // 20 "GLOBAL_UPDATE_PTE", // 21 "KCM_ALLOC", // 22 "KCM_FREE", // 23 "MAPPER_SYNC", // 24 "MAPPER_HANDLE_MISS", // 25 "VMM_DELETE_VSEG", // 26 "VMM_CREATE_VSEG", // 27 "VMM_SET_COW", // 28 "VMM_DISPLAY", // 29 }; ////////////////////////////////////////////////////////////////////////////////// void __attribute__((noinline)) rpc_undefined( xptr_t xp __attribute__ ((unused)) ) { assert( false , "called in cluster %x", local_cxy ); } /***************************************************************************************/ /************ Generic function supporting RPCs : client side ***************************/ /***************************************************************************************/ /////////////////////////////////////// void rpc_send( cxy_t server_cxy, rpc_desc_t * rpc ) { lid_t server_core_lid; lid_t client_core_lid; volatile error_t full; thread_t * this; full = 0; this = CURRENT_THREAD; client_core_lid = this->core->lid; // check calling thread can yield when is not the IDLE thread // RPCs executed by the IDLE thread during kernel_init do not deschedule if( this->type != THREAD_IDLE ) thread_assert_can_yield( this , __FUNCTION__ ); // select a server_core : use client core index if possible / core 0 otherwise if( client_core_lid < hal_remote_l32( XPTR( server_cxy , &LOCAL_CLUSTER->cores_nr ) ) ) { server_core_lid = client_core_lid; } else { server_core_lid = 0; } // register client_thread and client_core in RPC descriptor rpc->thread = this; rpc->lid = client_core_lid; // build extended pointer on the RPC descriptor xptr_t desc_xp = XPTR( local_cxy , rpc ); // get local pointer on rpc_fifo in remote cluster, remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo[server_core_lid]; xptr_t rpc_fifo_xp = XPTR( server_cxy , rpc_fifo ); // post RPC in remote fifo / deschedule without blocking if fifo full do { full = remote_fifo_put_item( rpc_fifo_xp , (uint64_t )desc_xp ); if ( full ) { printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n", __FUNCTION__ , local_cxy , server_cxy ); // deschedule without blocking sched_yield("RPC fifo full"); } } while( full ); #if DEBUG_RPC_CLIENT_GENERIC uint32_t cycle = (uint32_t)hal_get_cycles(); uint32_t items = remote_fifo_items( rpc_fifo_xp ); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] / rpc %s / server[%x,%d] / items %d / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], server_cxy, server_core_lid, items, cycle ); #endif // send IPI to the selected server core dev_pic_send_ipi( server_cxy , server_core_lid ); // wait RPC completion before returning if blocking RPC : // - deschedule without blocking if thread idle (in kernel init) // - block and deschedule policy for any other thread if ( rpc->blocking ) { if( this->type == THREAD_IDLE ) // deschedule without blocking policy { #if DEBUG_RPC_CLIENT_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] enter waiting loop for rpc %s / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle ); #endif while( 1 ) { // check responses counter if( hal_remote_l32( XPTR( local_cxy , rpc->rsp ) ) == 0 ) break; // deschedule sched_yield("busy_waiting RPC completion"); } #if DEBUG_RPC_CLIENT_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] received response for rpc %s / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle ); #endif } else // block and deschedule policy { #if DEBUG_RPC_CLIENT_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] blocks & deschedules for rpc %s / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle ); #endif // block client thread thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_RPC ); // deschedule sched_yield("blocked on RPC"); #if DEBUG_RPC_CLIENT_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] resumes after rpc %s / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle ); #endif } // response must be available for a blocking RPC assert( (*rpc->rsp == 0) , "illegal response for RPC %s\n", rpc_str[rpc->index] ); } else // non blocking RPC { #if DEBUG_RPC_CLIENT_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_CLIENT_GENERIC < cycle ) printk("\n[%s] thread[%x,%x] returns for non blocking rpc %s / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, rpc_str[rpc->index], cycle ); #endif } } // end rpc_send() /***************************************************************************************/ /************ Generic functions supporting RPCs : server side **************************/ /***************************************************************************************/ //////////////////////////// void rpc_server_func( void ) { error_t empty; // local RPC fifo state xptr_t desc_xp; // extended pointer on RPC request cxy_t desc_cxy; // RPC request cluster (client) rpc_desc_t * desc_ptr; // RPC request local pointer uint32_t index; // RPC request index thread_t * client_ptr; // local pointer on client thread xptr_t client_xp; // extended pointer on client thread lid_t client_lid; // local index of client core thread_t * server_ptr; // local pointer on server thread xptr_t server_xp; // extended pointer on server thread lid_t server_lid; // local index of server core remote_fifo_t * rpc_fifo; // local pointer on RPC fifo uint32_t * rsp_ptr; // local pointer on responses counter xptr_t rsp_xp; // extended pointer on responses counter uint32_t responses; // number of expected responses // makes RPC thread not preemptable hal_disable_irq( NULL ); server_ptr = CURRENT_THREAD; server_xp = XPTR( local_cxy , server_ptr ); server_lid = server_ptr->core->lid; rpc_fifo = &LOCAL_CLUSTER->rpc_fifo[server_lid]; // "infinite" RPC thread loop while(1) { // try to take RPC_FIFO ownership if( hal_atomic_test_set( &rpc_fifo->owner , server_ptr->trdid ) ) { #if DEBUG_RPC_SERVER_GENERIC uint32_t cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] on core[%d] takes RPC_FIFO ownership / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, server_lid, cycle ); #endif // try to consume one RPC request empty = remote_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp ); // release RPC_FIFO ownership rpc_fifo->owner = 0; // handle RPC request if success if ( empty == 0 ) { // get client cluster and pointer on RPC descriptor desc_cxy = GET_CXY( desc_xp ); desc_ptr = GET_PTR( desc_xp ); // get relevant infos from RPC descriptor index = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->index ) ); client_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->thread ) ); rsp_ptr = hal_remote_lpt( XPTR( desc_cxy , &desc_ptr->rsp ) ); client_lid = hal_remote_l32( XPTR( desc_cxy , &desc_ptr->lid ) ); rsp_xp = XPTR( desc_cxy , rsp_ptr ); client_xp = XPTR( desc_cxy , client_ptr ); #if DEBUG_RPC_SERVER_GENERIC cycle = (uint32_t)hal_get_cycles(); uint32_t items = remote_fifo_items( XPTR( local_cxy , rpc_fifo ) ); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] got rpc %s / client_cxy %x / items %d / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], desc_cxy, items, cycle ); #endif // register client thread in RPC thread descriptor server_ptr->rpc_client_xp = client_xp; // call the relevant server function rpc_server[index]( desc_xp ); #if DEBUG_RPC_SERVER_GENERIC cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] completes rpc %s / client_cxy %x / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, rpc_str[index], desc_cxy, cycle ); #endif // decrement expected responses counter responses = hal_remote_atomic_add( rsp_xp , -1 ); // unblock client thread if last response if( responses == 1 ) { // unblock client thread thread_unblock( client_xp , THREAD_BLOCKED_RPC ); hal_fence(); #if DEBUG_RPC_SERVER_GENERIC cycle = (uint32_t)hal_get_cycles(); trdid_t client_trdid = hal_remote_l32( XPTR( desc_cxy , &client_ptr->trdid ) ); process_t * process = hal_remote_lpt( XPTR( desc_cxy , &client_ptr->process ) ); pid_t client_pid = hal_remote_l32( XPTR( desc_cxy , &process->pid ) ); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] unblocked client thread[%x,%x] / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, client_pid, client_trdid, cycle ); #endif // send IPI to client core dev_pic_send_ipi( desc_cxy , client_lid ); } } // end RPC handling if fifo non empty } // end if RPC_fIFO ownership successfully taken and released // sucide if too many RPC threads if( LOCAL_CLUSTER->rpc_threads[server_lid] >= CONFIG_RPC_THREADS_MAX ) { #if DEBUG_RPC_SERVER_GENERIC uint32_t cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] suicides / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle ); #endif // update RPC threads counter hal_atomic_add( &LOCAL_CLUSTER->rpc_threads[server_lid] , -1 ); // RPC thread blocks on GLOBAL thread_block( server_xp , THREAD_BLOCKED_GLOBAL ); // RPC thread set the REQ_DELETE flag to suicide hal_remote_atomic_or( server_xp , THREAD_FLAG_REQ_DELETE ); } // block and deschedule otherwise else { #if DEBUG_RPC_SERVER_GENERIC uint32_t cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_SERVER_GENERIC < cycle ) printk("\n[%s] RPC thread[%x,%x] blocks & deschedules / cycle %d\n", __FUNCTION__, server_ptr->process->pid, server_ptr->trdid, cycle ); #endif // RPC thread blocks on IDLE thread_block( server_xp , THREAD_BLOCKED_IDLE ); // RPC thread deschedules sched_yield("RPC_FIFO empty"); } } // end infinite loop } // end rpc_server_func() ///////////////////////////////////////////////////////////////////////////////////////// // [0] Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking) ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////// void rpc_pmem_get_pages_client( cxy_t cxy, uint32_t order, // in page_t ** page ) // out { #if DEBUG_RPC_PMEM_GET_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_GET_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_PMEM_GET_PAGES; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)order; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output arguments from RPC descriptor *page = (page_t *)(intptr_t)rpc.args[1]; #if DEBUG_RPC_PMEM_GET_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_GET_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } /////////////////////////////////////////// void rpc_pmem_get_pages_server( xptr_t xp ) { #if DEBUG_RPC_PMEM_GET_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_GET_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client RPC descriptor uint32_t order = (uint32_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) ); // call local pmem allocator page_t * page = ppm_alloc_pages( order ); // set output arguments into client RPC descriptor hal_remote_s64( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page ); #if DEBUG_RPC_PMEM_GET_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_GET_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [1] Marshaling functions attached to RPC_PMEM_RELEASE_PAGES ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////// void rpc_pmem_release_pages_client( cxy_t cxy, page_t * page ) // out { #if DEBUG_RPC_PMEM_RELEASE_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_PMEM_RELEASE_PAGES; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)page; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_PMEM_RELEASE_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } /////////////////////////////////////////////// void rpc_pmem_release_pages_server( xptr_t xp ) { #if DEBUG_RPC_PMEM_RELEASE_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client RPC descriptor page_t * page = (page_t *)(intptr_t)hal_remote_l64( XPTR( cxy , &desc->args[0] ) ); // release memory to local pmem kmem_req_t req; req.type = KMEM_PAGE; req.ptr = page; kmem_free( &req ); #if DEBUG_RPC_PMEM_RELEASE_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PMEM_RELEASE_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [2] Marshaling functions attached to RPC_PPM_DISPLAY ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////// void rpc_ppm_display_client( cxy_t cxy ) { #if DEBUG_RPC_PPM_DISPLAY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PPM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_PPM_DISPLAY; rpc.blocking = true; rpc.rsp = &responses; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_PPM_DISPLAY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PPM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } //////////////////////////////////////////////////////////////////// void rpc_ppm_display_server( xptr_t __attribute__((__unused__)) xp ) { #if DEBUG_RPC_PPM_DISPLAY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PPM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif // call local kernel function ppm_display(); #if DEBUG_RPC_PPM_DISPLAY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PPM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [3] Marshaling functions attached to RPC_PROCESS_MAKE_FORK ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// void rpc_process_make_fork_client( cxy_t cxy, xptr_t ref_process_xp, // in xptr_t parent_thread_xp, // in pid_t * child_pid, // out thread_t ** child_thread_ptr, // out error_t * error ) // out { #if DEBUG_RPC_PROCESS_MAKE_FORK thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_PROCESS_MAKE_FORK; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)ref_process_xp; rpc.args[1] = (uint64_t)parent_thread_xp; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output arguments from RPC descriptor *child_pid = (pid_t)rpc.args[2]; *child_thread_ptr = (thread_t *)(intptr_t)rpc.args[3]; *error = (error_t)rpc.args[4]; #if DEBUG_RPC_PROCESS_MAKE_FORK cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ////////////////////////////////////////////// void rpc_process_make_fork_server( xptr_t xp ) { #if DEBUG_RPC_PROCESS_MAKE_FORK thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif xptr_t ref_process_xp; // extended pointer on reference parent process xptr_t parent_thread_xp; // extended pointer on parent thread pid_t child_pid; // child process identifier thread_t * child_thread_ptr; // local copy of exec_info structure error_t error; // local error status // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from cient RPC descriptor ref_process_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); parent_thread_xp = (xptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // call local kernel function error = process_make_fork( ref_process_xp, parent_thread_xp, &child_pid, &child_thread_ptr ); // set output argument into client RPC descriptor hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)child_pid ); hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)(intptr_t)child_thread_ptr ); hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); #if DEBUG_RPC_PROCESS_MAKE_FORK cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_PROCESS_MAKE_FORK ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [4] Marshaling functions attached to RPC_USER_DIR_CREATE ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// void rpc_user_dir_create_client( cxy_t cxy, vfs_inode_t * inode, xptr_t ref_xp, user_dir_t ** dir ) { #if DEBUG_RPC_USER_DIR_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_USER_DIR_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)inode; rpc.args[1] = (uint64_t)ref_xp; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output argument from RPC descriptor *dir = (user_dir_t *)(intptr_t)rpc.args[2]; #if DEBUG_RPC_USER_DIR_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } //////////////////////////////////////////// void rpc_user_dir_create_server( xptr_t xp ) { #if DEBUG_RPC_USER_DIR_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif vfs_inode_t * inode; // pointer on inode in server cluster xptr_t ref_xp; // extended pointer on reference user process user_dir_t * dir; // pointer on user_dir structure in server cluster // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument from RPC descriptor inode = (vfs_inode_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0])); ref_xp = (xptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[1])); // call kernel function dir = user_dir_create( inode , ref_xp ); // set output argument into RPC descriptor hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (intptr_t)dir ); #if DEBUG_RPC_USER_DIR_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [5] Marshaling functions attached to RPC_USER_DIR_DESTROY ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// void rpc_user_dir_destroy_client( cxy_t cxy, user_dir_t * dir, xptr_t ref_xp ) { #if DEBUG_RPC_USER_DIR_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_DESTROY) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_USER_DIR_DESTROY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)dir; rpc.args[1] = (uint64_t)ref_xp; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_USER_DIR_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_DESTROY) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////// void rpc_user_dir_destroy_server( xptr_t xp ) { #if DEBUG_RPC_USER_DIR_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_DESTROY) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif user_dir_t * dir; // pointer on user_dir structure in server cluster xptr_t ref_xp; // extended pointer on reference process // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument from RPC descriptor dir = (user_dir_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0])); ref_xp = (xptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[1])); // call kernel function user_dir_destroy( dir , ref_xp ); #if DEBUG_RPC_USER_DIR_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_USER_DIR_DESTROY) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [6] Marshaling functions attached to RPC_THREAD_USER_CREATE ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void rpc_thread_user_create_client( cxy_t cxy, pid_t pid, // in void * start_func, // in void * start_arg, // in pthread_attr_t * attr, // in xptr_t * thread_xp, // out error_t * error ) // out { #if DEBUG_RPC_THREAD_USER_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_USER_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_THREAD_USER_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)pid; rpc.args[1] = (uint64_t)(intptr_t)start_func; rpc.args[2] = (uint64_t)(intptr_t)start_arg; rpc.args[3] = (uint64_t)(intptr_t)attr; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output arguments from RPC descriptor *thread_xp = (xptr_t)rpc.args[4]; *error = (error_t)rpc.args[5]; #if DEBUG_RPC_THREAD_USER_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_USER_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } /////////////////////////////////////////////// void rpc_thread_user_create_server( xptr_t xp ) { #if DEBUG_RPC_THREAD_USER_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_USER_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif pthread_attr_t * attr_ptr; // pointer on attributes structure in client cluster pthread_attr_t attr_copy; // attributes structure copy in server cluster thread_t * thread_ptr; // local pointer on thread descriptor xptr_t thread_xp; // extended pointer on thread descriptor pid_t pid; // process identifier void * start_func; void * start_arg; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from RPC descriptor pid = (pid_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0])); start_func = (void *)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[1])); start_arg = (void *)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[2])); attr_ptr = (pthread_attr_t *)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[3])); // makes a local copy of attributes structure hal_remote_memcpy( XPTR( local_cxy , &attr_copy ), XPTR( client_cxy , attr_ptr ), sizeof(pthread_attr_t) ); // call kernel function error = thread_user_create( pid, start_func, start_arg, &attr_copy, &thread_ptr ); // set output arguments thread_xp = XPTR( local_cxy , thread_ptr ); hal_remote_s64( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)thread_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error ); #if DEBUG_RPC_THREAD_USER_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_USER_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [7] Marshaling functions attached to RPC_THREAD_KERNEL_CREATE ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// void rpc_thread_kernel_create_client( cxy_t cxy, uint32_t type, // in void * func, // in void * args, // in xptr_t * thread_xp, // out error_t * error ) // out { #if DEBUG_RPC_THREAD_KERNEL_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_THREAD_KERNEL_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)type; rpc.args[1] = (uint64_t)(intptr_t)func; rpc.args[2] = (uint64_t)(intptr_t)args; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output arguments from RPC descriptor *thread_xp = (xptr_t)rpc.args[3]; *error = (error_t)rpc.args[4]; #if DEBUG_RPC_THREAD_KERNEL_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////// void rpc_thread_kernel_create_server( xptr_t xp ) { #if DEBUG_RPC_THREAD_KERNEL_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif thread_t * thread_ptr; // local pointer on thread descriptor xptr_t thread_xp; // extended pointer on thread descriptor lid_t core_lid; // core local index error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get attributes from RPC descriptor uint32_t type = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); void * func = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); void * args = (void*)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) ); // select one core core_lid = cluster_select_local_core(); // call local kernel function error = thread_kernel_create( &thread_ptr , type , func , args , core_lid ); // set output arguments thread_xp = XPTR( local_cxy , thread_ptr ); hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp ); #if DEBUG_RPC_THREAD_KERNEL_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_THREAD_KERNEL_CREATE) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [8] Marshaling functions attached to RPC_VRS_FS_UPDATE_DENTRY ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void rpc_vfs_fs_update_dentry_client( cxy_t cxy, vfs_inode_t * inode, vfs_dentry_t * dentry, uint32_t size, error_t * error ) { #if DEBUG_RPC_VFS_FS_UPDATE_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FS_UPDATE_DENTRY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)inode; rpc.args[1] = (uint64_t)(intptr_t)dentry; rpc.args[2] = (uint64_t)size; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[3]; #if DEBUG_RPC_VFS_FS_UPDATE_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////// void rpc_vfs_fs_update_dentry_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FS_UPDATE_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif error_t error; vfs_inode_t * inode; vfs_dentry_t * dentry; uint32_t size; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments inode = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0])); dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1])); size = (uint32_t) hal_remote_l64(XPTR(client_cxy , &desc->args[2])); // call the kernel function error = vfs_fs_update_dentry( inode , dentry , size ); // set output argument hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_FS_UPDATE_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_UPDATE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [9] Marshaling functions attached to RPC_PROCESS_SIGACTION ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// void rpc_process_sigaction_client( cxy_t cxy, pid_t pid, uint32_t action ) { #if DEBUG_RPC_PROCESS_SIGACTION uint32_t cycle = (uint32_t)hal_get_cycles(); thread_t * this = CURRENT_THREAD; if( DEBUG_RPC_PROCESS_SIGACTION < cycle ) printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, process_action_str( action ), pid, cycle ); #endif uint32_t responses = 1; rpc_desc_t rpc; // initialise RPC descriptor header rpc.index = RPC_PROCESS_SIGACTION; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)pid; rpc.args[1] = (uint64_t)action; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_PROCESS_SIGACTION cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_PROCESS_SIGACTION < cycle ) printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, process_action_str( action ), pid, cycle ); #endif } // end rpc_process_sigaction_client() ////////////////////////////////////////////// void rpc_process_sigaction_server( xptr_t xp ) { // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments from RPC descriptor pid_t pid = (pid_t) hal_remote_l64( XPTR(client_cxy , &desc->args[0]) ); uint32_t action = (uint32_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) ); #if DEBUG_RPC_PROCESS_SIGACTION uint32_t cycle = (uint32_t)hal_get_cycles(); thread_t * this = CURRENT_THREAD; if( DEBUG_RPC_PROCESS_SIGACTION < cycle ) printk("\n[%s] thread[%x,%x] on core %d : enter to %s process %x / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, process_action_str( action ), pid, cycle ); #endif // get client thread pointers thread_t * client_ptr = hal_remote_lpt( XPTR( client_cxy , &desc->thread ) ); xptr_t client_xp = XPTR( client_cxy , client_ptr ); // get local process descriptor process_t * process = cluster_get_local_process_from_pid( pid ); // call relevant kernel function if found / does nothing if not found if( process != NULL ) { if ( action == DELETE_ALL_THREADS ) process_delete_threads ( process , client_xp ); if ( action == BLOCK_ALL_THREADS ) process_block_threads ( process ); if ( action == UNBLOCK_ALL_THREADS ) process_unblock_threads( process ); } #if DEBUG_RPC_PROCESS_SIGACTION cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_PROCESS_SIGACTION < cycle ) printk("\n[%s] thread[%x,%x] on core %d : exit after %s process %x / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, process_action_str( action ), pid, cycle ); #endif } // end rpc_process_sigaction_server() ///////////////////////////////////////////////////////////////////////////////////////// // [10] Marshaling functions attached to RPC_VFS_INODE_CREATE ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// void rpc_vfs_inode_create_client( cxy_t cxy, uint32_t fs_type, // in uint32_t attr, // in uint32_t rights, // in uint32_t uid, // in uint32_t gid, // in xptr_t * inode_xp, // out error_t * error ) // out { #if DEBUG_RPC_VFS_INODE_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_INODE_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)fs_type; rpc.args[1] = (uint64_t)attr; rpc.args[2] = (uint64_t)rights; rpc.args[3] = (uint64_t)uid; rpc.args[4] = (uint64_t)gid; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *inode_xp = (xptr_t)rpc.args[5]; *error = (error_t)rpc.args[6]; #if DEBUG_RPC_VFS_INODE_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////// void rpc_vfs_inode_create_server( xptr_t xp ) { #if DEBUG_RPC_VFS_INODE_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t fs_type; uint32_t attr; uint32_t rights; uint32_t uid; uint32_t gid; xptr_t inode_xp; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client rpc descriptor fs_type = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); attr = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); rights = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) ); uid = (uid_t) hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) ); gid = (gid_t) hal_remote_l64( XPTR( client_cxy , &desc->args[4] ) ); // call local kernel function error = vfs_inode_create( fs_type, attr, rights, uid, gid, &inode_xp ); // set output arguments hal_remote_s64( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)inode_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_INODE_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [11] Marshaling functions attached to RPC_VFS_INODE_DESTROY ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// void rpc_vfs_inode_destroy_client( cxy_t cxy, struct vfs_inode_s * inode ) { #if DEBUG_RPC_VFS_INODE_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_INODE_DESTROY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)inode; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VFS_INODE_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ////////////////////////////////////////////// void rpc_vfs_inode_destroy_server( xptr_t xp ) { #if DEBUG_RPC_VFS_INODE_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif vfs_inode_t * inode; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get argument "inode" from client RPC descriptor inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); // call local kernel function vfs_inode_destroy( inode ); #if DEBUG_RPC_VFS_INODE_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [12] Marshaling functions attached to RPC_VFS_DENTRY_CREATE ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void rpc_vfs_dentry_create_client( cxy_t cxy, uint32_t type, // in char * name, // in xptr_t * dentry_xp, // out error_t * error ) // out { #if DEBUG_RPC_VFS_DENTRY_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_DENTRY_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)type; rpc.args[1] = (uint64_t)(intptr_t)name; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *dentry_xp = (xptr_t)rpc.args[2]; *error = (error_t)rpc.args[3]; #if DEBUG_RPC_VFS_DENTRY_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ////////////////////////////////////////////// void rpc_vfs_dentry_create_server( xptr_t xp ) { #if DEBUG_RPC_VFS_DENTRY_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t type; char * name; xptr_t dentry_xp; error_t error; char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments "name", "type", and "parent" from client RPC descriptor type = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); name = (char *)(intptr_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // makes a local copy of name hal_remote_strcpy( XPTR( local_cxy , name_copy ), XPTR( client_cxy , name ) ); // call local kernel function error = vfs_dentry_create( type, name_copy, &dentry_xp ); // set output arguments hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)dentry_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_DENTRY_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [13] Marshaling functions attached to RPC_VFS_DENTRY_DESTROY ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////// void rpc_vfs_dentry_destroy_client( cxy_t cxy, vfs_dentry_t * dentry ) { #if DEBUG_RPC_VFS_DENTRY_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_DENTRY_DESTROY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)dentry; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VFS_DENTRY_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } /////////////////////////////////////////////// void rpc_vfs_dentry_destroy_server( xptr_t xp ) { #if DEBUG_RPC_VFS_DENTRY_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif vfs_dentry_t * dentry; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments "dentry" from client RPC descriptor dentry = (vfs_dentry_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); // call local kernel function vfs_dentry_destroy( dentry ); #if DEBUG_RPC_VFS_DENTRY_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_DENTRY_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [14] Marshaling functions attached to RPC_VFS_FILE_CREATE ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void rpc_vfs_file_create_client( cxy_t cxy, struct vfs_inode_s * inode, // in uint32_t file_attr, // in xptr_t * file_xp, // out error_t * error ) // out { #if DEBUG_RPC_VFS_FILE_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FILE_CREATE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)inode; rpc.args[1] = (uint64_t)file_attr; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *file_xp = (xptr_t)rpc.args[2]; *error = (error_t)rpc.args[3]; #if DEBUG_RPC_VFS_FILE_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } //////////////////////////////////////////// void rpc_vfs_file_create_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FILE_CREATE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t file_attr; vfs_inode_t * inode; xptr_t file_xp; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments "file_attr" and "inode" from client RPC descriptor inode = (vfs_inode_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); file_attr = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // call local kernel function error = vfs_file_create( inode, file_attr, &file_xp ); // set output arguments hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)file_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_FILE_CREATE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_CREATE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [15] Marshaling functions attached to RPC_VFS_FILE_DESTROY ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// void rpc_vfs_file_destroy_client( cxy_t cxy, vfs_file_t * file ) { #if DEBUG_RPC_VFS_FILE_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FILE_DESTROY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)file; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VFS_FILE_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////// void rpc_vfs_file_destroy_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FILE_DESTROY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif vfs_file_t * file; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments "dentry" from client RPC descriptor file = (vfs_file_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); // call local kernel function vfs_file_destroy( file ); #if DEBUG_RPC_VFS_FILE_DESTROY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FILE_DESTROY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [16] Marshaling functions attached to RPC_VFS_FS_GET_DENTRY ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// void rpc_vfs_fs_new_dentry_client( cxy_t cxy, vfs_inode_t * parent_inode, // in char * name, // in xptr_t child_inode_xp, // in error_t * error ) // out { #if DEBUG_RPC_VFS_FS_NEW_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FS_NEW_DENTRY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)parent_inode; rpc.args[1] = (uint64_t)(intptr_t)name; rpc.args[2] = (uint64_t)child_inode_xp; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[3]; #if DEBUG_RPC_VFS_FS_NEW_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ////////////////////////////////////////////// void rpc_vfs_fs_new_dentry_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FS_NEW_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif error_t error; vfs_inode_t * parent; xptr_t child_xp; char * name; char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments "parent", "name", and "child_xp" parent = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0])); name = (char*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[1])); child_xp = (xptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[2])); // get name local copy hal_remote_strcpy( XPTR( local_cxy , name_copy ) , XPTR( client_cxy , name ) ); // call the kernel function error = vfs_fs_new_dentry( parent , name_copy , child_xp ); // set output argument hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_FS_NEW_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_NEW_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [17] Marshaling function attached to RPC_VFS_FS_ADD_DENTRY ///////////////////////////////////////////////////////////////////////////////////////// void rpc_vfs_fs_add_dentry_client( cxy_t cxy, vfs_inode_t * parent, // in vfs_dentry_t * dentry, // in error_t * error ) // out { #if DEBUG_RPC_VFS_FS_ADD_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FS_ADD_DENTRY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)parent; rpc.args[1] = (uint64_t)(intptr_t)dentry; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[2]; #if DEBUG_RPC_VFS_FS_ADD_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ////////////////////////////////////////////// void rpc_vfs_fs_add_dentry_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FS_ADD_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif error_t error; vfs_inode_t * parent; vfs_dentry_t * dentry; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0])); dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1])); // call the kernel function error = vfs_fs_add_dentry( parent , dentry ); // set output argument hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_FS_ADD_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_ADD_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [18] Marshaling function attached to RPC_VFS_FS_REMOVE_DENTRY ///////////////////////////////////////////////////////////////////////////////////////// void rpc_vfs_fs_remove_dentry_client( cxy_t cxy, vfs_inode_t * parent, // in vfs_dentry_t * dentry, // in error_t * error ) // out { #if DEBUG_RPC_VFS_FS_REMOVE_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_FS_REMOVE_DENTRY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)parent; rpc.args[1] = (uint64_t)(intptr_t)dentry; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[2]; #if DEBUG_RPC_VFS_FS_REMOVE_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////// void rpc_vfs_fs_remove_dentry_server( xptr_t xp ) { #if DEBUG_RPC_VFS_FS_REMOVE_DENTRY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif error_t error; vfs_inode_t * parent; vfs_dentry_t * dentry; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments parent = (vfs_inode_t*)(intptr_t) hal_remote_l64(XPTR(client_cxy , &desc->args[0])); dentry = (vfs_dentry_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[1])); // call the kernel function error = vfs_fs_remove_dentry( parent , dentry ); // set output argument hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_FS_REMOVE_DENTRY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_FS_REMOVE_DENTRY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [19] Marshaling functions attached to RPC_VFS_INODE_LOAD_ALL_PAGES ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// void rpc_vfs_inode_load_all_pages_client( cxy_t cxy, vfs_inode_t * inode, // in error_t * error ) // out { #if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VFS_INODE_LOAD_ALL_PAGES; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)inode; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[1]; #if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////// void rpc_vfs_inode_load_all_pages_server( xptr_t xp ) { #if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif error_t error; vfs_inode_t * inode; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument inode = (vfs_inode_t*)(intptr_t)hal_remote_l64(XPTR(client_cxy , &desc->args[0])); // call the kernel function error = vfs_inode_load_all_pages( inode ); // set output argument hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); #if DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VFS_INODE_LOAD_ALL_PAGES ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [20] Marshaling functions attached to RPC_VMM_GET_VSEG ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////// void rpc_vmm_get_vseg_client( cxy_t cxy, process_t * process, // in intptr_t vaddr, // in xptr_t * vseg_xp, // out error_t * error ) // out { #if DEBUG_RPC_VMM_GET_VSEG thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GET_VSEG ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VMM_GET_VSEG; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)process; rpc.args[1] = (uint64_t)vaddr; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output argument from rpc descriptor *vseg_xp = rpc.args[2]; *error = (error_t)rpc.args[3]; #if DEBUG_RPC_VMM_GET_VSEG cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GET_VSEG ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////// void rpc_vmm_get_vseg_server( xptr_t xp ) { #if DEBUG_RPC_VMM_GET_VSEG thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GET_VSEG ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif process_t * process; intptr_t vaddr; vseg_t * vseg_ptr; xptr_t vseg_xp; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument from client RPC descriptor process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); vaddr = (intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // call local kernel function error = vmm_get_vseg( process , vaddr , &vseg_ptr ); // set output arguments to client RPC descriptor vseg_xp = XPTR( local_cxy , vseg_ptr ); hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)vseg_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_VMM_GET_VSEG cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GET_VSEG ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [21] Marshaling functions attached to RPC_VMM_GLOBAL_UPDATE_PTE ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////// void rpc_vmm_global_update_pte_client( cxy_t cxy, process_t * process, // in vpn_t vpn, // in uint32_t attr, // in ppn_t ppn ) // in { #if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VMM_GLOBAL_UPDATE_PTE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)process; rpc.args[1] = (uint64_t)vpn; rpc.args[2] = (uint64_t)attr; rpc.args[3] = (uint64_t)ppn; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ////////////////////////////////////////////////// void rpc_vmm_global_update_pte_server( xptr_t xp ) { #if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif process_t * process; vpn_t vpn; uint32_t attr; ppn_t ppn; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument "process" & "vpn" from client RPC descriptor process = (process_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); vpn = (vpn_t) hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); attr = (uint32_t) hal_remote_l64( XPTR( client_cxy , &desc->args[2] ) ); ppn = (ppn_t) hal_remote_l64( XPTR( client_cxy , &desc->args[3] ) ); // call local kernel function vmm_global_update_pte( process , vpn , attr , ppn ); #if DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_GLOBAL_UPDATE_PTE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [22] Marshaling functions attached to RPC_KCM_ALLOC ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////// void rpc_kcm_alloc_client( cxy_t cxy, uint32_t kmem_type, // in xptr_t * buf_xp ) // out { #if DEBUG_RPC_KCM_ALLOC thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_ALLOC ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_KCM_ALLOC; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)kmem_type; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output arguments from RPC descriptor *buf_xp = (xptr_t)rpc.args[1]; #if DEBUG_RPC_KCM_ALLOC cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_ALLOC ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ////////////////////////////////////// void rpc_kcm_alloc_server( xptr_t xp ) { #if DEBUG_RPC_KCM_ALLOC thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_ALLOC ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input argument "kmem_type" from client RPC descriptor uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); // allocates memory for kcm kmem_req_t req; req.type = kmem_type; req.flags = AF_ZERO; void * buf_ptr = kmem_alloc( &req ); // set output argument xptr_t buf_xp = XPTR( local_cxy , buf_ptr ); hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)buf_xp ); #if DEBUG_RPC_KCM_ALLOC cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_ALLOC ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [23] Marshaling functions attached to RPC_KCM_FREE ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////// void rpc_kcm_free_client( cxy_t cxy, void * buf, // in uint32_t kmem_type ) // in { #if DEBUG_RPC_KCM_FREE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_FREE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_KCM_FREE; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)buf; rpc.args[1] = (uint64_t)kmem_type; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_KCM_FREE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_FREE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////// void rpc_kcm_free_server( xptr_t xp ) { #if DEBUG_RPC_KCM_FREE thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_FREE ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments "buf" and "kmem_type" from client RPC descriptor void * buf = (void *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); uint32_t kmem_type = (uint32_t)hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // releases memory kmem_req_t req; req.type = kmem_type; req.ptr = buf; kmem_free( &req ); #if DEBUG_RPC_KCM_FREE cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_KCM_FREE ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [25] Marshaling functions attached to RPC_MAPPER_SYNC ///////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////// void rpc_mapper_sync_client( cxy_t cxy, struct mapper_s * mapper, error_t * error ) { #if DEBUG_RPC_MAPPER_SYNC thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_SYNC ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_MAPPER_SYNC; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)mapper; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *error = (error_t)rpc.args[1]; #if DEBUG_RPC_MAPPER_SYNC cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_SYNC ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } //////////////////////////////////////// void rpc_mapper_sync_server( xptr_t xp ) { #if DEBUG_RPC_MAPPER_SYNC thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_SYNC ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif mapper_t * mapper; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments from client RPC descriptor mapper = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); // call local kernel function error = mapper_sync( mapper ); // set output argument to client RPC descriptor hal_remote_s64( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); #if DEBUG_RPC_MAPPER_SYNC cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_SYNC ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [25] Marshaling functions attached to RPC_MAPPER_HANDLE_MISS ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// void rpc_mapper_handle_miss_client( cxy_t cxy, struct mapper_s * mapper, uint32_t page_id, xptr_t * page_xp, error_t * error ) { #if DEBUG_RPC_MAPPER_HANDLE_MISS thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_MAPPER_HANDLE_MISS; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)mapper; rpc.args[1] = (uint64_t)page_id; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *page_xp = (xptr_t)rpc.args[2]; *error = (error_t)rpc.args[3]; #if DEBUG_RPC_MAPPER_HANDLE_MISS cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } /////////////////////////////////////////////// void rpc_mapper_handle_miss_server( xptr_t xp ) { #if DEBUG_RPC_MAPPER_HANDLE_MISS thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif mapper_t * mapper; uint32_t page_id; xptr_t page_xp; error_t error; // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments from client RPC descriptor mapper = (mapper_t *)(intptr_t)hal_remote_l64( XPTR( client_cxy , &desc->args[0] ) ); page_id = hal_remote_l64( XPTR( client_cxy , &desc->args[1] ) ); // call local kernel function error = mapper_handle_miss( mapper, page_id, &page_xp ); // set output argument to client RPC descriptor hal_remote_s64( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)page_xp ); hal_remote_s64( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); #if DEBUG_RPC_MAPPER_HANDLE_MISS cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_MAPPER_HANDLE_MISS ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [26] Marshaling functions attached to RPC_VMM_DELETE_VSEG ///////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////// void rpc_vmm_delete_vseg_client( cxy_t cxy, pid_t pid, intptr_t vaddr ) { #if DEBUG_RPC_VMM_DELETE_VSEG thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DELETE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif uint32_t responses = 1; rpc_desc_t rpc; // initialise RPC descriptor header rpc.index = RPC_VMM_DELETE_VSEG; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)pid; rpc.args[1] = (uint64_t)vaddr; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VMM_DELETE_VSEG cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DELETE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } //////////////////////////////////////////// void rpc_vmm_delete_vseg_server( xptr_t xp ) { #if DEBUG_RPC_VMM_DELETE_VSEG uint32_t cycle = (uint32_t)hal_get_cycles(); thread_t * this = CURRENT_THREAD; if( DEBUG_RPC_VMM_DELETE_VSEG < cycle ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t client_cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get arguments from RPC descriptor pid_t pid = (pid_t) hal_remote_l64( XPTR(client_cxy , &desc->args[0]) ); intptr_t vaddr = (intptr_t)hal_remote_l64( XPTR(client_cxy , &desc->args[1]) ); // call relevant kernel function vmm_delete_vseg( pid , vaddr ); #if DEBUG_RPC_VMM_DELETE_VSEG cycle = (uint32_t)hal_get_cycles(); if( DEBUG_RPC_VMM_DELETE_VSEG < cycle ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid, cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [27] Marshaling functions attached to RPC_VMM_CREATE_VSEG ///////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////// void rpc_vmm_create_vseg_client( cxy_t cxy, struct process_s * process, vseg_type_t type, intptr_t base, uint32_t size, uint32_t file_offset, uint32_t file_size, xptr_t mapper_xp, cxy_t vseg_cxy, struct vseg_s ** vseg ) { #if DEBUG_RPC_VMM_CREATE_VSEG thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_CREATE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VMM_CREATE_VSEG; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)process; rpc.args[1] = (uint64_t)type; rpc.args[2] = (uint64_t)base; rpc.args[3] = (uint64_t)size; rpc.args[4] = (uint64_t)file_offset; rpc.args[5] = (uint64_t)file_size; rpc.args[6] = (uint64_t)mapper_xp; rpc.args[7] = (uint64_t)vseg_cxy; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); // get output values from RPC descriptor *vseg = (vseg_t *)(intptr_t)rpc.args[8]; #if DEBUG_RPC_VMM_CREATE_VSEG cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_CREATE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } //////////////////////////////////////////// void rpc_vmm_create_vseg_server( xptr_t xp ) { #if DEBUG_RPC_VMM_CREATE_VSEG thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_CREATE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif // get client cluster identifier and pointer on RPC descriptor cxy_t cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client RPC descriptor process_t * process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0])); vseg_type_t type = (vseg_type_t)(uint32_t)hal_remote_l64( XPTR(cxy , &desc->args[1])); intptr_t base = (intptr_t) hal_remote_l64( XPTR(cxy , &desc->args[2])); uint32_t size = (uint32_t) hal_remote_l64( XPTR(cxy , &desc->args[3])); uint32_t file_offset = (uint32_t) hal_remote_l64( XPTR(cxy , &desc->args[4])); uint32_t file_size = (uint32_t) hal_remote_l64( XPTR(cxy , &desc->args[5])); xptr_t mapper_xp = (xptr_t) hal_remote_l64( XPTR(cxy , &desc->args[6])); cxy_t vseg_cxy = (cxy_t)(uint32_t) hal_remote_l64( XPTR(cxy , &desc->args[7])); // call local kernel function vseg_t * vseg = vmm_create_vseg( process, type, base, size, file_offset, file_size, mapper_xp, vseg_cxy ); // set output arguments into client RPC descriptor hal_remote_s64( XPTR( cxy , &desc->args[8] ) , (uint64_t)(intptr_t)vseg ); #if DEBUG_RPC_VMM_CREATE_VSEG cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_CREATE_VSEG ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [28] Marshaling functions attached to RPC_VMM_SET_COW ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////// void rpc_vmm_set_cow_client( cxy_t cxy, process_t * process ) { #if DEBUG_RPC_VMM_SET_COW thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_SET_COW ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VMM_SET_COW; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)process; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VMM_SET_COW cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_SET_COW ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } //////////////////////////////////////// void rpc_vmm_set_cow_server( xptr_t xp ) { #if DEBUG_RPC_VMM_SET_COW thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_SET_COW ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif process_t * process; // get client cluster identifier and pointer on RPC descriptor cxy_t cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client RPC descriptor process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0])); // call local kernel function vmm_set_cow( process ); #if DEBUG_RPC_VMM_SET_COW cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_SET_COW ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } ///////////////////////////////////////////////////////////////////////////////////////// // [29] Marshaling functions attached to RPC_VMM_DISPLAY ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////// void rpc_hal_vmm_display_client( cxy_t cxy, process_t * process, bool_t detailed ) { #if DEBUG_RPC_VMM_DISPLAY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif uint32_t responses = 1; // initialise RPC descriptor header rpc_desc_t rpc; rpc.index = RPC_VMM_DISPLAY; rpc.blocking = true; rpc.rsp = &responses; // set input arguments in RPC descriptor rpc.args[0] = (uint64_t)(intptr_t)process; rpc.args[1] = (uint64_t)detailed; // register RPC request in remote RPC fifo rpc_send( cxy , &rpc ); #if DEBUG_RPC_VMM_DISPLAY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif } //////////////////////////////////////// void rpc_hal_vmm_display_server( xptr_t xp ) { #if DEBUG_RPC_VMM_DISPLAY thread_t * this = CURRENT_THREAD; uint32_t cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d enter / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif process_t * process; bool_t detailed; // get client cluster identifier and pointer on RPC descriptor cxy_t cxy = GET_CXY( xp ); rpc_desc_t * desc = GET_PTR( xp ); // get input arguments from client RPC descriptor process = (process_t *)(intptr_t)hal_remote_l64( XPTR(cxy , &desc->args[0])); detailed = (bool_t) hal_remote_l64( XPTR(cxy , &desc->args[1])); // call local kernel function hal_vmm_display( process , detailed ); #if DEBUG_RPC_VMM_DISPLAY cycle = (uint32_t)hal_get_cycles(); if( cycle > DEBUG_RPC_VMM_DISPLAY ) printk("\n[%s] thread[%x,%x] on core %d exit / cycle %d\n", __FUNCTION__, this->process->pid, this->trdid, this->core->lid , cycle ); #endif }