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

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

First implementation of fork/exec.

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