Changeset 279 for trunk/kernel/kern/scheduler.c
- Timestamp:
- Jul 27, 2017, 12:23:29 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/scheduler.c
r278 r279 41 41 sched->k_threads_nr = 0; 42 42 43 sched->current = NULL;44 sched->idle = NULL; 45 sched->u_last = NULL; 46 sched->k_last = NULL; 43 sched->current = CURRENT_THREAD; 44 sched->idle = NULL; // initialized in kernel_init() 45 sched->u_last = NULL; // initialized in sched_register_thread() 46 sched->k_last = NULL; // initialized in sched_register_thread() 47 47 48 48 // initialise threads lists … … 62 62 spinlock_lock( &sched->lock ); 63 63 64 // register thread65 64 if( type == THREAD_USER ) 66 65 { 66 // register thread in scheduler user list 67 67 list_add_last( &sched->u_root , &thread->sched_list ); 68 68 sched->u_threads_nr++; 69 70 // initialize u_last field if first user thread 71 if( sched->u_last == NULL ) sched->u_last = &thread->sched_list; 69 72 } 70 73 else // kernel thread 71 74 { 75 // register thread in scheduler kernel list 72 76 list_add_last( &sched->k_root , &thread->sched_list ); 73 77 sched->k_threads_nr++; 78 79 // initialize k_last field if first kernel thread 80 if( sched->k_last == NULL ) sched->k_last = &thread->sched_list; 74 81 } 75 82 … … 89 96 spinlock_lock( &sched->lock ); 90 97 91 // remove thread92 98 if( type == THREAD_USER ) 93 99 { 100 // remove thread from user list 94 101 list_unlink( &thread->sched_list ); 95 102 sched->u_threads_nr--; 103 104 // reset the u_last field if list empty 105 if( sched->u_threads_nr == 0 ) sched->u_last = NULL; 96 106 } 97 107 else // kernel thread 98 108 { 109 // remove thread from kernel list 99 110 list_unlink( &thread->sched_list ); 100 111 sched->k_threads_nr--; 112 113 // reset the k_last field if list empty 114 if( sched->k_threads_nr == 0 ) sched->k_last = NULL; 101 115 } 102 116 … … 140 154 list_entry_t * last; 141 155 142 // first scan the kernel threads 143 last = sched->k_last; 144 current = sched->k_last; 145 do 146 { 147 // get next entry in kernel list 148 current = list_next( &sched->k_root , current ); 149 150 // skip the list root that does not contain a thread 151 if( current == NULL ) continue; 152 153 // get thread pointer 154 thread = LIST_ELEMENT( current , thread_t , sched_list ); 155 156 // return thread if not blocked 157 if( thread->blocked == 0 ) 156 // first : scan the kernel threads list, 157 // only if this list is not empty 158 if( list_is_empty( &sched->k_root ) == false ) 159 { 160 last = sched->k_last; 161 current = sched->k_last; 162 do 158 163 { 159 // release lock 160 spinlock_unlock( &sched->lock ); 161 return thread; 164 // get next entry in kernel list 165 current = list_next( &sched->k_root , current ); 166 167 // skip the root that does not contain a thread 168 if( current == NULL ) current = sched->k_root.next; 169 170 // get thread pointer for this entry 171 thread = LIST_ELEMENT( current , thread_t , sched_list ); 172 173 // return thread if runnable 174 if( thread->blocked == 0 ) 175 { 176 // release lock 177 spinlock_unlock( &sched->lock ); 178 return thread; 179 } 162 180 } 163 } 164 while( current != last ); 165 166 // second scan the user threads 167 last = sched->u_last; 168 current = sched->u_last; 169 do 170 { 171 // get next entry in user list 172 current = list_next( &sched->u_root , current ); 173 174 // skip the list root that does not contain a thread 175 if( current == NULL ) continue; 176 177 // get thread pointer 178 thread = LIST_ELEMENT( current , thread_t , sched_list ); 179 180 // return thread if not blocked 181 if( thread->blocked == 0 ) 181 while( current != last ); 182 } 183 184 // second : scan the user threads list, 185 // only if this list is not empty 186 if( list_is_empty( &sched->u_root ) == false ) 187 { 188 last = sched->u_last; 189 current = sched->u_last; 190 do 182 191 { 183 // release lock 184 spinlock_unlock( &sched->lock ); 185 return thread; 192 // get next entry in user list 193 current = list_next( &sched->u_root , current ); 194 195 // skip the root that does not contain a thread 196 if( current == NULL ) current = sched->u_root.next; 197 198 // get thread pointer for this entry 199 thread = LIST_ELEMENT( current , thread_t , sched_list ); 200 201 // return thread if runnable 202 if( thread->blocked == 0 ) 203 { 204 // release lock 205 spinlock_unlock( &sched->lock ); 206 return thread; 207 } 186 208 } 187 }188 while( current != last );209 while( current != last ); 210 } 189 211 190 212 // release lock 191 213 spinlock_unlock( &sched->lock ); 192 214 193 // third ,return idle thread if no runnable thread215 // third : return idle thread if no runnable thread 194 216 return sched->idle; 195 217 … … 234 256 thread_t * current = CURRENT_THREAD; 235 257 core_t * core = current->core; 258 scheduler_t * sched = &core->scheduler; 236 259 237 260 if( thread_can_yield() == false ) … … 265 288 __FUNCTION__, core->lid, local_cxy, current->trdid, next->trdid ); 266 289 267 // switch contexts if new thread290 // switch contexts and update scheduler state if new thread 268 291 if( next != current ) 269 292 { 270 293 hal_cpu_context_save( current ); 271 294 hal_cpu_context_restore( next ); 295 296 if( current->type == THREAD_USER ) sched->u_last = ¤t->sched_list; 297 else sched->k_last = ¤t->sched_list; 298 299 sched->current = next; 272 300 } 273 301
Note: See TracChangeset
for help on using the changeset viewer.