Changeset 709 for soft/giet_vm/giet_kernel/ctx_handler.c
- Timestamp:
- Oct 1, 2015, 4:20:46 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_kernel/ctx_handler.c
r707 r709 9 9 #include <sys_handler.h> 10 10 #include <giet_config.h> 11 #include <fat32.h> 11 12 #include <hard_config.h> 12 13 #include <utils.h> 13 14 #include <tty0.h> 14 15 #include <xcu_driver.h> 16 #include <bdv_driver.h> 15 17 16 18 ///////////////////////////////////////////////////////////////////////////////// … … 19 21 20 22 // defined in giet_kernel/switch.s file 21 extern void _t ask_switch(unsigned int *, unsigned int *);23 extern void _thread_switch( thread_context_t* , thread_context_t* ); 22 24 23 25 // allocated in boot.c or kernel_init.c files 24 26 extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 25 27 26 27 /////////////////////////////////////////////// 28 static void _ctx_kill_task( unsigned int ltid ) 28 // allocated in kernel_init.c file 29 extern fat_desc_t _fat; 30 31 ////////////////////////////////////////////////////////////////// 32 // This function is called by the _ctx_switch() function. 33 // It desactivates a thread that received a KILL signal. 34 // We must release all ressources allocated to the thread 35 // before the actual desactivation, that uses NORUN_MASK_THREAD. 36 ////////////////////////////////////////////////////////////////// 37 static void _ctx_kill_thread( unsigned int x, 38 unsigned int y, 39 unsigned int p, 40 unsigned int ltid ) 29 41 { 30 42 // get scheduler address 31 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 32 33 // pretend the task to kill is scheduled (required for sys_handler calls) 34 unsigned int cur_task = psched->current; 43 static_scheduler_t* psched = _schedulers[x][y][p]; 44 45 // pretend the thread to kill is the currently scheduled thread 46 // (required by the _sys_***_release() calls) 47 unsigned int cur_thread = psched->current; 35 48 psched->current = ltid; 36 49 50 // release BDV lock if taken and reset BDV peripheral 51 if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_BDV ) 52 { 53 _bdv_set_register( BLOCK_DEVICE_STATUS , 0 ); 54 _spin_lock_release( &_bdv_lock ); 55 } 56 57 // release FAT lock if taken 58 if ( psched->context[ltid].slot[CTX_LOCKS_ID] & LOCKS_MASK_FAT ) 59 { 60 _spin_lock_release( &_fat.fat_lock ); 61 } 62 37 63 // release private TTY terminal if required 38 if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS ) 39 { 40 _sys_tty_release(); 41 psched->context[ltid][CTX_TTY_ID] = -1; 42 } 64 if ( psched->context[ltid].slot[CTX_TTY_ID] < NB_TTY_CHANNELS ) 65 _sys_tty_release(); 43 66 44 67 // release private TIM channel if required 45 if ( psched->context[ltid][CTX_TIM_ID] < NB_TIM_CHANNELS ) 68 69 if ( psched->context[ltid].slot[CTX_TIM_ID] < NB_TIM_CHANNELS ) 46 70 { 47 71 _sys_tim_release(); 48 psched->context[ltid][CTX_TIM_ID] = -1; 49 } 50 51 // release private NIC_RX channel if required 52 if ( psched->context[ltid][CTX_NIC_RX_ID] < NB_NIC_CHANNELS ) 72 } 73 74 // release private NIC_RX and CMA_RX channels if required 75 if ( psched->context[ltid].slot[CTX_NIC_RX_ID] < NB_NIC_CHANNELS ) 53 76 { 54 77 _sys_nic_release( 1 ); 55 psched->context[ltid][CTX_NIC_RX_ID] = -1; 56 } 57 58 // release private NIC_TX channel if required 59 if ( psched->context[ltid][CTX_NIC_TX_ID] < NB_NIC_CHANNELS ) 78 } 79 80 // release private NIC_TX and CMA_TX channels if required 81 if ( psched->context[ltid].slot[CTX_NIC_TX_ID] < NB_NIC_CHANNELS ) 60 82 { 61 83 _sys_nic_release( 0 ); 62 psched->context[ltid][CTX_NIC_TX_ID] = -1;63 84 } 64 85 65 86 // release private FBF_CMA channel if required 66 if ( psched->context[ltid] [CTX_CMA_FB_ID] < NB_CMA_CHANNELS )87 if ( psched->context[ltid].slot[CTX_CMA_FB_ID] < NB_CMA_CHANNELS ) 67 88 { 68 89 _sys_fbf_cma_release(); 69 psched->context[ltid][CTX_CMA_FB_ID] = -1; 70 } 71 72 // restore scheduled task 73 psched->current = cur_task; 74 75 // set NORUN_MASK_TASK bit 76 _atomic_or( &psched->context[ltid][CTX_NORUN_ID], NORUN_MASK_TASK ); 77 78 } // end _ctx_kill_task() 79 80 81 ////////////////////////////////// 82 void _ctx_display( unsigned int x, 83 unsigned int y, 84 unsigned int p, 85 unsigned int ltid, 86 char* string ) 87 { 88 static_scheduler_t* psched = _schedulers[x][y][p]; 89 _printf("\n########## task[%d,%d,%d,%d] context\n" 90 " - CTX_EPC = %x\n" 91 " - CTX_PTAB = %x\n" 92 " - CTX_PTPR = %x\n" 93 " - CTX_VSID = %x\n" 94 " - CTX_SR = %x\n" 95 " - CTX_RA = %x\n" 96 " - CTX_SP = %x\n" 97 " - CTX_NORUN = %x\n" 98 " - CTX_SIG = %x\n" 99 "########## %s\n", 100 x , y , p , ltid , 101 psched->context[ltid][CTX_EPC_ID], 102 psched->context[ltid][CTX_PTAB_ID], 103 psched->context[ltid][CTX_PTPR_ID], 104 psched->context[ltid][CTX_VSID_ID], 105 psched->context[ltid][CTX_SR_ID], 106 psched->context[ltid][CTX_RA_ID], 107 psched->context[ltid][CTX_SP_ID], 108 psched->context[ltid][CTX_NORUN_ID], 109 psched->context[ltid][CTX_SIG_ID], 110 string ); 111 } // _ctx_display() 90 } 91 92 // restore scheduled thread index 93 psched->current = cur_thread; 94 95 // set NORUN_MASK_THREAD bit to desactivate the target thread 96 psched->context[ltid].slot[CTX_NORUN_ID] = NORUN_MASK_THREAD; 97 98 } // end _ctx_kill_thread() 112 99 113 100 114 101 ////////////////// 115 102 void _ctx_switch() 116 {117 unsigned int gpid = _get_procid();118 unsigned int cluster_xy = gpid >> P_WIDTH;119 unsigned int lpid = gpid & ((1<<P_WIDTH)-1);120 121 // get scheduler address122 static_scheduler_t* psched = (static_scheduler_t*)_get_sched();123 124 // get number of tasks allocated to scheduler125 unsigned int tasks = psched->tasks;126 127 // get current task index128 unsigned int curr_task_id = psched->current;129 130 // select the next task using a round-robin policy131 unsigned int next_task_id;132 unsigned int tid;133 unsigned int found = 0;134 135 for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++)136 {137 next_task_id = tid % tasks;138 139 // this task needs to be killed140 if ( psched->context[next_task_id][CTX_SIG_ID] & SIG_MASK_KILL )141 {142 // acknowledge signal143 _atomic_and( &psched->context[next_task_id][CTX_SIG_ID], ~SIG_MASK_KILL );144 145 _ctx_kill_task( next_task_id );146 }147 148 // test if the task is runable149 if ( psched->context[next_task_id][CTX_NORUN_ID] == 0 )150 {151 found = 1;152 // TODO: don't break to process all pending signals.153 break;154 }155 }156 157 // launch "idle" task if no runable task158 if (found == 0) next_task_id = IDLE_TASK_INDEX;159 160 #if ( GIET_DEBUG_SWITCH & 0x1 )161 unsigned int x = cluster_xy >> Y_WIDTH;162 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);163 if ( _get_proctime() > GIET_DEBUG_SWITCH )164 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n",165 curr_task_id, next_task_id, x, y , lpid, _get_proctime() );166 #endif167 168 if (curr_task_id != next_task_id) // actual task switch required169 {170 unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]);171 unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]);172 173 // reset TICK timer counter.174 _xcu_timer_reset_cpt( cluster_xy, lpid );175 176 // set current task index177 psched->current = next_task_id;178 179 // makes context switch180 _task_switch( curr_ctx_vaddr , next_ctx_vaddr );181 }182 } //end _ctx_switch()183 184 185 /////////////////186 void _idle_task()187 103 { 188 104 unsigned int gpid = _get_procid(); … … 192 108 unsigned int p = gpid & ((1<<P_WIDTH)-1); 193 109 110 unsigned int ltid; // index for loops on threads in scheduler 111 112 // get calling thread scheduler address 113 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 114 115 // get number of threads allocated to scheduler 116 unsigned int threads = psched->threads; 117 118 // get current thread ltid 119 unsigned int curr_thread_id = psched->current; 120 121 // first loop on threads: handle all pending KILL signals 122 for ( ltid = 0 ; ltid < threads ; ltid++ ) 123 { 124 if ( psched->context[ltid].slot[CTX_SIGS_ID] & SIGS_MASK_KILL ) 125 { 126 // acknowledge KILL signal 127 _atomic_and( &psched->context[ltid].slot[CTX_SIGS_ID], ~SIGS_MASK_KILL ); 128 129 // desactivate the killed thread 130 _ctx_kill_thread( x , y , p , ltid ); 131 } 132 } 133 134 // second loop: select next thread using a round-robin policy 135 unsigned int next_thread_id; 136 unsigned int found = 0; 137 for ( ltid = curr_thread_id + 1 ; ltid < (curr_thread_id + 1 + threads) ; ltid++ ) 138 { 139 next_thread_id = ltid % threads; 140 141 // test if the thread is runable 142 if ( psched->context[next_thread_id].slot[CTX_NORUN_ID] == 0 ) 143 { 144 found = 1; 145 break; 146 } 147 } 148 149 // launch idle_thread if no runable thread 150 if ( found == 0 ) next_thread_id = IDLE_THREAD_INDEX; 151 152 if ( curr_thread_id != next_thread_id ) // actual thread switch required 153 { 154 155 #if GIET_DEBUG_SWITCH 156 unsigned int x = cluster_xy >> Y_WIDTH; 157 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 158 if ( (_get_proctime() > GIET_DEBUG_SWITCH) && (x == 0) && (y == 0) && (p == 0) ) 159 _printf("\n[DEBUG SWITCH] (%d) -> (%d) on processor[%d,%d,%d] at cycle %d\n", 160 curr_thread_id, next_thread_id, x, y , p, _get_proctime() ); 161 #endif 162 163 thread_context_t* curr_ctx_vaddr = &(psched->context[curr_thread_id]); 164 thread_context_t* next_ctx_vaddr = &(psched->context[next_thread_id]); 165 166 // reset TICK timer counter. 167 _xcu_timer_reset_cpt( cluster_xy, p ); 168 169 // set current thread index 170 psched->current = next_thread_id; 171 172 // makes context switch 173 _thread_switch( curr_ctx_vaddr , next_ctx_vaddr ); 174 } 175 } //end _ctx_switch() 176 177 178 /////////////////// 179 void _idle_thread() 180 { 181 unsigned int gpid = _get_procid(); 182 unsigned int cluster_xy = gpid >> P_WIDTH; 183 unsigned int x = cluster_xy >> Y_WIDTH; 184 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 185 unsigned int p = gpid & ((1<<P_WIDTH)-1); 186 194 187 while(1) 195 188 { 196 189 // initialize counter 197 unsigned int count = GIET_IDLE_T ASK_PERIOD;190 unsigned int count = GIET_IDLE_THREAD_PERIOD; 198 191 199 192 // decounting loop 200 193 asm volatile( 201 194 "move $3, %0 \n" 202 "_idle_t ask_loop: \n"195 "_idle_thread_loop: \n" 203 196 "addi $3, $3, -1 \n" 204 "bnez $3, _idle_t ask_loop \n"197 "bnez $3, _idle_thread_loop \n" 205 198 "nop \n" 206 199 :
Note: See TracChangeset
for help on using the changeset viewer.