Changeset 409 for trunk/kernel/kern/rpc.c
- Timestamp:
- Dec 20, 2017, 4:51:09 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/rpc.c
r408 r409 49 49 { 50 50 &rpc_pmem_get_pages_server, // 0 51 &rpc_p rocess_make_exec_server,// 152 &rpc_process_make_ fork_server, // 253 &rpc_process_ kill_server,// 354 &rpc_ thread_user_create_server,// 455 &rpc_ thread_kernel_create_server,// 556 &rpc_ signal_rise_server, // 657 &rpc_ undefined,// 758 &rpc_ undefined, // 859 &rpc_ undefined,// 951 &rpc_pmem_release_pages_server, // 1 52 &rpc_process_make_exec_server, // 2 53 &rpc_process_make_fork_server, // 3 54 &rpc_process_make_exit_server, // 4 55 &rpc_process_make_kill_server, // 5 56 &rpc_thread_user_create_server, // 6 57 &rpc_thread_kernel_create_server, // 7 58 &rpc_thread_kill_server, // 8 59 &rpc_process_sigaction_server, // 9 60 60 61 61 &rpc_vfs_inode_create_server, // 10 … … 88 88 } 89 89 90 ///////////////////////////////////////////////////////////////////////////////////////// 91 // [0] Marshaling functions attached to RPC_PMEM_GET_PAGES 90 /***************************************************************************************/ 91 /************ Generic functions supporting RPCs : client side **************************/ 92 /***************************************************************************************/ 93 94 /////////////////////////////////////// 95 void rpc_send( cxy_t server_cxy, 96 rpc_desc_t * rpc, 97 bool_t block ) 98 { 99 error_t error; 100 101 thread_t * this = CURRENT_THREAD; 102 core_t * core = this->core; 103 104 // register client thread pointer and core lid in RPC descriptor 105 rpc->thread = this; 106 rpc->lid = core->lid; 107 108 // build an extended pointer on the RPC descriptor 109 xptr_t desc_xp = XPTR( local_cxy , rpc ); 110 111 // get local pointer on rpc_fifo in remote cluster, with the 112 // assumption that local pointers are identical in all clusters 113 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 114 115 // try to post an item in remote fifo 116 // deschedule and retry if remote fifo full 117 do 118 { 119 error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), 120 (uint64_t )desc_xp ); 121 if ( error ) 122 { 123 printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n", 124 __FUNCTION__ , local_cxy , server_cxy ); 125 126 if( thread_can_yield() ) sched_yield("RPC fifo full"); 127 } 128 } 129 while( error ); 130 131 hal_fence(); 132 133 // send IPI to the remote core corresponding to the client core 134 dev_pic_send_ipi( server_cxy , core->lid ); 135 136 // wait RPC completion if blocking 137 // - busy waiting policy during kernel_init, or if threads cannot yield 138 // - block and deschedule in all other cases 139 if ( block ) 140 { 141 if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting 142 { 143 144 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n" 145 " rpc = %d / server = %x / cycle %d\n", 146 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 147 rpc->index , server_cxy , hal_time_stamp() ); 148 149 while( rpc->response ) hal_fixed_delay( 100 ); 150 151 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n", 152 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 153 154 } 155 else // block & deschedule 156 { 157 158 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n" 159 " rpc = %d / server = %x / cycle %d\n", 160 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 161 rpc->index , server_cxy , hal_time_stamp() ); 162 163 thread_block( this , THREAD_BLOCKED_RPC ); 164 sched_yield("BLOCKED on RPC"); 165 166 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n", 167 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 168 169 } 170 171 // check response available 172 assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" ); 173 174 // acknowledge the IPI sent by the server 175 dev_pic_ack_ipi(); 176 } 177 178 } // end rpc_send() 179 180 181 /***************************************************************************************/ 182 /************ Generic functions supporting RPCs : server side **************************/ 183 /***************************************************************************************/ 184 185 //////////////// 186 void rpc_check() 187 { 188 error_t error; 189 thread_t * thread; 190 uint32_t sr_save; 191 192 bool_t found = false; 193 thread_t * this = CURRENT_THREAD; 194 core_t * core = this->core; 195 scheduler_t * sched = &core->scheduler; 196 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 197 198 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n", 199 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 200 201 // interrupted thread not preemptable during RPC chek 202 hal_disable_irq( &sr_save ); 203 204 // check RPC FIFO not empty and no RPC thread handling it 205 if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) ) 206 { 207 // search one non blocked RPC thread 208 list_entry_t * iter; 209 LIST_FOREACH( &sched->k_root , iter ) 210 { 211 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 212 if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 213 { 214 found = true; 215 break; 216 } 217 } 218 219 // create new RPC thread if not found 220 if( found == false ) 221 { 222 error = thread_kernel_create( &thread, 223 THREAD_RPC, 224 &rpc_thread_func, 225 NULL, 226 this->core->lid ); 227 if( error ) 228 { 229 printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n", 230 __FUNCTION__ , local_cxy ); 231 } 232 else 233 { 234 // unblock created RPC thread 235 thread->blocked = 0; 236 237 // update core descriptor counter 238 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 239 240 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n", 241 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 242 243 } 244 } 245 } 246 247 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n", 248 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 249 250 // interrupted thread deschedule always 251 sched_yield("IPI received"); 252 253 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", 254 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 255 256 // interrupted thread restore IRQs after resume 257 hal_restore_irq( sr_save ); 258 259 } // end rpc_check() 260 261 262 ////////////////////// 263 void rpc_thread_func() 264 { 265 uint32_t count; // handled RPC requests counter 266 error_t empty; // local RPC fifo state 267 xptr_t desc_xp; // extended pointer on RPC request 268 cxy_t desc_cxy; // RPC request cluster (client) 269 rpc_desc_t * desc_ptr; // RPC request local pointer 270 uint32_t index; // RPC request index 271 uint32_t responses; // number of responses received by client 272 thread_t * thread_ptr; // local pointer on client thread 273 lid_t core_lid; // local index of client core 274 275 // makes RPC thread not preemptable 276 hal_disable_irq( NULL ); 277 278 thread_t * this = CURRENT_THREAD; 279 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 280 281 // two embedded loops: 282 // - external loop : "infinite" RPC thread 283 // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests 284 285 while(1) // external loop 286 { 287 // try to take RPC_FIFO ownership 288 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 289 { 290 // initializes RPC requests counter 291 count = 0; 292 293 // acknowledge local IPI 294 dev_pic_ack_ipi(); 295 296 // exit internal loop in three cases: 297 // - RPC fifo is empty 298 // - ownership has been lost (because descheduling) 299 // - max number of RPCs is reached 300 while( 1 ) // internal loop 301 { 302 empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp ); 303 304 if ( empty == 0 ) // one RPC request found 305 { 306 // get client cluster and pointer on RPC descriptor 307 desc_cxy = (cxy_t)GET_CXY( desc_xp ); 308 desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp ); 309 310 // get rpc index from RPC descriptor 311 index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) ); 312 313 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n", 314 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 315 316 // call the relevant server function 317 rpc_server[index]( desc_xp ); 318 319 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n", 320 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 321 322 // increment handled RPC counter 323 count++; 324 325 // decrement response counter in RPC descriptor 326 responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1); 327 328 // unblock client thread and send IPI to client core if last response 329 if( responses == 1 ) 330 { 331 // get pointer on client thread and unblock it 332 thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread)); 333 thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC ); 334 335 hal_fence(); 336 337 // get client core lid and send IPI 338 core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid)); 339 dev_pic_send_ipi( desc_cxy , core_lid ); 340 } 341 } 342 343 // chek exit condition 344 if( local_fifo_is_empty( rpc_fifo ) || 345 (rpc_fifo->owner != this->trdid) || 346 (count >= CONFIG_RPC_PENDING_MAX) ) break; 347 } // end internal loop 348 349 // release rpc_fifo ownership if not lost 350 if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0; 351 } 352 353 // sucide if too many RPC threads in cluster 354 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) 355 { 356 357 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n", 358 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 359 360 // update RPC threads counter 361 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 ); 362 363 // suicide 364 thread_kill( this ); 365 } 366 367 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n", 368 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 369 370 // deschedule without blocking 371 sched_yield("RPC fifo empty or too much work"); 372 373 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", 374 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 375 376 } // end external loop 377 378 } // end rpc_thread_func() 379 380 381 ///////////////////////////////////////////////////////////////////////////////////////// 382 // [0] Marshaling functions attached to RPC_PMEM_GET_PAGES (blocking) 92 383 ///////////////////////////////////////////////////////////////////////////////////////// 93 384 … … 97 388 page_t ** page ) // out 98 389 { 99 100 101 390 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 391 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 392 CURRENT_THREAD->core->lid , hal_time_stamp() ); 102 393 103 394 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); … … 112 403 113 404 // register RPC request in remote RPC fifo (blocking function) 114 rpc_send _sync( cxy , &rpc);405 rpc_send( cxy , &rpc , true ); 115 406 116 407 // get output arguments from RPC descriptor 117 408 *page = (page_t *)(intptr_t)rpc.args[1]; 118 409 119 120 121 410 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 411 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 412 CURRENT_THREAD->core->lid , hal_time_stamp() ); 122 413 } 123 414 … … 125 416 void rpc_pmem_get_pages_server( xptr_t xp ) 126 417 { 127 128 129 418 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 419 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 420 CURRENT_THREAD->core->lid , hal_time_stamp() ); 130 421 131 422 // get client cluster identifier and pointer on RPC descriptor … … 134 425 135 426 // get input arguments from client RPC descriptor 136 uint32_t order = hal_remote_lw( XPTR( cxy , &desc->args[0] ) );427 uint32_t order = (uint32_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) ); 137 428 138 429 // call local pmem allocator … … 142 433 hal_remote_swd( XPTR( cxy , &desc->args[1] ) , (uint64_t)(intptr_t)page ); 143 434 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_MAKE_EXEC 435 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 436 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 437 CURRENT_THREAD->core->lid , hal_time_stamp() ); 438 } 439 440 ///////////////////////////////////////////////////////////////////////////////////////// 441 // [1] Marshaling functions attached to RPC_PMEM_RELEASE_PAGES (blocking) 442 ///////////////////////////////////////////////////////////////////////////////////////// 443 444 ////////////////////////////////////////////////// 445 void rpc_pmem_release_pages_client( cxy_t cxy, 446 page_t * page ) // out 447 { 448 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 449 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 450 CURRENT_THREAD->core->lid , hal_time_stamp() ); 451 452 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 453 454 // initialise RPC descriptor header 455 rpc_desc_t rpc; 456 rpc.index = RPC_PMEM_RELEASE_PAGES; 457 rpc.response = 1; 458 459 // set input arguments in RPC descriptor 460 rpc.args[0] = (uint64_t)(intptr_t)page; 461 462 // register RPC request in remote RPC fifo (blocking function) 463 rpc_send( cxy , &rpc , true ); 464 465 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 466 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 467 CURRENT_THREAD->core->lid , hal_time_stamp() ); 468 } 469 470 /////////////////////////////////////////////// 471 void rpc_pmem_release_pages_server( xptr_t xp ) 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 // get client cluster identifier and pointer on RPC descriptor 478 cxy_t cxy = (cxy_t)GET_CXY( xp ); 479 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 480 481 // get input arguments from client RPC descriptor 482 page_t * page = (page_t *)(intptr_t)hal_remote_lwd( XPTR( cxy , &desc->args[0] ) ); 483 484 // release memory to local pmem 485 kmem_req_t req; 486 req.type = KMEM_PAGE; 487 req.ptr = page; 488 kmem_free( &req ); 489 490 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 491 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 492 CURRENT_THREAD->core->lid , hal_time_stamp() ); 493 } 494 495 ///////////////////////////////////////////////////////////////////////////////////////// 496 // [2] Marshaling functions attached to RPC_PROCESS_MAKE_EXEC (blocking) 151 497 ///////////////////////////////////////////////////////////////////////////////////////// 152 498 … … 156 502 error_t * error ) // out 157 503 { 158 159 160 504 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 505 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 506 CURRENT_THREAD->core->lid , hal_time_stamp() ); 161 507 162 508 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); … … 171 517 172 518 // register RPC request in remote RPC fifo (blocking function) 173 rpc_send _sync( cxy , &rpc);519 rpc_send( cxy , &rpc , true ); 174 520 175 521 // get output arguments from RPC descriptor 176 522 *error = (error_t)rpc.args[1]; 177 523 178 179 180 524 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 525 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 526 CURRENT_THREAD->core->lid , hal_time_stamp() ); 181 527 } 182 528 … … 184 530 void rpc_process_make_exec_server( xptr_t xp ) 185 531 { 532 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 533 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 534 CURRENT_THREAD->core->lid , hal_time_stamp() ); 535 186 536 exec_info_t * ptr; // local pointer on remote exec_info structure 187 537 exec_info_t info; // local copy of exec_info structure 188 538 error_t error; // local error error status 189 190 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",191 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,192 CURRENT_THREAD->core->lid , hal_time_stamp() );193 539 194 540 // get client cluster identifier and pointer on RPC descriptor … … 210 556 hal_remote_swd( XPTR( client_cxy , &desc->args[1] ) , (uint64_t)error ); 211 557 212 213 214 215 } 216 217 ///////////////////////////////////////////////////////////////////////////////////////// 218 // [ 2] Marshaling functions attached to RPC_PROCESS_MAKE_FORK558 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 559 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 560 CURRENT_THREAD->core->lid , hal_time_stamp() ); 561 } 562 563 ///////////////////////////////////////////////////////////////////////////////////////// 564 // [3] Marshaling functions attached to RPC_PROCESS_MAKE_FORK (blocking) 219 565 ///////////////////////////////////////////////////////////////////////////////////////// 220 566 … … 227 573 error_t * error ) // out 228 574 { 229 230 231 575 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 576 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 577 CURRENT_THREAD->core->lid , hal_time_stamp() ); 232 578 233 579 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); … … 243 589 244 590 // register RPC request in remote RPC fifo (blocking function) 245 rpc_send _sync( cxy , &rpc);591 rpc_send( cxy , &rpc , true ); 246 592 247 593 // get output arguments from RPC descriptor … … 250 596 *error = (error_t)rpc.args[4]; 251 597 252 253 254 598 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 599 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 600 CURRENT_THREAD->core->lid , hal_time_stamp() ); 255 601 } 256 602 … … 258 604 void rpc_process_make_fork_server( xptr_t xp ) 259 605 { 606 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 607 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 608 CURRENT_THREAD->core->lid , hal_time_stamp() ); 609 260 610 xptr_t ref_process_xp; // extended pointer on reference parent process 261 611 xptr_t parent_thread_xp; // extended pointer on parent thread … … 264 614 error_t error; // local error status 265 615 266 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",267 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,268 CURRENT_THREAD->core->lid , hal_time_stamp() );269 270 616 // get client cluster identifier and pointer on RPC descriptor 271 617 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); … … 287 633 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); 288 634 289 290 291 292 } 293 294 ///////////////////////////////////////////////////////////////////////////////////////// 295 // [ 3] Marshaling functions attached to RPC_PROCESS_KILL635 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 636 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 637 CURRENT_THREAD->core->lid , hal_time_stamp() ); 638 } 639 640 ///////////////////////////////////////////////////////////////////////////////////////// 641 // [4] Marshaling functions attached to RPC_PROCESS_MAKE_EXIT (blocking) 296 642 ///////////////////////////////////////////////////////////////////////////////////////// 297 643 298 644 /////////////////////////////////////////////////// 299 void rpc_process_kill_client( process_t * process ) 300 { 301 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 302 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 303 CURRENT_THREAD->core->lid , hal_time_stamp() ); 304 305 // only reference cluster can send this RPC 306 assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ , 307 "caller must be reference process cluster\n"); 308 309 // get local process index in reference cluster 310 lpid_t lpid = LPID_FROM_PID( process->pid ); 311 312 // get local process manager pointer 313 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 314 315 // get number of copies 316 uint32_t copies = pmgr->copies_nr[lpid]; 317 318 // initialise RPC descriptor 319 rpc_desc_t rpc; 320 rpc.index = RPC_PROCESS_KILL; 321 rpc.response = copies; 322 rpc.args[0] = (uint64_t)process->pid; 323 324 // loop on list of copies to send RPC 325 xptr_t iter; 326 XLIST_FOREACH( XPTR( local_cxy , &pmgr->copies_root[lpid] ) , iter ) 327 { 328 // get cluster_identifier for current copy 329 cxy_t target_cxy = GET_CXY( iter ); 330 331 // register RPC request in remote RPC fifo ... but the reference 332 if( target_cxy != local_cxy ) rpc_send_sync( target_cxy , &rpc ); 333 } 334 335 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 336 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 337 CURRENT_THREAD->core->lid , hal_time_stamp() ); 645 void rpc_process_make_exit_client( cxy_t cxy, 646 process_t * process, 647 uint32_t status ) 648 { 649 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 650 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 651 CURRENT_THREAD->core->lid , hal_time_stamp() ); 652 653 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 654 655 // initialise RPC descriptor header 656 rpc_desc_t rpc; 657 rpc.index = RPC_PROCESS_MAKE_EXIT; 658 rpc.response = 1; 659 660 // set input arguments in RPC descriptor 661 rpc.args[0] = (uint64_t)(intptr_t)process; 662 rpc.args[1] = (uint64_t)status; 663 664 // register RPC request in remote RPC fifo (blocking function) 665 rpc_send( cxy , &rpc , true ); 666 667 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 668 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 669 CURRENT_THREAD->core->lid , hal_time_stamp() ); 338 670 } 339 671 340 ///////////////////////////////////////// 341 void rpc_process_ kill_server( xptr_t xp )342 { 343 pid_t pid; 344 process_t * process;345 346 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 347 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,348 CURRENT_THREAD->core->lid , hal_time_stamp() );672 ////////////////////////////////////////////// 673 void rpc_process_make_exit_server( xptr_t xp ) 674 { 675 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 676 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 677 CURRENT_THREAD->core->lid , hal_time_stamp() ); 678 679 process_t * process; 680 uint32_t status; 349 681 350 682 // get client cluster identifier and pointer on RPC descriptor … … 352 684 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 353 685 354 // get pid argument from RPC descriptor 355 pid = (pid_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 356 357 // get process pointer to call local kernel function 358 process = cluster_get_local_process_from_pid( pid ); 359 360 if( process == NULL ) // process not found => do nothing 361 { 362 printk("\n[WARNING] in %s : process %x not found in cluster %x\n", 363 __FUNCTION__ , pid , local_cxy ); 364 } 365 else // destroy process 366 { 367 process_kill( process ); 368 } 369 370 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 371 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 372 CURRENT_THREAD->core->lid , hal_time_stamp() ); 686 // get arguments from RPC descriptor 687 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 688 status = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 689 690 // call local kernel function 691 process_make_exit( process , status ); 692 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() ); 373 696 } 374 697 375 376 ///////////////////////////////////////////////////////////////////////////////////////// 377 // [4] Marshaling functions attached to RPC_THREAD_USER_CREATE 698 ///////////////////////////////////////////////////////////////////////////////////////// 699 // [5] Marshaling functions attached to RPC_PROCESS_MAKE_KILL (blocking) 700 ///////////////////////////////////////////////////////////////////////////////////////// 701 702 /////////////////////////////////////////////////// 703 void rpc_process_make_kill_client( cxy_t cxy, 704 process_t * process, 705 uint32_t sig_id ) 706 { 707 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 708 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 709 CURRENT_THREAD->core->lid , hal_time_stamp() ); 710 711 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 712 713 // initialise RPC descriptor header 714 rpc_desc_t rpc; 715 rpc.index = RPC_PROCESS_MAKE_KILL; 716 rpc.response = 1; 717 718 // set input arguments in RPC descriptor 719 rpc.args[0] = (uint64_t)(intptr_t)process; 720 rpc.args[1] = (uint64_t)sig_id; 721 722 // register RPC request in remote RPC fifo (blocking function) 723 rpc_send( cxy , &rpc , true ); 724 725 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 726 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 727 CURRENT_THREAD->core->lid , hal_time_stamp() ); 728 } 729 730 ////////////////////////////////////////////// 731 void rpc_process_make_kill_server( xptr_t xp ) 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 process_t * process; 738 uint32_t sig_id; 739 740 // get client cluster identifier and pointer on RPC descriptor 741 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 742 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 743 744 // get arguments from RPC descriptor 745 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 746 sig_id = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 747 748 // call local kernel function 749 process_make_exit( process , sig_id ); 750 751 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 752 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 753 CURRENT_THREAD->core->lid , hal_time_stamp() ); 754 } 755 756 ///////////////////////////////////////////////////////////////////////////////////////// 757 // [6] Marshaling functions attached to RPC_THREAD_USER_CREATE (blocking) 378 758 ///////////////////////////////////////////////////////////////////////////////////////// 379 759 … … 387 767 error_t * error ) // out 388 768 { 389 390 391 769 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 770 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 771 CURRENT_THREAD->core->lid , hal_time_stamp() ); 392 772 393 773 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); … … 404 784 rpc.args[3] = (uint64_t)(intptr_t)attr; 405 785 406 // register RPC request in remote RPC fifo 407 rpc_send _sync( cxy , &rpc);786 // register RPC request in remote RPC fifo (blocking function) 787 rpc_send( cxy , &rpc , true ); 408 788 409 789 // get output arguments from RPC descriptor … … 411 791 *error = (error_t)rpc.args[5]; 412 792 413 414 415 793 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 794 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 795 CURRENT_THREAD->core->lid , hal_time_stamp() ); 416 796 } 417 797 … … 419 799 void rpc_thread_user_create_server( xptr_t xp ) 420 800 { 801 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 802 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 803 CURRENT_THREAD->core->lid , hal_time_stamp() ); 804 421 805 pthread_attr_t * attr_ptr; // pointer on attributes structure in client cluster 422 806 pthread_attr_t attr_copy; // attributes structure copy in server cluster … … 428 812 void * start_arg; 429 813 error_t error; 430 431 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",432 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,433 CURRENT_THREAD->core->lid , hal_time_stamp() );434 814 435 815 // get client cluster identifier and pointer on RPC descriptor … … 462 842 hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error ); 463 843 464 465 466 467 } 468 469 ///////////////////////////////////////////////////////////////////////////////////////// 470 // [ 5] Marshaling functions attached to RPC_THREAD_KERNEL_CREATE844 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 845 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 846 CURRENT_THREAD->core->lid , hal_time_stamp() ); 847 } 848 849 ///////////////////////////////////////////////////////////////////////////////////////// 850 // [7] Marshaling functions attached to RPC_THREAD_KERNEL_CREATE (blocking) 471 851 ///////////////////////////////////////////////////////////////////////////////////////// 472 852 … … 479 859 error_t * error ) // out 480 860 { 481 482 483 861 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 862 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 863 CURRENT_THREAD->core->lid , hal_time_stamp() ); 484 864 485 865 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); … … 495 875 rpc.args[2] = (uint64_t)(intptr_t)args; 496 876 497 // register RPC request in remote RPC fifo 498 rpc_send _sync( cxy , &rpc);877 // register RPC request in remote RPC fifo (blocking function) 878 rpc_send( cxy , &rpc , true ); 499 879 500 880 // get output arguments from RPC descriptor … … 502 882 *error = (error_t)rpc.args[4]; 503 883 504 505 506 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() ); 507 887 } 508 888 … … 510 890 void rpc_thread_kernel_create_server( xptr_t xp ) 511 891 { 892 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 893 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 894 CURRENT_THREAD->core->lid , hal_time_stamp() ); 895 512 896 thread_t * thread_ptr; // local pointer on thread descriptor 513 897 xptr_t thread_xp; // extended pointer on thread descriptor … … 515 899 error_t error; 516 900 517 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n",518 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy,519 CURRENT_THREAD->core->lid , hal_time_stamp() );520 521 901 // get client cluster identifier and pointer on RPC descriptor 522 902 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); … … 539 919 hal_remote_swd( XPTR( client_cxy , &desc->args[2] ) , (uint64_t)thread_xp ); 540 920 541 542 543 544 } 545 546 ///////////////////////////////////////////////////////////////////////////////////////// 547 // [ 6] Marshaling functions attached to RPC_SIGNAL_RISE921 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 922 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 923 CURRENT_THREAD->core->lid , hal_time_stamp() ); 924 } 925 926 ///////////////////////////////////////////////////////////////////////////////////////// 927 // [8] Marshaling functions attached to RPC_THREAD_KILL (blocking) 548 928 ///////////////////////////////////////////////////////////////////////////////////////// 549 929 550 930 ///////////////////////////////////////////// 551 void rpc_signal_rise_client( cxy_t cxy, 552 process_t * process, // in 553 uint32_t sig_id ) // in 554 { 555 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 556 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 557 CURRENT_THREAD->core->lid , hal_time_stamp() ); 558 559 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 560 561 // initialise RPC descriptor header 562 rpc_desc_t rpc; 563 rpc.index = RPC_SIGNAL_RISE; 931 void rpc_thread_kill_client( cxy_t cxy, 932 thread_t * thread ) // in 933 { 934 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 935 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 936 CURRENT_THREAD->core->lid , hal_time_stamp() ); 937 938 // this RPC can be called in local cluster 939 940 // initialise RPC descriptor header 941 rpc_desc_t rpc; 942 rpc.index = RPC_THREAD_KILL; 564 943 rpc.response = 1; 565 944 566 945 // set input arguments in RPC descriptor 567 rpc.args[0] = (uint64_t)(intptr_t)process; 568 rpc.args[1] = (uint64_t)sig_id; 946 rpc.args[0] = (uint64_t)(intptr_t)thread; 569 947 570 // register RPC request in remote RPC fifo 571 rpc_send _sync( cxy , &rpc);572 573 574 575 948 // register RPC request in remote RPC fifo (blocking function) 949 rpc_send( cxy , &rpc , true ); 950 951 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 952 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 953 CURRENT_THREAD->core->lid , hal_time_stamp() ); 576 954 } 577 955 578 956 //////////////////////////////////////// 579 void rpc_signal_rise_server( xptr_t xp ) 580 { 581 process_t * process; // local pointer on process descriptor 582 uint32_t sig_id; // signal index 583 584 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 585 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 586 CURRENT_THREAD->core->lid , hal_time_stamp() ); 957 void rpc_thread_kill_server( xptr_t xp ) 958 { 959 rpc_dmsg("\n[DBG] %s : enter / thread %x on core[%x,%d] / cycle %d\n", 960 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 961 CURRENT_THREAD->core->lid , hal_time_stamp() ); 962 963 thread_t * thread; // local pointer on process descriptor 587 964 588 965 // get client cluster identifier and pointer on RPC descriptor … … 591 968 592 969 // get attributes from RPC descriptor 593 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 594 sig_id = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 970 thread = (thread_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 595 971 596 972 // call local kernel function 597 signal_rise( process , sig_id ); 598 599 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 600 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 601 CURRENT_THREAD->core->lid , hal_time_stamp() ); 602 } 603 604 ///////////////////////////////////////////////////////////////////////////////////////// 605 // [10] Marshaling functions attached to RPC_VFS_INODE_CREATE 973 thread_kill( thread ); 974 975 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", 976 __FUNCTION__ , CURRENT_THREAD->trdid , local_cxy, 977 CURRENT_THREAD->core->lid , hal_time_stamp() ); 978 } 979 980 981 ///////////////////////////////////////////////////////////////////////////////////////// 982 // [9] Marshaling functions attached to RPC_PROCESS_KILL (multicast / non blocking) 983 ///////////////////////////////////////////////////////////////////////////////////////// 984 985 /////////////////////////////////////////////////// 986 void rpc_process_sigaction_client( cxy_t cxy, 987 process_t * process, // in 988 uint32_t sigaction, // in 989 xptr_t rsp_xp, // in 990 xptr_t client_xp ) // in 991 { 992 signal_dmsg("\n[DBG] %s : enter for %s / thread %x on core[%x,%d] / cycle %d\n", 993 __FUNCTION__ , process_action_str( sigaction ) , CURRENT_THREAD , 994 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 995 996 // initialise RPC descriptor header 997 rpc_desc_t rpc; 998 rpc.index = RPC_PROCESS_SIGACTION; 999 1000 // set input arguments in RPC descriptor 1001 rpc.args[0] = (uint64_t)(intptr_t)process; 1002 rpc.args[1] = (uint64_t)sigaction; 1003 rpc.args[2] = (uint64_t)rsp_xp; 1004 rpc.args[3] = (uint64_t)client_xp; 1005 1006 // register RPC request in remote RPC fifo (non blocking) 1007 rpc_send( cxy , &rpc , false ); 1008 1009 signal_dmsg("\n[DBG] %s : exit for %s / thread %x on core[%x,%d] / cycle %d\n", 1010 __FUNCTION__ , process_action_str( sigaction ) , CURRENT_THREAD , 1011 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 1012 } 1013 1014 ////////////////////////////////////////////// 1015 void rpc_process_sigaction_server( xptr_t xp ) 1016 { 1017 process_t * process; 1018 uint32_t action; 1019 xptr_t rsp_xp; 1020 xptr_t client_xp; 1021 1022 // get client cluster identifier and pointer on RPC descriptor 1023 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 1024 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 1025 1026 // get arguments from RPC descriptor 1027 process = (process_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 1028 action = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 1029 rsp_xp = (xptr_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 1030 client_xp = (xptr_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); 1031 1032 signal_dmsg("\n[DBG] %s : enter for %s / thread %x on core[%x,%d] / cycle %d\n", 1033 __FUNCTION__ , process_action_str( action ) , CURRENT_THREAD , 1034 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 1035 1036 // call relevant kernel function 1037 if (action == DELETE_ALL_THREADS ) process_delete ( process , rsp_xp , client_xp ); 1038 else if (action == BLOCK_ALL_THREADS ) process_block ( process , rsp_xp , client_xp ); 1039 else if (action == UNBLOCK_ALL_THREADS ) process_unblock( process , rsp_xp , client_xp ); 1040 1041 signal_dmsg("\n[DBG] %s : exit for %s / thread %x on core[%x,%d] / cycle %d\n", 1042 __FUNCTION__ , process_action_str( action ) , CURRENT_THREAD , 1043 local_cxy , CURRENT_THREAD->core->lid , hal_time_stamp() ); 1044 } 1045 1046 ///////////////////////////////////////////////////////////////////////////////////////// 1047 // [10] Marshaling functions attached to RPC_VFS_INODE_CREATE (blocking) 606 1048 ///////////////////////////////////////////////////////////////////////////////////////// 607 1049 … … 641 1083 642 1084 // register RPC request in remote RPC fifo (blocking function) 643 rpc_send _sync( cxy , &rpc);1085 rpc_send( cxy , &rpc , true ); 644 1086 645 1087 // get output values from RPC descriptor … … 705 1147 706 1148 ///////////////////////////////////////////////////////////////////////////////////////// 707 // [11] Marshaling functions attached to RPC_VFS_INODE_DESTROY 1149 // [11] Marshaling functions attached to RPC_VFS_INODE_DESTROY (blocking) 708 1150 ///////////////////////////////////////////////////////////////////////////////////////// 709 1151 … … 727 1169 728 1170 // register RPC request in remote RPC fifo (blocking function) 729 rpc_send _sync( cxy , &rpc);1171 rpc_send( cxy , &rpc , true ); 730 1172 731 1173 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 759 1201 760 1202 ///////////////////////////////////////////////////////////////////////////////////////// 761 // [12] Marshaling functions attached to RPC_VFS_DENTRY_CREATE 1203 // [12] Marshaling functions attached to RPC_VFS_DENTRY_CREATE (blocking) 762 1204 ///////////////////////////////////////////////////////////////////////////////////////// 763 1205 … … 787 1229 788 1230 // register RPC request in remote RPC fifo (blocking function) 789 rpc_send _sync( cxy , &rpc);1231 rpc_send( cxy , &rpc , true ); 790 1232 791 1233 // get output values from RPC descriptor … … 841 1283 842 1284 ///////////////////////////////////////////////////////////////////////////////////////// 843 // [13] Marshaling functions attached to RPC_VFS_DENTRY_DESTROY 1285 // [13] Marshaling functions attached to RPC_VFS_DENTRY_DESTROY (blocking) 844 1286 ///////////////////////////////////////////////////////////////////////////////////////// 845 1287 … … 864 1306 865 1307 // register RPC request in remote RPC fifo (blocking function) 866 rpc_send _sync( cxy , &rpc);1308 rpc_send( cxy , &rpc , true ); 867 1309 868 1310 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 897 1339 898 1340 ///////////////////////////////////////////////////////////////////////////////////////// 899 // [14] Marshaling functions attached to RPC_VFS_FILE_CREATE 1341 // [14] Marshaling functions attached to RPC_VFS_FILE_CREATE (blocking) 900 1342 ///////////////////////////////////////////////////////////////////////////////////////// 901 1343 … … 923 1365 924 1366 // register RPC request in remote RPC fifo (blocking function) 925 rpc_send _sync( cxy , &rpc);1367 rpc_send( cxy , &rpc , true ); 926 1368 927 1369 // get output values from RPC descriptor … … 969 1411 970 1412 ///////////////////////////////////////////////////////////////////////////////////////// 971 // [15] Marshaling functions attached to RPC_VFS_FILE_DESTROY 1413 // [15] Marshaling functions attached to RPC_VFS_FILE_DESTROY (blocking) 972 1414 ///////////////////////////////////////////////////////////////////////////////////////// 973 1415 … … 991 1433 992 1434 // register RPC request in remote RPC fifo (blocking function) 993 rpc_send _sync( cxy , &rpc);1435 rpc_send( cxy , &rpc , true ); 994 1436 995 1437 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 1023 1465 1024 1466 ///////////////////////////////////////////////////////////////////////////////////////// 1025 // [16] Marshaling functions attached to RPC_VFS_INODE_LOAD 1467 // [16] Marshaling functions attached to RPC_VFS_INODE_LOAD (blocking) 1026 1468 ///////////////////////////////////////////////////////////////////////////////////////// 1027 1469 … … 1050 1492 1051 1493 // register RPC request in remote RPC fifo (blocking function) 1052 rpc_send _sync( cxy , &rpc);1494 rpc_send( cxy , &rpc , true ); 1053 1495 1054 1496 // get output values from RPC descriptor … … 1099 1541 1100 1542 ///////////////////////////////////////////////////////////////////////////////////////// 1101 // [17] Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL 1543 // [17] Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL (blocking) 1102 1544 ///////////////////////////////////////////////////////////////////////////////////////// 1103 1545 … … 1122 1564 1123 1565 // register RPC request in remote RPC fifo (blocking function) 1124 rpc_send _sync( cxy , &rpc);1566 rpc_send( cxy , &rpc , true ); 1125 1567 1126 1568 // get output values from RPC descriptor … … 1161 1603 1162 1604 ///////////////////////////////////////////////////////////////////////////////////////// 1163 // [18] Marshaling functions attached to RPC_FATFS_GET_CLUSTER 1605 // [18] Marshaling functions attached to RPC_FATFS_GET_CLUSTER (blocking) 1164 1606 ///////////////////////////////////////////////////////////////////////////////////////// 1165 1607 … … 1189 1631 1190 1632 // register RPC request in remote RPC fifo 1191 rpc_send _sync( cxy , &rpc);1633 rpc_send( cxy , &rpc , true ); 1192 1634 1193 1635 // get output argument from rpc descriptor … … 1235 1677 1236 1678 ///////////////////////////////////////////////////////////////////////////////////////// 1237 // [20] Marshaling functions attached to RPC_VMM_GET_VSEG 1679 // [20] Marshaling functions attached to RPC_VMM_GET_VSEG (blocking) 1238 1680 ///////////////////////////////////////////////////////////////////////////////////////// 1239 1681 … … 1261 1703 1262 1704 // register RPC request in remote RPC fifo (blocking function) 1263 rpc_send _sync( cxy , &rpc);1705 rpc_send( cxy , &rpc , true ); 1264 1706 1265 1707 // get output argument from rpc descriptor … … 1308 1750 1309 1751 ///////////////////////////////////////////////////////////////////////////////////////// 1310 // [21] Marshaling functions attached to RPC_VMM_GET_PTE 1752 // [21] Marshaling functions attached to RPC_VMM_GET_PTE (blocking) 1311 1753 ///////////////////////////////////////////////////////////////////////////////////////// 1312 1754 … … 1337 1779 1338 1780 // register RPC request in remote RPC fifo (blocking function) 1339 rpc_send _sync( cxy , &rpc);1781 rpc_send( cxy , &rpc , true ); 1340 1782 1341 1783 // get output argument from rpc descriptor … … 1386 1828 1387 1829 ///////////////////////////////////////////////////////////////////////////////////////// 1388 // [22] Marshaling functions attached to RPC_KCM_ALLOC 1830 // [22] Marshaling functions attached to RPC_KCM_ALLOC (blocking) 1389 1831 ///////////////////////////////////////////////////////////////////////////////////////// 1390 1832 … … 1408 1850 rpc.args[0] = (uint64_t)kmem_type; 1409 1851 1410 // register RPC request in remote RPC fifo 1411 rpc_send _sync( cxy , &rpc);1852 // register RPC request in remote RPC fifo (blocking function) 1853 rpc_send( cxy , &rpc , true ); 1412 1854 1413 1855 // get output arguments from RPC descriptor … … 1449 1891 1450 1892 ///////////////////////////////////////////////////////////////////////////////////////// 1451 // [23] Marshaling functions attached to RPC_KCM_FREE 1893 // [23] Marshaling functions attached to RPC_KCM_FREE (blocking) 1452 1894 ///////////////////////////////////////////////////////////////////////////////////////// 1453 1895 … … 1472 1914 rpc.args[1] = (uint64_t)kmem_type; 1473 1915 1474 // register RPC request in remote RPC fifo 1475 rpc_send _sync( cxy , &rpc);1916 // register RPC request in remote RPC fifo (blocking function) 1917 rpc_send( cxy , &rpc , true ); 1476 1918 1477 1919 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 1540 1982 1541 1983 // register RPC request in remote RPC fifo (blocking function) 1542 rpc_send _sync( cxy , &rpc);1984 rpc_send( cxy , &rpc , true ); 1543 1985 1544 1986 // get output values from RPC descriptor … … 1608 2050 1609 2051 ///////////////////////////////////////////////////////////////////////////////////////// 1610 // [25] Marshaling functions attached to RPC_MAPPER_GET_PAGE 2052 // [25] Marshaling functions attached to RPC_MAPPER_GET_PAGE (blocking) 1611 2053 ///////////////////////////////////////////////////////////////////////////////////////// 1612 2054 … … 1633 2075 1634 2076 // register RPC request in remote RPC fifo (blocking function) 1635 rpc_send _sync( cxy , &rpc);2077 rpc_send( cxy , &rpc , true ); 1636 2078 1637 2079 // get output values from RPC descriptor … … 1670 2112 1671 2113 ///////////////////////////////////////////////////////////////////////////////////////// 1672 // [26] Marshaling functions attached to RPC_VMM_CREATE_VSEG 2114 // [26] Marshaling functions attached to RPC_VMM_CREATE_VSEG (blocking) 1673 2115 ///////////////////////////////////////////////////////////////////////////////////////// 1674 2116 … … 1707 2149 1708 2150 // register RPC request in remote RPC fifo (blocking function) 1709 rpc_send _sync( cxy , &rpc);2151 rpc_send( cxy , &rpc , true ); 1710 2152 1711 2153 // get output values from RPC descriptor … … 1757 2199 1758 2200 ///////////////////////////////////////////////////////////////////////////////////////// 1759 // [27] Marshaling functions attached to RPC_SCHED_DISPLAY 2201 // [27] Marshaling functions attached to RPC_SCHED_DISPLAY (blocking) 1760 2202 ///////////////////////////////////////////////////////////////////////////////////////// 1761 2203 … … 1779 2221 1780 2222 // register RPC request in remote RPC fifo (blocking function) 1781 rpc_send _sync( cxy , &rpc);2223 rpc_send( cxy , &rpc , true ); 1782 2224 1783 2225 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 1809 2251 1810 2252 ///////////////////////////////////////////////////////////////////////////////////////// 1811 // [28] Marshaling functions attached to RPC_VMM_SET_COW 2253 // [28] Marshaling functions attached to RPC_VMM_SET_COW (blocking) 1812 2254 ///////////////////////////////////////////////////////////////////////////////////////// 1813 2255 … … 1831 2273 1832 2274 // register RPC request in remote RPC fifo (blocking function) 1833 rpc_send _sync( cxy , &rpc);2275 rpc_send( cxy , &rpc , true ); 1834 2276 1835 2277 rpc_dmsg("\n[DBG] %s : exit / thread %x on core[%x,%d] / cycle %d\n", … … 1862 2304 } 1863 2305 1864 /***************************************************************************************/ 1865 /************ Generic functions supporting RPCs : client side **************************/ 1866 /***************************************************************************************/ 1867 1868 //////////////////////////////////////////// 1869 void rpc_send_sync( cxy_t server_cxy, 1870 rpc_desc_t * rpc ) 1871 { 1872 error_t error; 1873 1874 thread_t * this = CURRENT_THREAD; 1875 core_t * core = this->core; 1876 1877 // register client thread pointer and core lid in RPC descriptor 1878 rpc->thread = this; 1879 rpc->lid = core->lid; 1880 1881 // build an extended pointer on the RPC descriptor 1882 xptr_t desc_xp = XPTR( local_cxy , rpc ); 1883 1884 // get local pointer on rpc_fifo in remote cluster, with the 1885 // assumption that local pointers are identical in all clusters 1886 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1887 1888 // try to post an item in remote fifo 1889 // deschedule and retry if remote fifo full 1890 do 1891 { 1892 error = remote_fifo_put_item( XPTR( server_cxy , rpc_fifo ), 1893 (uint64_t )desc_xp ); 1894 if ( error ) 1895 { 1896 printk("\n[WARNING] %s : cluster %x cannot post RPC to cluster %x\n", 1897 __FUNCTION__ , local_cxy , server_cxy ); 1898 1899 if( thread_can_yield() ) sched_yield("RPC fifo full"); 1900 } 1901 } 1902 while( error ); 1903 1904 hal_fence(); 1905 1906 // send IPI to the remote core corresponding to the client core 1907 dev_pic_send_ipi( server_cxy , core->lid ); 1908 1909 // wait RPC completion: 1910 // - busy waiting policy during kernel_init, or if threads cannot yield 1911 // - block and deschedule in all other cases 1912 1913 if( (this->type == THREAD_IDLE) || (thread_can_yield() == false) ) // busy waiting 1914 { 1915 1916 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s busy waiting after registering RPC\n" 1917 " rpc = %d / server = %x / cycle %d\n", 1918 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 1919 rpc->index , server_cxy , hal_time_stamp() ); 1920 1921 while( rpc->response ) hal_fixed_delay( 100 ); 1922 1923 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s exit after RPC completion\n", 1924 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 1925 1926 } 1927 else // block & deschedule 1928 { 1929 1930 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s deschedule after registering RPC\n" 1931 " rpc = %d / server = %x / cycle %d\n", 1932 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) , 1933 rpc->index , server_cxy , hal_time_stamp() ); 1934 1935 thread_block( this , THREAD_BLOCKED_RPC ); 1936 sched_yield("client blocked on RPC"); 1937 1938 grpc_dmsg("\n[DBG] %s : core[%x,%d] / thread %s resumes after RPC completion\n", 1939 __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , thread_type_str(this->type) ); 1940 1941 } 1942 1943 // check response available 1944 assert( (rpc->response == 0) , __FUNCTION__, "illegal RPC response\n" ); 1945 1946 // acknowledge the IPI sent by the server 1947 dev_pic_ack_ipi(); 1948 1949 } // end rpc_send_sync() 1950 1951 1952 1953 /***************************************************************************************/ 1954 /************ Generic functions supporting RPCs : server side **************************/ 1955 /***************************************************************************************/ 1956 1957 //////////////// 1958 void rpc_check() 1959 { 1960 error_t error; 1961 thread_t * thread; 1962 uint32_t sr_save; 1963 1964 bool_t found = false; 1965 thread_t * this = CURRENT_THREAD; 1966 core_t * core = this->core; 1967 scheduler_t * sched = &core->scheduler; 1968 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 1969 1970 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s / cycle %d\n", 1971 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 1972 1973 // interrupted thread not preemptable during RPC chek 1974 hal_disable_irq( &sr_save ); 1975 1976 // check RPC FIFO not empty and no RPC thread handling it 1977 if( (rpc_fifo->owner == 0) && (local_fifo_is_empty(rpc_fifo) == false) ) 1978 { 1979 // search one non blocked RPC thread 1980 list_entry_t * iter; 1981 LIST_FOREACH( &sched->k_root , iter ) 1982 { 1983 thread = LIST_ELEMENT( iter , thread_t , sched_list ); 1984 if( (thread->type == THREAD_RPC) && (thread->blocked == 0 ) ) 1985 { 1986 found = true; 1987 break; 1988 } 1989 } 1990 1991 // create new RPC thread if not found 1992 if( found == false ) 1993 { 1994 error = thread_kernel_create( &thread, 1995 THREAD_RPC, 1996 &rpc_thread_func, 1997 NULL, 1998 this->core->lid ); 1999 if( error ) 2000 { 2001 printk("\n[WARNING] in %s : no memory for new RPC thread in cluster %x\n", 2002 __FUNCTION__ , local_cxy ); 2003 } 2004 else 2005 { 2006 // unblock created RPC thread 2007 thread->blocked = 0; 2008 2009 // update core descriptor counter 2010 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , 1 ); 2011 2012 grpc_dmsg("\n[DBG] %s : core [%x,%d] creates a new RPC thread %x / cycle %d\n", 2013 __FUNCTION__ , local_cxy , core->lid , thread->trdid , hal_time_stamp() ); 2014 2015 } 2016 } 2017 } 2018 2019 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s deschedules / cycle %d\n", 2020 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 2021 2022 // interrupted thread deschedule always 2023 sched_yield("IPI received"); 2024 2025 grpc_dmsg("\n[DBG] %s : core[%x,%d] / interrupted thread %s resume / cycle %d\n", 2026 __FUNCTION__, local_cxy, core->lid, thread_type_str(this->type), hal_time_stamp() ); 2027 2028 // interrupted thread restore IRQs after resume 2029 hal_restore_irq( sr_save ); 2030 2031 } // end rpc_check() 2032 2033 2034 ////////////////////// 2035 void rpc_thread_func() 2036 { 2037 uint32_t count; // handled RPC requests counter 2038 error_t empty; // local RPC fifo state 2039 xptr_t desc_xp; // extended pointer on RPC request 2040 cxy_t desc_cxy; // RPC request cluster (client) 2041 rpc_desc_t * desc_ptr; // RPC request local pointer 2042 uint32_t index; // RPC request index 2043 uint32_t responses; // number of responses received by client 2044 thread_t * thread_ptr; // local pointer on client thread 2045 lid_t core_lid; // local index of client core 2046 2047 // makes RPC thread not preemptable 2048 hal_disable_irq( NULL ); 2049 2050 thread_t * this = CURRENT_THREAD; 2051 remote_fifo_t * rpc_fifo = &LOCAL_CLUSTER->rpc_fifo; 2052 2053 // two embedded loops: 2054 // - external loop : "infinite" RPC thread 2055 // - internal loop : handle up to CONFIG_RPC_PENDING_MAX RPC requests 2056 2057 while(1) // external loop 2058 { 2059 // try to take RPC_FIFO ownership 2060 if( hal_atomic_test_set( &rpc_fifo->owner , this->trdid ) ) 2061 { 2062 // initializes RPC requests counter 2063 count = 0; 2064 2065 // acknowledge local IPI 2066 dev_pic_ack_ipi(); 2067 2068 // exit internal loop in three cases: 2069 // - RPC fifo is empty 2070 // - ownership has been lost (because descheduling) 2071 // - max number of RPCs is reached 2072 while( 1 ) // internal loop 2073 { 2074 empty = local_fifo_get_item( rpc_fifo , (uint64_t *)&desc_xp ); 2075 2076 if ( empty == 0 ) // one RPC request found 2077 { 2078 // get client cluster and pointer on RPC descriptor 2079 desc_cxy = (cxy_t)GET_CXY( desc_xp ); 2080 desc_ptr = (rpc_desc_t *)GET_PTR( desc_xp ); 2081 2082 // get rpc index from RPC descriptor 2083 index = hal_remote_lw( XPTR( desc_cxy , &desc_ptr->index ) ); 2084 2085 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / starts rpc %d / cycle %d\n", 2086 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 2087 2088 // call the relevant server function 2089 rpc_server[index]( desc_xp ); 2090 2091 grpc_dmsg("\n[DBG] %s : core[%x,%d] / RPC thread %x / completes rpc %d / cycle %d\n", 2092 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , index , hal_time_stamp() ); 2093 2094 // increment handled RPC counter 2095 count++; 2096 2097 // decrement response counter in RPC descriptor 2098 responses = hal_remote_atomic_add(XPTR( desc_cxy, &desc_ptr->response ), -1); 2099 2100 // unblock client thread and send IPI to client core if last response 2101 if( responses == 1 ) 2102 { 2103 // get pointer on client thread and unblock it 2104 thread_ptr = (thread_t *)hal_remote_lpt(XPTR(desc_cxy,&desc_ptr->thread)); 2105 thread_unblock( XPTR(desc_cxy,thread_ptr) , THREAD_BLOCKED_RPC ); 2106 2107 hal_fence(); 2108 2109 // get client core lid and send IPI 2110 core_lid = hal_remote_lw(XPTR(desc_cxy, &desc_ptr->lid)); 2111 dev_pic_send_ipi( desc_cxy , core_lid ); 2112 } 2113 } 2114 2115 // chek exit condition 2116 if( local_fifo_is_empty( rpc_fifo ) || 2117 (rpc_fifo->owner != this->trdid) || 2118 (count >= CONFIG_RPC_PENDING_MAX) ) break; 2119 } // end internal loop 2120 2121 // release rpc_fifo ownership if not lost 2122 if( rpc_fifo->owner == this->trdid ) rpc_fifo->owner = 0; 2123 } 2124 2125 // sucide if too many RPC threads in cluster 2126 if( LOCAL_CLUSTER->rpc_threads >= CONFIG_RPC_THREADS_MAX ) 2127 { 2128 2129 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) suicide at cycle %d\n", 2130 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2131 2132 // update RPC threads counter 2133 hal_atomic_add( &LOCAL_CLUSTER->rpc_threads , -1 ); 2134 2135 // suicide 2136 thread_exit(); 2137 } 2138 2139 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) deschedules / cycle %d\n", 2140 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2141 2142 // deschedule without blocking 2143 sched_yield("RPC fifo empty or too much work"); 2144 2145 grpc_dmsg("\n[DBG] %s : core[%x,%d] (RPC thread %x) resumes / cycle %d\n", 2146 __FUNCTION__, local_cxy, this->core->lid, this->trdid, hal_time_stamp() ); 2147 2148 } // end external loop 2149 2150 } // end rpc_thread_func() 2151 2152 2306
Note: See TracChangeset
for help on using the changeset viewer.