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

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

Fix bugs in exec

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