Changeset 409 for trunk/kernel/kern/thread.c
- Timestamp:
- Dec 20, 2017, 4:51:09 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r408 r409 112 112 ///////////////////////////////////////////////////////////////////////////////////// 113 113 // This static function initializes a thread descriptor (kernel or user). 114 // It can be called by the fourfunctions:114 // It can be called by the three functions: 115 115 // - thread_user_create() 116 116 // - thread_user_fork() … … 164 164 165 165 thread->local_locks = 0; 166 list_root_init( &thread->locks_root );167 168 166 thread->remote_locks = 0; 167 168 #if CONFIG_LOCKS_DEBUG 169 list_root_init( &thread->locks_root ); 169 170 xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) ); 171 #endif 170 172 171 173 thread->u_stack_base = u_stack_base; … … 177 179 thread->entry_args = args; // thread function arguments 178 180 thread->flags = 0; // all flags reset 179 thread->signals = 0; // no pending signal180 181 thread->errno = 0; // no error detected 181 182 thread->fork_user = 0; // no user defined placement for fork 182 183 thread->fork_cxy = 0; // user defined target cluster for fork 183 184 // thread blocked 185 thread->blocked = THREAD_BLOCKED_GLOBAL; 184 thread->blocked = THREAD_BLOCKED_GLOBAL; 186 185 187 186 // reset children list … … 195 194 // reset thread info 196 195 memset( &thread->info , 0 , sizeof(thread_info_t) ); 196 197 // initializes join_lock 198 remote_spinlock_init( XPTR( local_cxy , &thread->join_lock ) ); 197 199 198 200 // initialise signature … … 296 298 return EINVAL; 297 299 } 298 299 // set LOADABLE flag300 thread->flags = THREAD_FLAG_LOADABLE;301 300 302 301 // set DETACHED flag if required … … 593 592 uint32_t tm_start; 594 593 uint32_t tm_end; 595 reg_t s tate;594 reg_t save_sr; 596 595 597 596 process_t * process = thread->process; … … 614 613 // release memory allocated for CPU context and FPU context 615 614 hal_cpu_context_destroy( thread ); 616 hal_fpu_context_destroy( thread );615 if ( thread->type == THREAD_USER ) hal_fpu_context_destroy( thread ); 617 616 618 617 // release FPU if required 619 618 // TODO This should be done before calling thread_destroy() 620 hal_disable_irq( &s tate);619 hal_disable_irq( &save_sr ); 621 620 if( core->fpu_owner == thread ) 622 621 { … … 624 623 hal_fpu_disable(); 625 624 } 626 hal_restore_irq( s tate);625 hal_restore_irq( save_sr ); 627 626 628 627 // remove thread from process th_tbl[] … … 668 667 xlist_add_first( root , entry ); 669 668 hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->children_nr ) , 1 ); 670 } 669 670 } // end thread_child_parent_link() 671 671 672 672 /////////////////////////////////////////////////// … … 693 693 // release the lock 694 694 remote_spinlock_unlock( lock ); 695 } 695 696 } // thread_child_parent_unlink() 696 697 697 698 ///////////////////////////////////////////////// 698 699 inline void thread_set_signal( thread_t * thread, 699 uint32_t mask ) 700 { 701 hal_atomic_or( &thread->signals , mask ); 700 uint32_t * sig_rsp_count ) 701 { 702 reg_t save_sr; // for critical section 703 704 // get pointer on thread thread scheduler 705 scheduler_t * thread_sched = &thread->core->scheduler; 706 707 // wait scheduler ready to handle a new signal 708 while( thread_sched->sig_pending ) asm volatile( "nop" ); 709 710 // enter critical section 711 hal_disable_irq( &save_sr ); 712 713 // set signal in thread scheduler 714 thread_sched->sig_pending = true; 715 716 // set signal in thread thread "flags" 717 hal_atomic_or( &thread->flags , THREAD_FLAG_SIGNAL ); 718 719 // set pointer on responses counter in thread thread 720 thread->sig_rsp_count = sig_rsp_count; 721 722 // exit critical section 723 hal_restore_irq( save_sr ); 724 702 725 hal_fence(); 703 } 704 705 /////////////////////////////////////////////////// 706 inline void thread_reset_signal( thread_t * thread, 707 uint32_t mask ) 708 { 709 hal_atomic_and( &thread->signals , ~mask ); 726 727 } // thread_set_signal() 728 729 //////////////////////////////////////////////////// 730 inline void thread_reset_signal( thread_t * thread ) 731 { 732 reg_t save_sr; // for critical section 733 734 // get pointer on target thread scheduler 735 scheduler_t * sched = &thread->core->scheduler; 736 737 // check signal pending in scheduler 738 assert( sched->sig_pending , __FUNCTION__ , "no pending signal" ); 739 740 // enter critical section 741 hal_disable_irq( &save_sr ); 742 743 // reset signal in scheduler 744 sched->sig_pending = false; 745 746 // reset signal in thread "flags" 747 hal_atomic_and( &thread->flags , ~THREAD_FLAG_SIGNAL ); 748 749 // reset pointer on responses counter 750 thread->sig_rsp_count = NULL; 751 752 // exit critical section 753 hal_restore_irq( save_sr ); 754 710 755 hal_fence(); 711 } 756 757 } // thread_reset_signal() 712 758 713 759 //////////////////////////////// … … 760 806 } // end thread_unblock() 761 807 762 /////////////////////763 error_t thread_exit()764 {765 reg_t sr_save;766 767 thread_t * this = CURRENT_THREAD;768 769 // test if this thread can be descheduled770 if( !thread_can_yield() )771 {772 printk("ERROR in %s : locks not released for thread %x in process %x on core[%x,%d]\n",773 __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid );774 return EINVAL;775 }776 777 if( this->flags & THREAD_FLAG_DETACHED )778 {779 // if detached set signal and set blocking cause atomically780 hal_disable_irq( &sr_save );781 thread_set_signal( this , THREAD_SIG_KILL );782 thread_block( this , THREAD_BLOCKED_EXIT );783 hal_restore_irq( sr_save );784 }785 else786 {787 // if attached, set blocking cause788 thread_block( this , THREAD_BLOCKED_EXIT );789 }790 791 // deschedule792 sched_yield( "exit" );793 return 0;794 795 } // end thread_exit()796 797 808 ///////////////////////////////////// 798 809 void thread_kill( thread_t * target ) 799 810 { 800 // set SIG_KILL signal in target thread descriptor 801 thread_set_signal( target , THREAD_SIG_KILL ); 811 volatile uint32_t sig_rsp_count = 1; // responses counter 812 813 thread_t * killer = CURRENT_THREAD; 814 815 kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n", 816 __FUNCTION__, local_cxy, killer->trdid , target trdid ); 802 817 803 818 // set the global blocked bit in target thread descriptor. 804 819 thread_block( target , THREAD_BLOCKED_GLOBAL ); 805 820 806 // send an IPI to schedule the target thread core. 807 dev_pic_send_ipi( local_cxy , target->core->lid ); 821 // request target scheduler to deschedule the target thread 822 // when killer thread is not running on same core as target thread 823 if( killer->core->lid != target->core->lid ) 824 { 825 // set signal in target thread descriptor and in target scheduler 826 thread_set_signal( target , (uint32_t *)(&sig_rsp_count) ); 827 828 // send an IPI to the target thread core. 829 dev_pic_send_ipi( local_cxy , target->core->lid ); 830 831 // poll the response 832 while( 1 ) 833 { 834 // exit when response received from scheduler 835 if( sig_rsp_count == 0 ) break; 836 837 // deschedule without blocking 838 hal_fixed_delay( 1000 ); 839 } 840 } 841 842 // release FPU if required 843 if( target->core->fpu_owner == target ) target->core->fpu_owner = NULL; 844 845 // detach thread from parent if attached 846 if( (target->flags & THREAD_FLAG_DETACHED) == 0 ) 847 thread_child_parent_unlink( target->parent , XPTR( local_cxy , target ) ); 848 849 // detach thread from process 850 process_remove_thread( target ); 851 852 // remove thread from scheduler 853 sched_remove_thread( target ); 854 855 // release memory allocated to target thread 856 thread_destroy( target ); 857 858 kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n", 859 __FUNCTION__, local_cxy, killer->trdid , target trdid ); 808 860 809 861 } // end thread_kill()
Note: See TracChangeset
for help on using the changeset viewer.