Changeset 416 for trunk/kernel/kern/process.c
- Timestamp:
- Jan 4, 2018, 10:05:47 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/process.c
r415 r416 337 337 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 338 338 339 // get the lock protecting the list of local process descriptors339 // remove the process descriptor from local_list in cluster manager 340 340 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) ); 341 342 // remove the process descriptor from local_list in local cluster manager343 341 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); 344 345 // release the lock protecting the list of local process descriptors346 342 remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) ); 347 343 … … 356 352 remote_spinlock_unlock( copies_lock ); 357 353 354 // release the process PID to cluster manager 355 cluster_pid_release( process->pid ); 356 358 357 hal_fence(); 359 358 … … 370 369 vmm_destroy( process ); 371 370 372 process_dmsg("\n[DBG] %s for pid %d / page_faults = %d\n", 373 __FUNCTION__ , process->pid, process->vmm.pgfault_nr);371 // release memory allocated to process descriptor 372 process_free( process ); 374 373 375 374 } // end process_destroy() … … 393 392 xptr_t root_xp; // extended pointer on root of copies 394 393 xptr_t lock_xp; // extended pointer on lock protecting copies 395 xptr_t client_xp; // extended pointer on client thread396 uint32_t rsp_count; // number of expected responses397 xptr_t rsp_xp; // extended pointer on responses counter398 394 xptr_t iter_xp; // iterator on copies list 399 395 xptr_t process_xp; // extended pointer on process copy 400 396 cxy_t process_cxy; // process copy cluster identifier 401 397 process_t * process_ptr; // local pointer on process copy 402 403 sigaction_dmsg("\n[DBG] %s : enter for signal %s to process %x in cluster %x\n", 404 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy ); 405 406 thread_t * this = CURRENT_THREAD; 407 408 // get extended pointer on client thread and response counter 409 client_xp = XPTR( local_cxy , this ); 410 rsp_xp = XPTR( local_cxy , &rsp_count ); 398 uint32_t responses; // number of remote process copies 399 uint32_t rsp_count; // used to assert number of copies 400 401 rpc_desc_t rpc; // rpc descriptor allocated in stack 402 403 sigaction_dmsg("\n[DBG] %s : enter to %s process %x in cluster %x\n", 404 __FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy ); 405 406 thread_t * client = CURRENT_THREAD; 407 xptr_t client_xp = XPTR( local_cxy , client ); 408 409 // get local pointer on local cluster manager 410 cluster = LOCAL_CLUSTER; 411 411 412 412 // get owner cluster identifier and process lpid … … 414 414 lpid = LPID_FROM_PID( process->pid ); 415 415 416 assert( (owner_cxy == local_cxy) , __FUNCTION__ , "illegal cluster\n" ); 416 // check owner cluster 417 assert( (owner_cxy == local_cxy) , __FUNCTION__ , 418 "must be executed in the owner cluster\n" ); 417 419 418 // get local pointer on local cluster manager 419 cluster = LOCAL_CLUSTER; 420 // get number of remote copies 421 responses = cluster->pmgr.copies_nr[lpid] - 1; 422 rsp_count = 0; 423 424 // check action type 425 assert( ((action_type == DELETE_ALL_THREADS ) || 426 (action_type == BLOCK_ALL_THREADS ) || 427 (action_type == UNBLOCK_ALL_THREADS )), 428 __FUNCTION__ , "illegal action type" ); 429 430 // initialise rpc descriptor 431 rpc.index = RPC_PROCESS_SIGACTION; 432 rpc.response = responses; 433 rpc.blocking = false; 434 rpc.thread = client; 420 435 421 436 // get extended pointers on copies root, copies lock, and number of copies … … 423 438 lock_xp = XPTR( local_cxy , &cluster->pmgr.copies_lock[lpid] ); 424 439 425 // initialize responses number426 rsp_count = cluster->pmgr.copies_nr[lpid];427 428 440 // take the lock protecting the copies 429 441 remote_spinlock_lock( lock_xp ); 430 442 431 // send RPCs to all process copies443 // send RPCs to remote clusters 432 444 XLIST_FOREACH( root_xp , iter_xp ) 433 445 { … … 436 448 process_ptr = (process_t *)GET_PTR( process_xp ); 437 449 438 sigaction_dmsg("\n[DBG] %s : process = %x / pid = %x / ppid = %x\n", 439 __FUNCTION__ , process_ptr , process_ptr->pid , process_ptr->ppid ); 440 441 rpc_process_sigaction_client( process_cxy, 442 process_ptr, 443 action_type, 444 rsp_xp, 445 client_xp ); 450 // send RPC to remote clusters 451 if( process_cxy != local_cxy ) 452 { 453 454 sigaction_dmsg("\n[DBG] %s : send RPC to remote cluster %x\n", 455 __FUNCTION__ , process_cxy ); 456 457 rpc.args[0] = (uint64_t)action_type; 458 rpc.args[1] = (uint64_t)(intptr_t)process_ptr; 459 rpc_process_sigaction_client( process_cxy , &rpc ); 460 rsp_count++; 461 } 446 462 } 447 463 … … 449 465 remote_spinlock_unlock( lock_xp ); 450 466 451 // block and deschedule to wait response 452 thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC ); 453 sched_yield("BLOCKED on RPC"); 454 455 sigaction_dmsg("\n[DBG] %s : exit for signal %s to process %x in cluster %x\n", 456 __FUNCTION__ , process_action_str( action_type ) , process , local_cxy ); 467 // check number of copies... 468 assert( (rsp_count == responses) , __FUNCTION__ , 469 "unconsistent number of process copies : rsp_count = %d / responses = %d", 470 rsp_count , responses ); 471 472 // block and deschedule to wait RPC responses if required 473 if( responses ) 474 { 475 thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC ); 476 sched_yield("BLOCKED on RPC_PROCESS_SIGACTION"); 477 } 478 479 sigaction_dmsg("\n[DBG] %s : make action in owner cluster %x\n", 480 __FUNCTION__ , local_cxy ); 481 482 483 // call directly the relevant function in local owner cluster 484 if (action_type == DELETE_ALL_THREADS ) process_delete ( process , client_xp ); 485 else if (action_type == BLOCK_ALL_THREADS ) process_block ( process , client_xp ); 486 else if (action_type == UNBLOCK_ALL_THREADS ) process_unblock( process ); 487 488 sigaction_dmsg("\n[DBG] %s : exit after %s process %x in cluster %x\n", 489 __FUNCTION__ , process_action_str( action_type ) , process->pid , local_cxy ); 457 490 458 491 } // end process_sigaction() … … 460 493 //////////////////////////////////////// 461 494 void process_block( process_t * process, 462 xptr_t rsp_xp,463 495 xptr_t client_xp ) 464 496 { 465 497 thread_t * target; // pointer on target thread 466 498 uint32_t ltid; // index in process th_tbl 467 thread_t * killer; // killerthread pointer499 thread_t * requester; // requesting thread pointer 468 500 uint32_t count; // requests counter 469 volatile uint32_t sig_rsp_count; // responses counter 470 cxy_t client_cxy; // client thread cluster identifier 471 thread_t * client_ptr; // client thread pointer 472 core_t * client_core; // client thread core pointer 473 474 // get local killer thread pointer 475 killer = CURRENT_THREAD; 501 volatile uint32_t rsp_count; // responses counter 502 503 // get calling thread pointer 504 requester = CURRENT_THREAD; 476 505 477 506 sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n", … … 482 511 483 512 // initialize local responses counter 484 sig_rsp_count = process->th_nr;513 rsp_count = process->th_nr; 485 514 486 515 // loop on process threads to block and deschedule all threads in cluster … … 494 523 count++; 495 524 496 // set signal in target thread descriptor 497 thread_set_signal( target , (uint32_t *)sig_rsp_count ); 498 499 // set the global blocked bit in target thread descriptor. 500 thread_block( target , THREAD_BLOCKED_GLOBAL ); 501 502 // - if the killer thread and the target thread are not on the same core 503 // we want the scheduler of target thread to acknowlege the signal 504 // to be sure that the target thread is descheduled 505 // - if the killer thread and the target thread are on the same core 506 // we simply decrement the response counter. 507 if( killer->core->lid != target->core->lid ) 525 // - if the target thread is the client thread, we do nothing, 526 // and simply decrement the responses counter. 527 // - if the calling thread and the target thread are on the same core, 528 // we block the target thread, we don't ask ask anything to the scheduler, 529 // and simply decrement the responses counter. 530 // - if the calling thread and the target thread are not running on the same 531 // core, we ask the target scheduler to acknowlege the blocking 532 // to be sure that the target thread is not running. 533 534 if( XPTR( local_cxy , target ) == client_xp ) 508 535 { 536 // decrement responses counter 537 hal_atomic_add( (void *)&rsp_count , -1 ); 538 } 539 else if( requester->core->lid == target->core->lid ) 540 { 541 // set the global blocked bit in target thread descriptor. 542 thread_block( target , THREAD_BLOCKED_GLOBAL ); 543 544 // decrement responses counter 545 hal_atomic_add( (void *)&rsp_count , -1 ); 546 } 547 else 548 { 549 // set the global blocked bit in target thread descriptor. 550 thread_block( target , THREAD_BLOCKED_GLOBAL ); 551 552 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor 553 thread_set_req_ack( target , (void *)&rsp_count ); 554 555 // force scheduling on target thread 509 556 dev_pic_send_ipi( local_cxy , target->core->lid ); 510 557 } 511 else512 {513 hal_atomic_add( (void *)&sig_rsp_count , -1 );514 }515 558 } 516 559 } 517 560 518 // poll the reponses counter 561 // get lock protecting process th_tbl[] 562 spinlock_unlock( &process->th_lock ); 563 564 // wait all responses from schedulers 519 565 while( 1 ) 520 566 { 521 // exit loop when all responses received522 if ( sig_rsp_count == 0 ) break;567 // exit loop when all local responses received 568 if ( rsp_count == 0 ) break; 523 569 524 570 // wait 1000 cycles before retry … … 526 572 } 527 573 528 // acknowledge client thread & unblock client thread if last response529 client_cxy = GET_CXY( client_xp );530 client_ptr = (thread_t *)GET_PTR( client_xp );531 client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) );532 if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 )533 {534 thread_unblock( client_xp , THREAD_BLOCKED_RPC);535 dev_pic_send_ipi( client_cxy , client_core->lid );536 }537 538 574 sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n", 539 575 __FUNCTION__ , process->pid , local_cxy , count ); … … 541 577 } // end process_block() 542 578 543 ////////////////////////////////////////// 544 void process_unblock( process_t * process, 545 xptr_t rsp_xp, 546 xptr_t client_xp ) 579 /////////////////////////////////////////// 580 void process_unblock( process_t * process ) 547 581 { 548 582 thread_t * target; // pointer on target thead 549 583 uint32_t ltid; // index in process th_tbl 550 thread_t * killer; // killer thread pointer 551 uint32_t req_count; // requests counter 552 cxy_t client_cxy; // client thread cluster identifier 553 thread_t * client_ptr; // client thread pointer 554 core_t * client_core; // client thread core pointer 555 556 // get local killer thread pointer 557 killer = CURRENT_THREAD; 584 uint32_t count; // requests counter 558 585 559 586 sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x\n", … … 564 591 565 592 // loop on process threads to unblock all threads in cluster 566 // we use both "ltid" and "req_count" because it can exist "holes" in th_tbl 567 for( ltid = 0 , req_count = 0 ; 568 req_count < process->th_nr ; 569 ltid++ ) 593 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 594 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) 570 595 { 571 596 target = process->th_tbl[ltid]; … … 573 598 if( target != NULL ) // thread found 574 599 { 575 req_count++;600 count++; 576 601 577 602 // reset the global blocked bit in target thread descriptor. … … 580 605 } 581 606 582 // acknowledge client thread & unblock client thread if last response 583 client_cxy = GET_CXY( client_xp ); 584 client_ptr = (thread_t *)GET_PTR( client_xp ); 585 client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) ); 586 if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 ) 587 { 588 thread_unblock( client_xp , THREAD_BLOCKED_RPC); 589 dev_pic_send_ipi( client_cxy , client_core->lid ); 590 } 607 // get lock protecting process th_tbl[] 608 spinlock_unlock( &process->th_lock ); 591 609 592 610 sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x / %d threads blocked\n", 593 __FUNCTION__ , process->pid , local_cxy , req_count );611 __FUNCTION__ , process->pid , local_cxy , count ); 594 612 595 613 } // end process_unblock() … … 597 615 ///////////////////////////////////////// 598 616 void process_delete( process_t * process, 599 xptr_t rsp_xp,600 617 xptr_t client_xp ) 601 618 { 602 thread_t * t hread; // pointer on target thread619 thread_t * target; // pointer on target thread 603 620 uint32_t ltid; // index in process th_tbl 604 621 uint32_t count; // request counter 605 pid_t pid; // process PID 606 cxy_t client_cxy; // client thread cluster identifier 607 thread_t * client_ptr; // client thread pointer 608 core_t * client_core; // client thread core pointer 609 610 // get process PID 611 pid = process->pid; 622 thread_t * requester; // pointer on calling thread 612 623 613 624 sigaction_dmsg("\n[DBG] %s : enter for process %x in cluster %x at cycle %d\n", 614 __FUNCTION__ , pid , local_cxy , (uint32_t)hal_get_cycles() ); 615 616 // loop on threads to release memory allocated to threads 625 __FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() ); 626 627 // get calling thread pointer 628 requester = CURRENT_THREAD; 629 630 // get lock protecting process th_tbl[] 631 spinlock_lock( &process->th_lock ); 632 633 // loop on threads to set the REQ_DELETE flag 634 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 617 635 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) 618 636 { 619 t hread= process->th_tbl[ltid];620 621 if( t hread!= NULL ) // thread found637 target = process->th_tbl[ltid]; 638 639 if( target != NULL ) // thread found 622 640 { 623 641 count++; 624 642 625 // detach thread from parent if attached 626 if( (thread->flags & THREAD_FLAG_DETACHED) == 0 ) 627 thread_child_parent_unlink( thread->parent , XPTR( local_cxy , thread ) ); 628 629 // detach thread from process 630 process_remove_thread( thread ); 631 632 // remove thread from scheduler 633 sched_remove_thread( thread ); 634 635 // release memory allocated to thread 636 thread_destroy( thread ); 643 // delete only if the target is not the client 644 if( XPTR( local_cxy , target ) != client_xp ) 645 { 646 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE ); 647 } 637 648 } 638 649 } 639 650 640 // release memory allocated to process descriptors 641 // for all clusters other than the owner cluster 642 if( local_cxy != CXY_FROM_PID( process->pid ) ) process_destroy( process ); 643 644 // acknowledge client thread & unblock client thread if last response 645 client_cxy = GET_CXY( client_xp ); 646 client_ptr = (thread_t *)GET_PTR( client_xp ); 647 client_core = (core_t *)hal_remote_lpt( XPTR( client_cxy , &client_ptr->core ) ); 648 if( hal_remote_atomic_add( rsp_xp , -1 ) == 1 ) 649 { 650 thread_unblock( client_xp , THREAD_BLOCKED_RPC); 651 dev_pic_send_ipi( client_cxy , client_core->lid ); 652 } 651 // get lock protecting process th_tbl[] 652 spinlock_unlock( &process->th_lock ); 653 653 654 654 sigaction_dmsg("\n[DBG] %s : exit for process %x in cluster %x at cycle %d\n", 655 __FUNCTION__ , p id , local_cxy , (uint32_t)hal_get_cycles() );655 __FUNCTION__ , process->pid , local_cxy , (uint32_t)hal_get_cycles() ); 656 656 657 657 } // end process_delete() … … 951 951 952 952 // allocate a child PID from local cluster 953 error = cluster_pid_alloc( XPTR( local_cxy , process ), &new_pid );953 error = cluster_pid_alloc( process , &new_pid ); 954 954 if( (error != 0) || (new_pid == 0) ) 955 955 { … … 1037 1037 return 0; 1038 1038 1039 } // end process_make_fork() 1040 1041 /* deprecated because we don't wand to destroy the existing process descriptor 1039 } // end process_make_fork() 1040 1042 1041 1043 1042 ///////////////////////////////////////////////////// … … 1045 1044 { 1046 1045 char * path; // pathname to .elf file 1047 process_t * old; // local pointer on old process 1048 process_t * new; // local pointer on new process 1049 pid_t pid; // old process identifier 1050 thread_t * thread; // pointer on new thread 1046 process_t * old_process; // local pointer on old process 1047 process_t * new_process; // local pointer on new process 1048 pid_t old_pid; // old process identifier 1049 pid_t new_pid; // new (temporary) process identifier 1050 thread_t * old_thread; // pointer on new thread 1051 thread_t * new_thread; // pointer on new thread 1051 1052 pthread_attr_t attr; // main thread attributes 1052 1053 lid_t lid; // selected core local index … … 1054 1055 1055 1056 // get .elf pathname and PID from exec_info 1056 path = exec_info->path;1057 pid = exec_info->pid;1058 1059 // check local cluster is process owner1060 assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__,1061 "local cluster %x is not owner for process %x\n", local_cxy, pid );1057 path = exec_info->path; 1058 old_pid = exec_info->pid; 1059 1060 // this function must be executed by a thread running in owner cluster 1061 assert( (CXY_FROM_PID( old_pid ) == local_cxy), __FUNCTION__, 1062 "local cluster %x is not owner for process %x\n", local_cxy, old_pid ); 1062 1063 1063 1064 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n", 1064 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path ); 1065 1066 // get old process local pointer 1067 old = (process_t *)cluster_get_local_process_from_pid( pid ); 1065 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, old_pid , path ); 1066 1067 // get old process and thread local pointers 1068 old_process = (process_t *)cluster_get_local_process_from_pid( old_pid ); 1069 old_thread = CURRENT_THREAD; 1068 1070 1069 assert( (old != NULL ) , __FUNCTION__ , 1070 "process %x not found in cluster %x\n", pid , local_cxy ); 1071 if( old_process == NULL ) 1072 { 1073 printk("\n[ERROR] in %s : cannot get old process descriptor\n", __FUNCTION__ ); 1074 return -1; 1075 } 1071 1076 1072 1077 // allocate memory for new process descriptor 1073 new = process_alloc(); 1078 new_process = process_alloc(); 1079 1080 if( new_process == NULL ) 1081 { 1082 printk("\n[ERROR] in %s : cannot allocate new process descriptor\n", __FUNCTION__ ); 1083 return -1; 1084 } 1085 1086 // get a (temporary) PID for new process 1087 error = cluster_pid_alloc( new_process , &new_pid ); 1088 1089 if( error ) 1090 { 1091 printk("\n[ERROR] in %s : cannot allocate a temporary PID\n", __FUNCTION__ ); 1092 process_destroy( new_process ); 1093 return -1; 1094 } 1074 1095 1075 1096 // initialize new process descriptor 1076 process_reference_init( new ,1077 old->pid, // same as old1078 old ->ppid, // same as old1079 XPTR( local_cxy , old ) );1097 process_reference_init( new_process, 1098 new_pid, // temporary PID 1099 old_process->ppid, // same parent 1100 XPTR( local_cxy , old_process ) ); 1080 1101 1081 1102 exec_dmsg("\n[DBG] %s : core[%x,%d] created new process %x / path = %s\n", 1082 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid, path );1103 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, new_pid, path ); 1083 1104 1084 1105 // register "code" and "data" vsegs as well as entry-point 1085 1106 // in new process VMM, using information contained in the elf file. 1086 if( elf_load_process( path , new ) )1107 if( elf_load_process( path , new_process ) ) 1087 1108 { 1088 1109 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n", 1089 __FUNCTION__, pid , path ); 1090 process_destroy( new ); 1110 __FUNCTION__, new_pid , path ); 1111 cluster_pid_release( new_pid ); 1112 process_destroy( new_process ); 1091 1113 return -1; 1092 1114 } … … 1104 1126 1105 1127 // create and initialize thread descriptor 1106 error = thread_user_create( pid,1107 (void *)new ->vmm.entry_point,1128 error = thread_user_create( new_pid, 1129 (void *)new_process->vmm.entry_point, 1108 1130 exec_info->args_pointers, 1109 1131 &attr, 1110 & thread );1132 &new_thread ); 1111 1133 if( error ) 1112 1134 { 1113 1135 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n", 1114 __FUNCTION__, pid , path ); 1115 process_destroy( new ); 1136 __FUNCTION__, new_pid , path ); 1137 cluster_pid_release( new_pid ); 1138 process_destroy( new_process ); 1116 1139 return -1; 1117 1140 } 1118 1141 1119 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n", 1120 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid ); 1121 1122 // update children list (rooted in parent process) 1123 xlist_replace( XPTR( local_cxy , &old->brothers_list ) , 1124 XPTR( local_cxy , &new->brothers_list ) ); 1125 1126 // request destruction of old process copies and threads in all clusters 1127 process_sigaction( old , SIGKILL ); 1128 1142 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x\n", 1143 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, new_thread->trdid ); 1144 1145 // update children list rooted in parent process 1146 xlist_replace( XPTR( local_cxy , &old_process->brothers_list ) , 1147 XPTR( local_cxy , &new_process->brothers_list ) ); 1148 1149 // request blocking for all threads in old process (but the calling thread) 1150 process_sigaction( old_process , BLOCK_ALL_THREADS ); 1151 1152 // request destruction for all threads in old process (but the calling thread) 1153 process_sigaction( old_process , DELETE_ALL_THREADS ); 1154 1155 // update PID for both processes 1156 new_process->pid = old_pid; 1157 old_process->pid = 0xFFFFFFFF; 1158 1159 // release temporary PID 1160 cluster_pid_release( new_pid ); 1161 1129 1162 // activate new thread 1130 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL );1163 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 1131 1164 1132 1165 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n", 1133 1166 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 1134 1167 1168 // set BLOCKED_GLOBAL bit 1169 thread_block( old_thread , THREAD_BLOCKED_GLOBAL ); 1170 1171 // set REQ_DELETE flag 1172 hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE ); 1173 1174 // deschedule 1175 sched_yield("suicide after exec"); 1176 1177 // never executed but required by compiler 1135 1178 return 0; 1136 1179 1137 1180 } // end process_make_exec() 1138 1181 1139 */ 1140 1141 ///////////////////////////////////////////////////// 1142 error_t process_make_exec( exec_info_t * exec_info ) 1143 { 1144 char * path; // pathname to .elf file 1145 process_t * process; // local pointer on old process 1146 pid_t pid; // old process identifier 1147 thread_t * thread; // pointer on new main thread 1148 pthread_attr_t attr; // main thread attributes 1149 lid_t lid; // selected core local index 1150 error_t error; 1151 1152 // get .elf pathname and PID from exec_info 1153 path = exec_info->path; 1154 pid = exec_info->pid; 1155 1156 // check local cluster is process owner 1157 assert( (CXY_FROM_PID( pid ) == local_cxy), __FUNCTION__, 1158 "local cluster %x is not owner for process %x\n", local_cxy, pid ); 1159 1160 exec_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x / path = %s\n", 1161 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , path ); 1162 1163 // get process local pointer 1164 process = (process_t *)cluster_get_local_process_from_pid( pid ); 1165 1166 assert( (process != NULL ) , __FUNCTION__ , 1167 "process %x not found in cluster %x\n", pid , local_cxy ); 1168 1169 // reset the existing vmm 1170 vmm_destroy( process ); 1171 1172 exec_dmsg("\n[DBG] %s : core[%x,%d] VMM cleared\n", 1173 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid ); 1174 1175 // block all existing process threads 1176 process_sigaction( process , BLOCK_ALL_THREADS ); 1177 1178 // kill all existing threads and process descriptors (other than owner) 1179 process_sigaction( process , DELETE_ALL_THREADS ); 1180 1181 // check no threads 1182 assert( (process->th_nr == 0) , __FUNCTION__ , "no threads at this point" ); 1183 1184 exec_dmsg("\n[DBG] %s : core[%x,%d] all threads deleted\n", 1185 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid ); 1186 1187 // initialize VMM 1188 error = vmm_init( process ); 1189 { 1190 printk("\n[ERROR] in %s : cannot initialize VMM for process %x / path = %s\n", 1191 __FUNCTION__, pid , path ); 1192 process_destroy( process ); 1193 return -1; 1194 } 1195 1196 if( error ) 1197 1198 // register "code" and "data" vsegs as well as entry-point and vfs_bin_xp 1199 // in VMM, using information contained in the elf file. 1200 error = elf_load_process( path , process ); 1201 1202 if( error ) 1203 { 1204 printk("\n[ERROR] in %s : failed to access .elf file for process %x / path = %s\n", 1205 __FUNCTION__, pid , path ); 1206 process_destroy( process ); 1207 return -1; 1208 } 1209 1210 exec_dmsg("\n[DBG] %s : core[%x,%d] new vsegs registered / path = %s\n", 1211 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 1212 1213 // @@@ 1214 vmm_display( process , true ); 1215 // @@@ 1216 1217 // select a core in local cluster to execute the new main thread 1218 lid = cluster_select_local_core(); 1219 1220 // initialize pthread attributes for new main thread 1221 attr.attributes = PT_ATTR_DETACH | PT_ATTR_CLUSTER_DEFINED | PT_ATTR_CORE_DEFINED; 1222 attr.cxy = local_cxy; 1223 attr.lid = lid; 1224 1225 // create and initialize thread descriptor 1226 error = thread_user_create( pid, 1227 (void *)process->vmm.entry_point, 1228 exec_info->args_pointers, 1229 &attr, 1230 &thread ); 1231 if( error ) 1232 { 1233 printk("\n[ERROR] in %s : cannot create thread for process %x / path = %s\n", 1234 __FUNCTION__, pid , path ); 1235 process_destroy( process ); 1236 return -1; 1237 } 1238 1239 exec_dmsg("\n[DBG] %s : core[%x,%d] created main thread %x for new process %x\n", 1240 __FUNCTION__ , local_cxy, CURRENT_THREAD->core->lid, thread->trdid, pid ); 1241 1242 // activate new thread 1243 thread_unblock( XPTR( local_cxy , thread ) , THREAD_BLOCKED_GLOBAL ); 1244 1245 exec_dmsg("\n[DBG] %s : core[%x,%d] exit for path = %s\n", 1246 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, path ); 1247 1248 return 0; 1249 1250 } // end process_make_exec() 1251 1252 //////////////////////////////////////////// 1253 void process_make_kill( process_t * process, 1254 uint32_t sig_id ) 1182 /////////////////////////////////////// 1183 void process_make_kill( pid_t pid, 1184 uint32_t sig_id ) 1255 1185 { 1256 1186 // this function must be executed by a thread running in owner cluster 1257 assert( (CXY_FROM_PID( p rocess->pid ) == local_cxy) , __FUNCTION__ ,1187 assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , 1258 1188 "must execute in owner cluster" ); 1189 1190 kill_dmsg("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d\n", 1191 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id ); 1192 1193 // get pointer on local process descriptor 1194 process_t * process = process_get_local_copy( pid ); 1195 1196 // does nothing if process does not exist 1197 if( process == NULL ) 1198 { 1199 printk("\n[WARNING] %s : process %x does not exist => do nothing\n", 1200 __FUNCTION__ , pid ); 1201 return; 1202 } 1259 1203 1260 1204 // analyse signal type 1261 1205 switch( sig_id ) 1262 1206 { 1263 case SIGSTOP: // block all threads 1207 case SIGSTOP: // block all threads in all clusters 1264 1208 { 1265 1209 process_sigaction( process , BLOCK_ALL_THREADS ); 1266 1210 } 1267 1211 break; 1268 case SIGCONT: // unblock all threads 1212 case SIGCONT: // unblock all threads in all clusters 1269 1213 { 1270 1214 process_sigaction( process , UNBLOCK_ALL_THREADS ); … … 1273 1217 case SIGKILL: // block all threads, then delete all threads 1274 1218 { 1219 // block all threads (but the calling thread) 1275 1220 process_sigaction( process , BLOCK_ALL_THREADS ); 1221 1222 // delete all threads (but the calling thread) 1276 1223 process_sigaction( process , DELETE_ALL_THREADS ); 1277 process_destroy( process ); 1224 1225 // delete the calling thread if required 1226 thread_t * this = CURRENT_THREAD; 1227 1228 if( this->process == process ) 1229 { 1230 // set REQ_DELETE flag 1231 hal_atomic_or( &this->flags , THREAD_FLAG_REQ_DELETE ); 1232 1233 // deschedule 1234 sched_yield( "suicide after kill" ); 1235 } 1278 1236 } 1279 1237 break; 1280 1238 } 1239 1240 //@@@ 1241 sched_display( 0 ); 1242 //@@@ 1243 1244 kill_dmsg("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d \n", 1245 __FUNCTION__, local_cxy, CURRENT_THREAD->core->lid, pid , sig_id ); 1246 1281 1247 } // end process_make_kill() 1282 1248 1283 ///////////////////////////////////////// ///1284 void process_make_exit( p rocess_t * process,1249 ///////////////////////////////////////// 1250 void process_make_exit( pid_t pid, 1285 1251 uint32_t status ) 1286 1252 { 1287 1253 // this function must be executed by a thread running in owner cluster 1288 assert( (CXY_FROM_PID( p rocess->pid ) == local_cxy) , __FUNCTION__ ,1254 assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , 1289 1255 "must execute in owner cluster" ); 1290 1256 1291 // block all threads in all clusters 1257 // get pointer on local process descriptor 1258 process_t * process = process_get_local_copy( pid ); 1259 1260 // does nothing if process does not exist 1261 if( process == NULL ) 1262 { 1263 printk("\n[WARNING] %s : process %x does not exist => do nothing\n", 1264 __FUNCTION__ , pid ); 1265 return; 1266 } 1267 1268 // block all threads in all clusters (but the calling thread) 1292 1269 process_sigaction( process , BLOCK_ALL_THREADS ); 1293 1270 1294 // delete all threads in all clusters 1271 // delete all threads in all clusters (but the calling thread) 1295 1272 process_sigaction( process , DELETE_ALL_THREADS ); 1296 1273 1297 // delete local process descriptor 1298 process_destroy( process ); 1274 // delete the calling thread 1275 hal_atomic_or( &CURRENT_THREAD->flags , THREAD_FLAG_REQ_DELETE ); 1276 1277 // deschedule 1278 sched_yield( "suicide after exit" ); 1299 1279 1300 1280 } // end process_make_exit() … … 1322 1302 1323 1303 // get PID from local cluster 1324 error = cluster_pid_alloc( XPTR( local_cxy , process ), &pid );1304 error = cluster_pid_alloc( process , &pid ); 1325 1305 if( error ) 1326 1306 {
Note: See TracChangeset
for help on using the changeset viewer.