Changeset 436 for trunk/kernel/kern/thread.c
- Timestamp:
- Mar 7, 2018, 9:02:03 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r433 r436 799 799 } // end thread_check_sched() 800 800 801 ///////////////////////////////////// 802 void thread_block( thread_t * thread, 803 uint32_t cause ) 804 { 801 ////////////////////////////////////// 802 void thread_block( xptr_t thread_xp, 803 uint32_t cause ) 804 { 805 // get thread cluster and local pointer 806 cxy_t cxy = GET_CXY( thread_xp ); 807 thread_t * ptr = GET_PTR( thread_xp ); 808 805 809 // set blocking cause 806 hal_ atomic_or( &thread->blocked, cause );810 hal_remote_atomic_or( XPTR( cxy , &ptr->blocked ) , cause ); 807 811 hal_fence(); 808 812 … … 810 814 uint32_t cycle = (uint32_t)hal_get_cycles(); 811 815 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 812 printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / state %x / cycle %d\n", 813 __FUNCTION__ , CURRENT_THREAD , thread , cause , thread->blocked , cycle ); 816 printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / cycle %d\n", 817 __FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle ); 818 #endif 819 820 #if (CONFIG_DEBUG_THREAD_BLOCK & 1) 821 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 822 sched_display( ptr->core->lid ); 814 823 #endif 815 824 … … 831 840 uint32_t cycle = (uint32_t)hal_get_cycles(); 832 841 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 833 printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / state %x / cycle %d\n", 834 __FUNCTION__ , CURRENT_THREAD , ptr , cause , ptr->blocked , cycle ); 842 printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / cycle %d\n", 843 __FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle ); 844 #endif 845 846 #if (CONFIG_DEBUG_THREAD_BLOCK & 1) 847 if( CONFIG_DEBUG_THREAD_BLOCK < cycle ) 848 sched_display( ptr->core->lid ); 835 849 #endif 836 850 … … 840 854 } // end thread_unblock() 841 855 842 ///////////////////////////////////// 843 void thread_kill( thread_t * target ) 844 { 845 volatile uint32_t rsp_count = 1; // responses counter 846 847 thread_t * killer = CURRENT_THREAD; 856 //////////////////////////////////// 857 void thread_kill( xptr_t target_xp, 858 bool_t is_exit, 859 bool_t is_forced ) 860 { 861 reg_t save_sr; // for critical section 862 bool_t attached; // target thread in attached mode 863 bool_t join_done; // joining thread arrived first 864 xptr_t killer_xp; // extended pointer on killer thread (this) 865 thread_t * killer_ptr; // pointer on killer thread (this) 866 cxy_t target_cxy; // target thread cluster 867 thread_t * target_ptr; // pointer on target thread 868 xptr_t joining_xp; // extended pointer on joining thread 869 thread_t * joining_ptr; // pointer on joining thread 870 cxy_t joining_cxy; // joining thread cluster 871 pid_t target_pid; // target process PID 872 cxy_t owner_cxy; // target process owner cluster 873 trdid_t target_trdid; // target thread identifier 874 ltid_t target_ltid; // target thread local index 875 xptr_t process_state_xp; // extended pointer on <term_state> in process 876 877 xptr_t target_flags_xp; // extended pointer on target thread <flags> 878 xptr_t target_join_lock_xp; // extended pointer on target thread <join_lock> 879 xptr_t target_join_xp_xp; // extended pointer on target thread <join_xp> 880 xptr_t target_process_xp; // extended pointer on target thread <process> 881 882 process_t * target_process; // pointer on target thread process 883 884 // get target thread cluster and pointer 885 target_cxy = GET_CXY( target_xp ); 886 target_ptr = GET_PTR( target_xp ); 887 888 // get killer thread pointers 889 killer_ptr = CURRENT_THREAD; 890 killer_xp = XPTR( local_cxy , killer_ptr ); 848 891 849 892 #if CONFIG_DEBUG_THREAD_KILL … … 851 894 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 852 895 printk("\n[DBG] %s : thread %x enter for target thread %x / cycle %d\n", 853 __FUNCTION__, killer, target, cycle ); 854 #endif 855 856 // set the global blocked bit in target thread descriptor. 857 thread_block( target , THREAD_BLOCKED_GLOBAL ); 858 859 // request target scheduler to deschedule the target thread 860 // when killer thread is not running on same core as target thread 861 if( killer->core->lid != target->core->lid ) 862 { 863 // set signal in target thread descriptor and in target scheduler 864 thread_set_req_ack( target , (void *)(&rsp_count) ); 865 866 // send an IPI to the target thread core. 867 dev_pic_send_ipi( local_cxy , target->core->lid ); 868 869 // poll the response 870 while( 1 ) 896 __FUNCTION__, killer_ptr, target_ptr, cycle ); 897 #endif 898 899 // block the target thread 900 thread_block( target_xp , THREAD_BLOCKED_GLOBAL ); 901 902 // get target thread attached mode 903 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 904 attached = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0); 905 906 // synchronize with the joining thread 907 // if the target thread is attached && not forced 908 909 if( attached && (is_forced == false) ) 910 { 911 // build extended pointers on target thread join fields 912 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 913 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 914 915 // enter critical section 916 hal_disable_irq( &save_sr ); 917 918 // take the join_lock in target thread descriptor 919 remote_spinlock_lock( target_join_lock_xp ); 920 921 // get join_done from target thread descriptor 922 join_done = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_JOIN_DONE) != 0); 923 924 if( join_done ) // joining thread arrived first 871 925 { 872 // exit when response received from scheduler 873 if( rsp_count == 0 ) break; 874 875 // deschedule without blocking 876 hal_fixed_delay( 1000 ); 926 // get extended pointer on joining thread 927 joining_xp = (xptr_t)hal_remote_lwd( target_join_xp_xp ); 928 joining_ptr = GET_PTR( joining_xp ); 929 joining_cxy = GET_CXY( joining_xp ); 930 931 // reset the join_done flag in target thread 932 hal_remote_atomic_and( target_flags_xp , ~THREAD_FLAG_JOIN_DONE ); 933 934 // unblock the joining thread 935 thread_unblock( joining_xp , THREAD_BLOCKED_JOIN ); 936 937 // release the join_lock in target thread descriptor 938 remote_spinlock_unlock( target_join_lock_xp ); 939 940 // restore IRQs 941 hal_restore_irq( save_sr ); 877 942 } 878 } 879 880 // set REQ_DELETE flag 881 hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE ); 943 else // this thread arrived first 944 { 945 // set the kill_done flag in target thread 946 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_KILL_DONE ); 947 948 // block this thread on BLOCKED_JOIN 949 thread_block( killer_xp , THREAD_BLOCKED_JOIN ); 950 951 // set extended pointer on killer thread in target thread 952 hal_remote_swd( target_join_xp_xp , killer_xp ); 953 954 // release the join_lock in target thread descriptor 955 remote_spinlock_unlock( target_join_lock_xp ); 956 957 // deschedule 958 sched_yield( "killer thread wait joining thread" ); 959 960 // restore IRQs 961 hal_restore_irq( save_sr ); 962 } 963 } // end if attached 964 965 // - if the target thread is the main thread 966 // => synchronize with the parent process main thread 967 // - if the target thread is not the main thread 968 // => simply mark the target thread for delete 969 970 // get pointer on target thread process 971 target_process_xp = XPTR( target_cxy , &target_ptr->process ); 972 target_process = (process_t *)hal_remote_lpt( target_process_xp ); 973 974 // get target process owner cluster 975 target_pid = hal_remote_lw( XPTR( target_cxy , &target_process->pid ) ); 976 owner_cxy = CXY_FROM_PID( target_pid ); 977 978 // get target thread local index 979 target_trdid = hal_remote_lw( XPTR( target_cxy , &target_ptr->trdid ) ); 980 target_ltid = LTID_FROM_TRDID( target_trdid ); 981 982 if( (owner_cxy == target_cxy) && (target_ltid == 0) ) // main thread 983 { 984 // get extended pointer on term_state in target process owner cluster 985 process_state_xp = XPTR( owner_cxy , &target_process->term_state ); 986 987 // set termination info in target process owner 988 if( is_exit ) hal_remote_atomic_or( process_state_xp , PROCESS_TERM_EXIT ); 989 else hal_remote_atomic_or( process_state_xp , PROCESS_TERM_KILL ); 882 990 883 991 #if CONFIG_DEBUG_THREAD_KILL 884 992 cycle = (uint32_t)hal_get_cycles; 885 993 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 886 printk("\n[DBG] %s : thread %x exit for target thread %x / cycle %d\n", 887 __FUNCTION__, killer, target, cycle ); 888 #endif 994 printk("\n[DBG] %s : thread %x exit for thread %x / main thread / cycle %d\n", 995 __FUNCTION__, killer_ptr, target_ptr, cycle ); 996 #endif 997 998 } 999 else // main thread 1000 { 1001 // set the REQ_DELETE flag in target thread descriptor 1002 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_REQ_DELETE ); 1003 1004 #if CONFIG_DEBUG_THREAD_KILL 1005 cycle = (uint32_t)hal_get_cycles; 1006 if( CONFIG_DEBUG_THREAD_KILL < cycle ) 1007 printk("\n[DBG] %s : thread %x exit for thread %x / not the main thread / cycle %d\n", 1008 __FUNCTION__, killer_ptr, target_ptr, cycle ); 1009 #endif 1010 1011 } 889 1012 890 1013 } // end thread_kill() … … 958 1081 target_thread_ltid = LTID_FROM_TRDID( trdid ); 959 1082 1083 // check trdid argument 1084 if( (target_thread_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || 1085 cluster_is_undefined( target_cxy ) ) return XPTR_NULL; 1086 960 1087 // get root of list of process descriptors in target cluster 961 1088 hal_remote_memcpy( XPTR( local_cxy , &root ), … … 987 1114 remote_spinlock_unlock( lock_xp ); 988 1115 989 // check target thread found 990 if( found == false ) 991 { 992 return XPTR_NULL; 993 } 1116 // check PID found 1117 if( found == false ) return XPTR_NULL; 994 1118 995 1119 // get target thread local pointer … … 997 1121 target_thread_ptr = (thread_t *)hal_remote_lpt( xp ); 998 1122 999 if( target_thread_ptr == NULL ) 1000 { 1001 return XPTR_NULL; 1002 } 1123 if( target_thread_ptr == NULL ) return XPTR_NULL; 1003 1124 1004 1125 return XPTR( target_cxy , target_thread_ptr );
Note: See TracChangeset
for help on using the changeset viewer.