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

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

Fix a bug in scheduler related to RPC blocking.

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