Changeset 436 for trunk/kernel/kern/process.c
- Timestamp:
- Mar 7, 2018, 9:02:03 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/process.c
r435 r436 365 365 cxy_t parent_cxy; 366 366 xptr_t children_lock_xp; 367 xptr_t copies_lock_xp;368 367 369 368 assert( (process->th_nr == 0) , __FUNCTION__ , … … 377 376 #endif 378 377 379 // get local process manager pointer 380 pmgr_t * pmgr = &LOCAL_CLUSTER->pmgr; 381 382 // remove process from local_list in cluster manager 383 remote_spinlock_lock( XPTR( local_cxy , &pmgr->local_lock ) ); 384 xlist_unlink( XPTR( local_cxy , &process->local_list ) ); 385 remote_spinlock_unlock( XPTR( local_cxy , &pmgr->local_lock ) ); 386 387 // get extended pointer on copies_lock in owner cluster manager 388 cxy_t owner_cxy = CXY_FROM_PID( process->pid ); 389 lpid_t lpid = LPID_FROM_PID( process->pid ); 390 copies_lock_xp = XPTR( owner_cxy , &pmgr->copies_lock[lpid] ); 391 392 // remove local process from copies_list 393 remote_spinlock_lock( copies_lock_xp ); 394 xlist_unlink( XPTR( local_cxy , &process->copies_list ) ); 395 remote_spinlock_unlock( copies_lock_xp ); 396 397 // for reference process only 398 if( XPTR( local_cxy , process ) == process->ref_xp ) 399 { 400 // remove reference process from txt_list 401 process_txt_detach( process ); 402 378 // remove process from local_list in local cluster manager 379 cluster_process_local_unlink( process ); 380 381 // remove process from copies_list in owner cluster manager 382 cluster_process_copies_unlink( process ); 383 384 // remove process from children_list if process is in owner cluster 385 if( CXY_FROM_PID( process->pid ) == local_cxy ) 386 { 403 387 // get pointers on parent process 404 388 parent_xp = process->parent_xp; … … 461 445 xptr_t process_xp; // extended pointer on process copy 462 446 cxy_t process_cxy; // process copy cluster identifier 463 process_t * process_ptr; // local pointer on process copy 464 uint32_t responses; // number of remote process copies 465 uint32_t rsp_count; // used to assert number of copies 466 rpc_desc_t rpc; // rpc descriptor allocated in stack 447 reg_t save_sr; // for critical section 448 rpc_desc_t rpc; // shared RPC descriptor 467 449 468 450 thread_t * client = CURRENT_THREAD; … … 475 457 #endif 476 458 477 // get localpointer on local cluster manager459 // get pointer on local cluster manager 478 460 cluster = LOCAL_CLUSTER; 479 461 … … 483 465 484 466 // get root of list of copies, lock, and number of copies from owner cluster 485 responses = hal_remote_lw ( XPTR( owner_cxy , &cluster->pmgr.copies_nr[lpid] ) ); 486 root_xp = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ) ); 487 lock_xp = hal_remote_lwd( XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ) ); 488 489 rsp_count = 0; 467 root_xp = XPTR( owner_cxy , &cluster->pmgr.copies_root[lpid] ); 468 lock_xp = XPTR( owner_cxy , &cluster->pmgr.copies_lock[lpid] ); 490 469 491 470 // check action type … … 494 473 (action_type == UNBLOCK_ALL_THREADS )), __FUNCTION__ , "illegal action type" ); 495 474 496 // initialise rpc descriptor 497 rpc.index = RPC_PROCESS_SIGACTION; 498 rpc.response = responses; 499 rpc.blocking = false; 500 rpc.thread = client; 475 // allocate a - shared - RPC descriptor in client thread stack 476 // it can be shared because all parallel, non-blocking, server threads 477 // use the same input arguments, and use the shared RPC response field 478 // but use 479 480 // the client thread makes the following sequence: 481 // 1. mask interrupts 482 // 2. block itself 483 // 3. send RPC requests to all copies 484 // 4. unmask interrupts 485 // 5. deschedule 486 487 // mask IRQs 488 hal_disable_irq( &save_sr); 489 490 // client register blocking condition for itself 491 thread_block( XPTR( local_cxy , client ) , THREAD_BLOCKED_RPC ); 501 492 502 493 // take the lock protecting the copies 503 494 remote_spinlock_lock( lock_xp ); 504 495 505 // send RPCs to remote clusters 496 // initialize shared RPC descriptor 497 rpc.response = 0; 498 rpc.blocking = false; 499 rpc.index = RPC_PROCESS_SIGACTION; 500 rpc.thread = client; 501 rpc.lid = client->core->lid; 502 rpc.args[0] = action_type; 503 rpc.args[1] = pid; 504 505 // send RPCs to all clusters containing process copiess 506 506 XLIST_FOREACH( root_xp , iter_xp ) 507 507 { 508 509 #if CONFIG_DEBUG_PROCESS_SIGACTION 510 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 511 printk("\n[DBG] %s : send RPC to %s process %x in cluster %x\n", 512 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy ); 513 #endif 514 // atomically increment responses counter 515 hal_atomic_add( (void *)&rpc.response , 1 ); 516 508 517 process_xp = XLIST_ELEMENT( iter_xp , process_t , copies_list ); 509 518 process_cxy = GET_CXY( process_xp ); 510 process_ptr = GET_PTR( process_xp ); 511 512 #if CONFIG_DEBUG_PROCESS_SIGACTION 513 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 514 printk("\n[DBG] %s : send RPC to cluster %x\n", __FUNCTION__ , process_cxy ); 515 #endif 516 517 // check PID 518 assert( (hal_remote_lw( XPTR( process_cxy , &process_ptr->pid) ) == pid), 519 __FUNCTION__ , "unconsistent PID value\n" ); 520 521 rpc.args[0] = (uint64_t)action_type; 522 rpc.args[1] = (uint64_t)pid; 519 520 // call RPC in target cluster 523 521 rpc_process_sigaction_client( process_cxy , &rpc ); 524 rsp_count++;525 522 } 526 523 … … 528 525 remote_spinlock_unlock( lock_xp ); 529 526 530 // check number of copies... 531 assert( (rsp_count == responses) , __FUNCTION__ , 532 "unconsistent number of process copies : rsp_count = %d / responses = %d", 533 rsp_count , responses ); 534 535 // block and deschedule to wait RPC responses 536 thread_block( CURRENT_THREAD , THREAD_BLOCKED_RPC ); 537 sched_yield("BLOCKED on RPC_PROCESS_SIGACTION"); 527 // restore IRQs 528 hal_restore_irq( save_sr); 529 530 // client deschedule : will be unblocked by the last RPC server thread 531 sched_yield("blocked on rpc_process_sigaction"); 538 532 539 533 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 541 535 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 542 536 printk("\n[DBG] %s : thread %x exit after %s process %x in cluster %x / cycle %d\n", 543 __FUNCTION__ , client, process_action_str( action_type ) , 544 process->pid , local_cxy , cycle ); 537 __FUNCTION__ , client, process_action_str( action_type ) , pid , local_cxy , cycle ); 545 538 #endif 546 539 … … 553 546 thread_t * this; // pointer on calling thread 554 547 uint32_t ltid; // index in process th_tbl 548 cxy_t owner_cxy; // target process owner cluster 555 549 uint32_t count; // requests counter 556 volatile uint32_t rsp_count; // responsescounter550 volatile uint32_t ack_count; // scheduler acknowledge counter 557 551 558 552 // get calling thread pointer 559 553 this = CURRENT_THREAD; 554 555 // get target process owner cluster 556 owner_cxy = CXY_FROM_PID( process->pid ); 560 557 561 558 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 569 566 spinlock_lock( &process->th_lock ); 570 567 571 // initialize local responses counter 572 rsp_count = process->th_nr; 573 574 // loop on process threads to block and deschedule all threads in cluster 568 // loop to block all threads but the main thread 575 569 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 576 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )570 for( ltid = 0 , count = 0 , ack_count = 0 ; count < process->th_nr ; ltid++ ) 577 571 { 578 572 target = process->th_tbl[ltid]; 579 573 580 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" ); 581 582 if( target != NULL ) // thread found 574 if( target != NULL ) // thread exist 583 575 { 584 576 count++; 585 577 586 // - if the calling thread and the target thread are on the same core, 587 // we block the target thread, we don't need confirmation from scheduler, 588 // and we simply decrement the responses counter. 589 // - if the calling thread and the target thread are not running on the same 590 // core, we ask the target scheduler to acknowlege the blocking 591 // to be sure that the target thread is not running. 592 593 if( this->core->lid == target->core->lid ) 578 // main thread should not be deleted 579 if( (ltid != 0) || (owner_cxy != local_cxy) ) 594 580 { 595 581 // set the global blocked bit in target thread descriptor. 596 thread_block( target , THREAD_BLOCKED_GLOBAL ); 597 598 // decrement responses counter 599 hal_atomic_add( (void *)&rsp_count , -1 ); 600 } 601 else 602 { 603 // set the global blocked bit in target thread descriptor. 604 thread_block( target , THREAD_BLOCKED_GLOBAL ); 605 606 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor 607 thread_set_req_ack( target , (void *)&rsp_count ); 608 609 // force scheduling on target thread 610 dev_pic_send_ipi( local_cxy , target->core->lid ); 582 thread_block( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL ); 583 584 // - if the calling thread and the target thread are on the same core, 585 // we don't need confirmation from scheduler, 586 // - if the calling thread and the target thread are not running on the same 587 // core, we ask the target scheduler to acknowlege the blocking 588 // to be sure that the target thread is not running. 589 590 if( this->core->lid != target->core->lid ) 591 { 592 // increment responses counter 593 hal_atomic_add( (void*)&ack_count , 1 ); 594 595 // set FLAG_REQ_ACK and &ack_rsp_count in target descriptor 596 thread_set_req_ack( target , (uint32_t *)&ack_count ); 597 598 // force scheduling on target thread 599 dev_pic_send_ipi( local_cxy , target->core->lid ); 600 } 611 601 } 612 602 } … … 616 606 spinlock_unlock( &process->th_lock ); 617 607 618 // wait a ll responses from schedulers608 // wait acknowledges 619 609 while( 1 ) 620 610 { 621 // exit loop when all local responses received622 if ( rsp_count == 0 ) break;611 // exit when all scheduler acknoledges received 612 if ( ack_count == 0 ) break; 623 613 624 614 // wait 1000 cycles before retry … … 656 646 spinlock_lock( &process->th_lock ); 657 647 658 // loop on process threads to unblock all threads in cluster648 // loop on process threads to unblock all threads 659 649 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 660 650 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) 661 651 { 662 652 target = process->th_tbl[ltid]; 663 664 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" );665 653 666 654 if( target != NULL ) // thread found … … 689 677 { 690 678 thread_t * target; // pointer on target thread 691 thread_t * this; // pointer on calling thread692 679 uint32_t ltid; // index in process th_tbl 693 uint32_t count; // request counter 694 cxy_t owner_cxy; // owner cluster identifier 695 696 // get calling thread pointer 697 this = CURRENT_THREAD; 698 owner_cxy = CXY_FROM_PID( process->pid ); 680 uint32_t count; // threads counter 699 681 700 682 #if CONFIG_DEBUG_PROCESS_SIGACTION … … 702 684 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 703 685 printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n", 704 __FUNCTION__ , this, process->pid , local_cxy , cycle );686 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle ); 705 687 #endif 706 688 … … 708 690 spinlock_lock( &process->th_lock ); 709 691 710 // loop on threads to set the REQ_DELETE flag692 // loop to set the REQ_DELETE flag on all threads but the main 711 693 // we use both "ltid" and "count" because it can exist "holes" in th_tbl 712 694 for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ ) … … 714 696 target = process->th_tbl[ltid]; 715 697 716 assert( (target != this) , __FUNCTION__ , "calling thread cannot be a target\n" ); 717 718 if( target != NULL ) // thread found 698 if( target != NULL ) 719 699 { 720 700 count++; 721 701 722 // the main thread should not be deleted 723 if( (owner_cxy != local_cxy) || (ltid != 0) ) 724 { 725 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE ); 726 } 702 thread_kill( XPTR( local_cxy , target ), 703 false, // is_exit 704 true ); // is_forced 727 705 } 728 706 } … … 735 713 if( CONFIG_DEBUG_PROCESS_SIGACTION < cycle ) 736 714 printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n", 737 __FUNCTION__ , this, process->pid , local_cxy , cycle );715 __FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle ); 738 716 #endif 739 717 … … 790 768 791 769 } // end process_get_local_copy() 770 771 //////////////////////////////////////////// 772 pid_t process_get_ppid( xptr_t process_xp ) 773 { 774 cxy_t process_cxy; 775 process_t * process_ptr; 776 xptr_t parent_xp; 777 cxy_t parent_cxy; 778 process_t * parent_ptr; 779 780 // get process cluster and local pointer 781 process_cxy = GET_CXY( process_xp ); 782 process_ptr = GET_PTR( process_xp ); 783 784 // get pointers on parent process 785 parent_xp = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) ); 786 parent_cxy = GET_CXY( parent_xp ); 787 parent_ptr = GET_PTR( parent_xp ); 788 789 return hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 790 } 792 791 793 792 ////////////////////////////////////////////////////////////////////////////////////////// … … 1067 1066 parent_process_xp ); 1068 1067 1069 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1068 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1070 1069 cycle = (uint32_t)hal_get_cycles(); 1071 1070 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1086 1085 } 1087 1086 1088 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1087 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1089 1088 cycle = (uint32_t)hal_get_cycles(); 1090 1089 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1112 1111 assert( (thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1113 1112 1114 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1113 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1115 1114 cycle = (uint32_t)hal_get_cycles(); 1116 1115 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1134 1133 vmm_set_cow( process ); 1135 1134 1136 #if CONFIG_DEBUG_PROCESS_MAKE_FORK1135 #if( CONFIG_DEBUG_PROCESS_MAKE_FORK & 1 ) 1137 1136 cycle = (uint32_t)hal_get_cycles(); 1138 1137 if( CONFIG_DEBUG_PROCESS_MAKE_FORK < cycle ) … … 1236 1235 1237 1236 // give TXT ownership to new_process 1238 process_txt_set_ownership( XPTR( local_cxy , new_process 1239 1240 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1237 process_txt_set_ownership( XPTR( local_cxy , new_process) ); 1238 1239 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1241 1240 cycle = (uint32_t)hal_get_cycles(); 1242 1241 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1255 1254 } 1256 1255 1257 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1256 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1258 1257 cycle = (uint32_t)hal_get_cycles(); 1259 1258 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1287 1286 assert( (new_thread->trdid == 0) , __FUNCTION__ , "main thread must have index 0\n" ); 1288 1287 1289 #if CONFIG_DEBUG_PROCESS_MAKE_EXEC1288 #if( CONFIG_DEBUG_PROCESS_MAKE_EXEC & 1 ) 1290 1289 cycle = (uint32_t)hal_get_cycles(); 1291 1290 if( CONFIG_DEBUG_PROCESS_MAKE_EXEC < cycle ) … … 1312 1311 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 1313 1312 1313 // detach old_process from TXT 1314 process_txt_detach( XPTR( local_cxy , old_process ) ); 1315 1314 1316 // request old_thread destruction => old_process destruction 1315 thread_block( old_thread, THREAD_BLOCKED_GLOBAL );1317 thread_block( XPTR( local_cxy , old_thread ) , THREAD_BLOCKED_GLOBAL ); 1316 1318 hal_atomic_or( &old_thread->flags , THREAD_FLAG_REQ_DELETE ); 1317 1319 … … 1600 1602 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1601 1603 printk("\n[DBG] %s : thread %x enter for process %x / txt_id = %d / cycle %d\n", 1602 __FUNCTION__, CURRENT_THREAD, process , txt_id, cycle );1603 #endif 1604 1605 // check process is reference1606 assert( ( process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ ,1607 "process is not the reference descriptor" );1604 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id, cycle ); 1605 #endif 1606 1607 // check process is in owner cluster 1608 assert( (CXY_FROM_PID( process->pid ) == local_cxy) , __FUNCTION__ , 1609 "process descriptor not in owner cluster" ); 1608 1610 1609 1611 // check terminal index … … 1629 1631 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1630 1632 printk("\n[DBG] %s : thread %x exit for process %x / txt_id = %d / cycle %d\n", 1631 __FUNCTION__, CURRENT_THREAD, process , txt_id , cycle );1633 __FUNCTION__, CURRENT_THREAD, process->pid, txt_id , cycle ); 1632 1634 #endif 1633 1635 1634 1636 } // end process_txt_attach() 1635 1637 1636 ////////////////////////////////////////////// 1637 void process_txt_detach( process_t * process ) 1638 { 1638 ///////////////////////////////////////////// 1639 void process_txt_detach( xptr_t process_xp ) 1640 { 1641 process_t * process_ptr; // local pointer on process in owner cluster 1642 cxy_t process_cxy; // process owner cluster 1643 pid_t process_pid; // process identifier 1644 xptr_t file_xp; // extended pointer on stdin file 1639 1645 xptr_t chdev_xp; // extended pointer on TXT_RX chdev 1640 1646 cxy_t chdev_cxy; // TXT_RX chdev cluster … … 1642 1648 xptr_t lock_xp; // extended pointer on list lock in chdev 1643 1649 1650 // get process cluster, local pointer, and PID 1651 process_cxy = GET_CXY( process_xp ); 1652 process_ptr = GET_PTR( process_xp ); 1653 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1654 1655 // check process descriptor in owner cluster 1656 assert( (CXY_FROM_PID( process_pid ) == process_cxy ) , __FUNCTION__ , 1657 "process descriptor not in owner cluster" ); 1658 1644 1659 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1645 1660 uint32_t cycle = (uint32_t)hal_get_cycles(); 1646 1661 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1647 1662 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n", 1648 __FUNCTION__, CURRENT_THREAD, process, cycle ); 1649 #endif 1650 1651 // check process is reference 1652 assert( (process->ref_xp == XPTR( local_cxy , process )) , __FUNCTION__ , 1653 "process is not the reference descriptor" ); 1654 1655 // get extended pointer on TXT_RX chdev 1656 chdev_xp = chdev_from_file( process->fd_array.array[0] ); 1663 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1664 #endif 1665 1666 // release TXT ownership (does nothing if not TXT owner) 1667 process_txt_transfer_ownership( process_xp ); 1668 1669 // get extended pointer on process stdin file 1670 file_xp = (xptr_t)hal_remote_lwd( XPTR( process_cxy , &process_ptr->fd_array.array[0] ) ); 1671 1672 // get pointers on TXT_RX chdev 1673 chdev_xp = chdev_from_file( file_xp ); 1657 1674 chdev_cxy = GET_CXY( chdev_xp ); 1658 1675 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp ); 1659 1676 1660 // get extended pointer on lock ofattached process list1677 // get extended pointer on lock protecting attached process list 1661 1678 lock_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.lock ); 1662 1679 1663 1680 // unlink process from attached process list 1664 1681 remote_spinlock_lock( lock_xp ); 1665 xlist_unlink( XPTR( local_cxy , &process->txt_list ) );1682 xlist_unlink( XPTR( process_cxy , &process_ptr->txt_list ) ); 1666 1683 remote_spinlock_unlock( lock_xp ); 1667 1684 1685 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1686 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1687 { 1688 xptr_t root_xp = XPTR( chdev_cxy , &chdev_ptr->ext.txt.root ); 1689 xptr_t iter_xp; 1690 XLIST_FOREACH( root_xp , iter_xp ) 1691 { 1692 xptr_t current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1693 process_t * current_ptr = GET_PTR( current_xp ); 1694 1695 printk("\n[DBG] %s : attached_process %x (pid = %x)\n", 1696 __FUNCTION__, current_ptr, current_ptr->pid ); 1697 } 1698 } 1699 #endif 1700 1668 1701 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1669 1702 cycle = (uint32_t)hal_get_cycles(); 1670 1703 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1671 printk("\n[DBG] %s : thread %x exit for process %x/ cycle %d\n",1672 __FUNCTION__, CURRENT_THREAD, process , cycle );1704 printk("\n[DBG] %s : thread %x exit / process %x detached from TXT / cycle %d\n", 1705 __FUNCTION__, CURRENT_THREAD, process->pid, cycle ); 1673 1706 #endif 1674 1707 … … 1680 1713 process_t * process_ptr; 1681 1714 cxy_t process_cxy; 1715 pid_t process_pid; 1682 1716 xptr_t file_xp; 1683 1717 xptr_t txt_xp; … … 1685 1719 cxy_t txt_cxy; 1686 1720 1687 // get cluster and local pointer on process1721 // get pointers on process in owner cluster 1688 1722 process_cxy = GET_CXY( process_xp ); 1689 1723 process_ptr = GET_PTR( process_xp ); 1724 1725 // get process PID 1726 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1727 1728 // check owner cluster 1729 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1730 "process descriptor not in owner cluster\n" ); 1731 1732 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1733 uint32_t cycle = (uint32_t)hal_get_cycles(); 1734 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1735 printk("\n[DBG] %s : thread %x enter for process %x / cycle %d\n", 1736 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1737 #endif 1690 1738 1691 1739 // get extended pointer on stdin pseudo file … … 1700 1748 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , process_xp ); 1701 1749 1750 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1751 cycle = (uint32_t)hal_get_cycles(); 1752 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1753 printk("\n[DBG] %s : thread %x exit for process %x / cycle %d\n", 1754 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1755 #endif 1756 1702 1757 } // end process_txt_set ownership() 1703 1758 1704 ///////////////////////////////////////////////////// 1705 void process_txt_reset_ownership( xptr_t process_xp ) 1706 { 1707 process_t * process_ptr; 1708 cxy_t process_cxy; 1709 xptr_t parent_xp; // extended pointer on parent process 1710 process_t * parent_ptr; 1711 cxy_t parent_cxy; 1759 //////////////////////////////////////////////////////// 1760 void process_txt_transfer_ownership( xptr_t process_xp ) 1761 { 1762 process_t * process_ptr; // local pointer on process releasing ownership 1763 cxy_t process_cxy; // process cluster 1764 pid_t process_pid; // process identifier 1712 1765 xptr_t file_xp; // extended pointer on TXT_RX pseudo file 1713 1766 xptr_t txt_xp; // extended pointer on TXT_RX chdev … … 1717 1770 xptr_t owner_xp; // extended pointer on current TXT_RX owner 1718 1771 xptr_t root_xp; // extended pointer on root of attached process list 1772 xptr_t lock_xp; // extended pointer on lock protecting attached process list 1719 1773 xptr_t iter_xp; // iterator for xlist 1720 1774 xptr_t current_xp; // extended pointer on current process 1721 1775 process_t * current_ptr; // local pointer on current process 1722 1776 cxy_t current_cxy; // cluster for current process 1723 pid_t ppid; // parent process identifier for current process 1724 1725 // get cluster and local pointer on process 1777 1778 // get pointers on process in owner cluster 1726 1779 process_cxy = GET_CXY( process_xp ); 1727 1780 process_ptr = GET_PTR( process_xp ); 1781 1782 // get process PID 1783 process_pid = hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1784 1785 // check owner cluster 1786 assert( (process_cxy == CXY_FROM_PID( process_pid )) , __FUNCTION__, 1787 "process descriptor not in owner cluster\n" ); 1788 1789 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1790 uint32_t cycle = (uint32_t)hal_get_cycles(); 1791 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1792 printk("\n[DBG] %s : thread %x enter / process %x / pid %x / cycle %d\n", 1793 __FUNCTION__, CURRENT_THREAD, process_ptr, process_pid, cycle ); 1794 #endif 1728 1795 1729 1796 // get extended pointer on stdin pseudo file … … 1739 1806 txt_id = hal_remote_lw ( XPTR( txt_cxy , &txt_ptr->channel ) ); 1740 1807 1741 // transfer ownership to KSH if required 1742 if( (owner_xp == process_xp) && (txt_id > 0) ) 1743 { 1744 // get extended pointer on root of list of attached processes 1745 root_xp = hal_remote_lwd( XPTR( txt_cxy , &txt_ptr->ext.txt.root ) ); 1746 1747 // scan attached process list to find KSH process 1748 XLIST_FOREACH( root_xp , iter_xp ) 1808 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1809 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1810 printk("\n[DBG] %s : file_ptr %x / txt_ptr %x / txt_id %d / owner_ptr = %x\n", 1811 __FUNCTION__, GET_PTR(file_xp), txt_ptr, txt_id, GET_PTR(owner_xp) ); 1812 #endif 1813 1814 // transfer ownership only if process is the TXT owner 1815 if( (owner_xp == process_xp) && (txt_id > 0) ) 1816 { 1817 // get extended pointers on root and lock of attached processes list 1818 root_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.root ); 1819 lock_xp = XPTR( txt_cxy , &txt_ptr->ext.txt.lock ); 1820 1821 // get lock 1822 remote_spinlock_lock( lock_xp ); 1823 1824 if( process_get_ppid( process_xp ) != 1 ) // process is not KSH 1749 1825 { 1750 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1751 current_cxy = GET_CXY( current_xp ); 1752 current_ptr = GET_PTR( current_xp ); 1753 parent_xp = hal_remote_lwd( XPTR( current_cxy , ¤t_ptr->parent_xp ) ); 1754 parent_cxy = GET_CXY( parent_xp ); 1755 parent_ptr = GET_PTR( parent_xp ); 1756 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 1757 1758 printk("\n@@@ %s : pid = %x / process = %x\n", __FUNCTION__ , current_ptr->pid, current_ptr ); 1759 1760 if( ppid == 1 ) // current is KSH 1826 1827 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1828 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1829 printk("\n[DBG] %s : process is not the KSH process => search the KSH\n", __FUNCTION__ ); 1830 #endif 1831 // scan attached process list to find KSH process 1832 XLIST_FOREACH( root_xp , iter_xp ) 1761 1833 { 1762 // set owner field in TXT chdev 1763 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1764 return; 1834 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1835 current_cxy = GET_CXY( current_xp ); 1836 current_ptr = GET_PTR( current_xp ); 1837 1838 if( process_get_ppid( current_xp ) == 1 ) // current is KSH 1839 { 1840 // release lock 1841 remote_spinlock_unlock( lock_xp ); 1842 1843 // set owner field in TXT chdev 1844 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1845 1846 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1847 cycle = (uint32_t)hal_get_cycles(); 1848 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1849 printk("\n[DBG] %s : thread %x exit / process %x to KSH process %x / cycle %d\n", 1850 __FUNCTION__, CURRENT_THREAD, process_pid, 1851 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle ); 1852 #endif 1853 return; 1854 } 1765 1855 } 1856 1857 // release lock 1858 remote_spinlock_unlock( lock_xp ); 1859 1860 // PANIC if KSH not found 1861 assert( false , __FUNCTION__ , "KSH process not found for TXT %d" ); 1862 1863 return; 1766 1864 } 1767 1768 assert( false , __FUNCTION__ , "KSH process not found" ); 1769 } 1770 } // end process_txt_reset_ownership() 1771 1772 1773 ////////////////////////////////////////////////////// 1774 inline pid_t process_get_txt_owner( uint32_t channel ) 1865 else // process is KSH 1866 { 1867 1868 #if( CONFIG_DEBUG_PROCESS_TXT_ATTACH & 1 ) 1869 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1870 printk("\n[DBG] %s : process is the KSH process => search another\n", __FUNCTION__ ); 1871 #endif 1872 1873 // scan attached process list to find another process 1874 XLIST_FOREACH( root_xp , iter_xp ) 1875 { 1876 current_xp = XLIST_ELEMENT( iter_xp , process_t , txt_list ); 1877 current_cxy = GET_CXY( current_xp ); 1878 current_ptr = GET_PTR( current_xp ); 1879 1880 if( current_xp != process_xp ) // current is not KSH 1881 { 1882 // release lock 1883 remote_spinlock_unlock( lock_xp ); 1884 1885 // set owner field in TXT chdev 1886 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , current_xp ); 1887 1888 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1889 cycle = (uint32_t)hal_get_cycles(); 1890 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1891 printk("\n[DBG] %s : thread %x exit / KSH process %x to process %x / cycle %d\n", 1892 __FUNCTION__, CURRENT_THREAD, process_pid, 1893 hal_remote_lw( XPTR( current_cxy , ¤t_ptr->pid ) ), cycle ); 1894 #endif 1895 return; 1896 } 1897 } 1898 1899 // release lock 1900 remote_spinlock_unlock( lock_xp ); 1901 1902 // no more owner for TXT if no other process found 1903 hal_remote_swd( XPTR( txt_cxy , &txt_ptr->ext.txt.owner_xp ) , XPTR_NULL ); 1904 1905 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1906 cycle = (uint32_t)hal_get_cycles(); 1907 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1908 printk("\n[DBG] %s : thread %x exit / KSH process %x to nobody / cycle %d\n", 1909 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1910 #endif 1911 return; 1912 } 1913 } 1914 else 1915 { 1916 1917 #if CONFIG_DEBUG_PROCESS_TXT_ATTACH 1918 cycle = (uint32_t)hal_get_cycles(); 1919 if( CONFIG_DEBUG_PROCESS_TXT_ATTACH < cycle ) 1920 printk("\n[DBG] %s : thread %x exit / process %x is not TXT owner / cycle %d\n", 1921 __FUNCTION__, CURRENT_THREAD, process_pid, cycle ); 1922 #endif 1923 1924 } 1925 } // end process_txt_transfer_ownership() 1926 1927 1928 //////////////////////////////////////////////// 1929 xptr_t process_txt_get_owner( uint32_t channel ) 1775 1930 { 1776 1931 xptr_t txt_rx_xp = chdev_dir.txt_rx[channel]; … … 1778 1933 chdev_t * txt_rx_ptr = GET_PTR( txt_rx_xp ); 1779 1934 1780 xptr_t process_xp = (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy, 1781 &txt_rx_ptr->ext.txt.owner_xp ) ); 1782 1783 cxy_t process_cxy = GET_CXY( process_xp ); 1784 process_t * process_ptr = GET_PTR( process_xp ); 1785 1786 return (pid_t)hal_remote_lw( XPTR( process_cxy , &process_ptr->pid ) ); 1935 return (xptr_t)hal_remote_lwd( XPTR( txt_rx_cxy , &txt_rx_ptr->ext.txt.owner_xp ) ); 1787 1936 } 1788 1937 … … 1817 1966 remote_spinlock_lock( lock_xp ); 1818 1967 1819 // scan attached process list to find KSH process1968 // scan attached process list 1820 1969 XLIST_FOREACH( root_xp , iter_xp ) 1821 1970 {
Note: See TracChangeset
for help on using the changeset viewer.