Changeset e16e036a in mainline for generic/src
- Timestamp:
- 2005-11-07T20:04:30Z (20 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c4e8ed9d
- Parents:
- d90ca68
- Location:
- generic/src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/debug/print.c
rd90ca68 re16e036a 42 42 #define DEFAULT_DOUBLE_BUFFER_SIZE 128 43 43 44 void print_double(double num, __u8 modifier, __u16 precision) 44 45 /** Print NULL terminated string 46 * 47 * Print characters from str using putchar() until 48 * \\0 character is reached. 49 * 50 * @param str Characters to print. 51 * 52 */ 53 static void print_str(const char *str) 54 { 55 int i = 0; 56 char c; 57 58 while (c = str[i++]) 59 putchar(c); 60 } 61 62 63 /** Print hexadecimal digits 64 * 65 * Print fixed count of hexadecimal digits from 66 * the number num. The digits are printed in 67 * natural left-to-right order starting with 68 * the width-th digit. 69 * 70 * @param num Number containing digits. 71 * @param width Count of digits to print. 72 * 73 */ 74 static void print_fixed_hex(const __u64 num, const int width) 75 { 76 int i; 77 78 for (i = width*8 - 4; i >= 0; i -= 4) 79 putchar(digits[(num>>i) & 0xf]); 80 } 81 82 83 /** Print number in given base 84 * 85 * Print significant digits of a number in given 86 * base. 87 * 88 * @param num Number to print. 89 * @param base Base to print the number in (should 90 * be in range 2 .. 16). 91 * 92 */ 93 static void print_number(const __native num, const unsigned int base) 94 { 95 int val = num; 96 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */ 97 int i = sizeof(__native)*8-1; 98 99 do { 100 d[i--] = digits[val % base]; 101 } while (val /= base); 102 103 d[sizeof(__native)*8] = 0; 104 print_str(&d[i + 1]); 105 } 106 107 108 static void print_double(double num, __u8 modifier, __u16 precision) 45 109 { 46 110 double intval,intval2; … … 143 207 } 144 208 145 /** Print NULL terminated string146 *147 * Print characters from str using putchar() until148 * \\0 character is reached.149 *150 * @param str Characters to print.151 *152 */153 void print_str(const char *str)154 {155 int i = 0;156 char c;157 158 while (c = str[i++])159 putchar(c);160 }161 162 163 /** Print hexadecimal digits164 *165 * Print fixed count of hexadecimal digits from166 * the number num. The digits are printed in167 * natural left-to-right order starting with168 * the width-th digit.169 *170 * @param num Number containing digits.171 * @param width Count of digits to print.172 *173 */174 void print_fixed_hex(const __u64 num, const int width)175 {176 int i;177 178 for (i = width*8 - 4; i >= 0; i -= 4)179 putchar(digits[(num>>i) & 0xf]);180 }181 182 183 /** Print number in given base184 *185 * Print significant digits of a number in given186 * base.187 *188 * @param num Number to print.189 * @param base Base to print the number in (should190 * be in range 2 .. 16).191 *192 */193 void print_number(const __native num, const unsigned int base)194 {195 int val = num;196 char d[sizeof(__native)*8+1]; /* this is good enough even for base == 2 */197 int i = sizeof(__native)*8-1;198 199 do {200 d[i--] = digits[val % base];201 } while (val /= base);202 203 d[sizeof(__native)*8] = 0;204 print_str(&d[i + 1]);205 }206 207 209 208 210 /** General formatted text print -
generic/src/main/kinit.c
rd90ca68 re16e036a 123 123 */ 124 124 m = vm_create(NULL); 125 if (!m) panic("vm_create"); 125 if (!m) 126 panic("vm_create"); 126 127 u = task_create(m); 127 if (!u) panic("task_create"); 128 if (!u) 129 panic("task_create"); 128 130 t = thread_create(uinit, NULL, u, THREAD_USER_STACK); 129 if (!t) panic("thread_create"); 131 if (!t) 132 panic("thread_create"); 130 133 131 134 /* … … 133 136 */ 134 137 a = vm_area_create(m, VMA_TEXT, 1, UTEXT_ADDRESS); 135 if (!a) panic("vm_area_create: vm_text"); 138 if (!a) 139 panic("vm_area_create: vm_text"); 136 140 vm_area_map(a, m); 137 141 memcpy((void *) PA2KA(a->mapping[0]), (void *) utext, utext_size < PAGE_SIZE ? utext_size : PAGE_SIZE); … … 141 145 */ 142 146 a = vm_area_create(m, VMA_STACK, 1, USTACK_ADDRESS); 143 if (!a) panic("vm_area_create: vm_stack"); 147 if (!a) 148 panic("vm_area_create: vm_stack"); 144 149 vm_area_map(a, m); 145 150 -
generic/src/proc/scheduler.c
rd90ca68 re16e036a 117 117 * 118 118 */ 119 st ruct thread *find_best_thread(void)119 static struct thread *find_best_thread(void) 120 120 { 121 121 thread_t *t; … … 223 223 * 224 224 */ 225 void relink_rq(int start)225 static void relink_rq(int start) 226 226 { 227 227 link_t head; … … 255 255 256 256 257 /** Scheduler stack switch wrapper 258 * 259 * Second part of the scheduler() function 260 * using new stack. Handling the actual context 261 * switch to a new thread. 262 * 263 */ 264 static void scheduler_separated_stack(void) 265 { 266 int priority; 267 268 ASSERT(CPU != NULL); 269 270 if (THREAD) { 271 switch (THREAD->state) { 272 case Running: 273 THREAD->state = Ready; 274 spinlock_unlock(&THREAD->lock); 275 thread_ready(THREAD); 276 break; 277 278 case Exiting: 279 frame_free((__address) THREAD->kstack); 280 if (THREAD->ustack) { 281 frame_free((__address) THREAD->ustack); 282 } 283 284 /* 285 * Detach from the containing task. 286 */ 287 spinlock_lock(&TASK->lock); 288 list_remove(&THREAD->th_link); 289 spinlock_unlock(&TASK->lock); 290 291 spinlock_unlock(&THREAD->lock); 292 293 spinlock_lock(&threads_lock); 294 list_remove(&THREAD->threads_link); 295 spinlock_unlock(&threads_lock); 296 297 spinlock_lock(&CPU->lock); 298 if(CPU->fpu_owner==THREAD) CPU->fpu_owner=NULL; 299 spinlock_unlock(&CPU->lock); 300 301 free(THREAD); 302 303 break; 304 305 case Sleeping: 306 /* 307 * Prefer the thread after it's woken up. 308 */ 309 THREAD->priority = -1; 310 311 /* 312 * We need to release wq->lock which we locked in waitq_sleep(). 313 * Address of wq->lock is kept in THREAD->sleep_queue. 314 */ 315 spinlock_unlock(&THREAD->sleep_queue->lock); 316 317 /* 318 * Check for possible requests for out-of-context invocation. 319 */ 320 if (THREAD->call_me) { 321 THREAD->call_me(THREAD->call_me_with); 322 THREAD->call_me = NULL; 323 THREAD->call_me_with = NULL; 324 } 325 326 spinlock_unlock(&THREAD->lock); 327 328 break; 329 330 default: 331 /* 332 * Entering state is unexpected. 333 */ 334 panic("tid%d: unexpected state %s\n", THREAD->tid, thread_states[THREAD->state]); 335 break; 336 } 337 THREAD = NULL; 338 } 339 340 341 THREAD = find_best_thread(); 342 343 spinlock_lock(&THREAD->lock); 344 priority = THREAD->priority; 345 spinlock_unlock(&THREAD->lock); 346 347 relink_rq(priority); 348 349 spinlock_lock(&THREAD->lock); 350 351 /* 352 * If both the old and the new task are the same, lots of work is avoided. 353 */ 354 if (TASK != THREAD->task) { 355 vm_t *m1 = NULL; 356 vm_t *m2; 357 358 if (TASK) { 359 spinlock_lock(&TASK->lock); 360 m1 = TASK->vm; 361 spinlock_unlock(&TASK->lock); 362 } 363 364 spinlock_lock(&THREAD->task->lock); 365 m2 = THREAD->task->vm; 366 spinlock_unlock(&THREAD->task->lock); 367 368 /* 369 * Note that it is possible for two tasks to share one vm mapping. 370 */ 371 if (m1 != m2) { 372 /* 373 * Both tasks and vm mappings are different. 374 * Replace the old one with the new one. 375 */ 376 vm_install(m2); 377 } 378 TASK = THREAD->task; 379 } 380 381 THREAD->state = Running; 382 383 #ifdef SCHEDULER_VERBOSE 384 printf("cpu%d: tid %d (priority=%d,ticks=%d,nrdy=%d)\n", CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, CPU->nrdy); 385 #endif 386 387 /* 388 * Copy the knowledge of CPU, TASK, THREAD and preemption counter to thread's stack. 389 */ 390 the_copy(THE, (the_t *) THREAD->kstack); 391 392 context_restore(&THREAD->saved_context); 393 /* not reached */ 394 } 395 396 257 397 /** The scheduler 258 398 * … … 320 460 321 461 322 /** Scheduler stack switch wrapper 323 * 324 * Second part of the scheduler() function 325 * using new stack. Handling the actual context 326 * switch to a new thread. 327 * 328 */ 329 void scheduler_separated_stack(void) 330 { 331 int priority; 332 333 ASSERT(CPU != NULL); 334 335 if (THREAD) { 336 switch (THREAD->state) { 337 case Running: 338 THREAD->state = Ready; 339 spinlock_unlock(&THREAD->lock); 340 thread_ready(THREAD); 341 break; 342 343 case Exiting: 344 frame_free((__address) THREAD->kstack); 345 if (THREAD->ustack) { 346 frame_free((__address) THREAD->ustack); 347 } 348 349 /* 350 * Detach from the containing task. 351 */ 352 spinlock_lock(&TASK->lock); 353 list_remove(&THREAD->th_link); 354 spinlock_unlock(&TASK->lock); 355 356 spinlock_unlock(&THREAD->lock); 357 358 spinlock_lock(&threads_lock); 359 list_remove(&THREAD->threads_link); 360 spinlock_unlock(&threads_lock); 361 362 spinlock_lock(&CPU->lock); 363 if(CPU->fpu_owner==THREAD) CPU->fpu_owner=NULL; 364 spinlock_unlock(&CPU->lock); 365 366 free(THREAD); 367 368 break; 369 370 case Sleeping: 371 /* 372 * Prefer the thread after it's woken up. 373 */ 374 THREAD->priority = -1; 375 376 /* 377 * We need to release wq->lock which we locked in waitq_sleep(). 378 * Address of wq->lock is kept in THREAD->sleep_queue. 379 */ 380 spinlock_unlock(&THREAD->sleep_queue->lock); 381 382 /* 383 * Check for possible requests for out-of-context invocation. 384 */ 385 if (THREAD->call_me) { 386 THREAD->call_me(THREAD->call_me_with); 387 THREAD->call_me = NULL; 388 THREAD->call_me_with = NULL; 389 } 390 391 spinlock_unlock(&THREAD->lock); 392 393 break; 394 395 default: 396 /* 397 * Entering state is unexpected. 398 */ 399 panic("tid%d: unexpected state %s\n", THREAD->tid, thread_states[THREAD->state]); 400 break; 401 } 402 THREAD = NULL; 403 } 404 405 406 THREAD = find_best_thread(); 407 408 spinlock_lock(&THREAD->lock); 409 priority = THREAD->priority; 410 spinlock_unlock(&THREAD->lock); 411 412 relink_rq(priority); 413 414 spinlock_lock(&THREAD->lock); 415 416 /* 417 * If both the old and the new task are the same, lots of work is avoided. 418 */ 419 if (TASK != THREAD->task) { 420 vm_t *m1 = NULL; 421 vm_t *m2; 422 423 if (TASK) { 424 spinlock_lock(&TASK->lock); 425 m1 = TASK->vm; 426 spinlock_unlock(&TASK->lock); 427 } 428 429 spinlock_lock(&THREAD->task->lock); 430 m2 = THREAD->task->vm; 431 spinlock_unlock(&THREAD->task->lock); 432 433 /* 434 * Note that it is possible for two tasks to share one vm mapping. 435 */ 436 if (m1 != m2) { 437 /* 438 * Both tasks and vm mappings are different. 439 * Replace the old one with the new one. 440 */ 441 vm_install(m2); 442 } 443 TASK = THREAD->task; 444 } 445 446 THREAD->state = Running; 447 448 #ifdef SCHEDULER_VERBOSE 449 printf("cpu%d: tid %d (priority=%d,ticks=%d,nrdy=%d)\n", CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, CPU->nrdy); 450 #endif 451 452 /* 453 * Copy the knowledge of CPU, TASK, THREAD and preemption counter to thread's stack. 454 */ 455 the_copy(THE, (the_t *) THREAD->kstack); 456 457 context_restore(&THREAD->saved_context); 458 /* not reached */ 459 } 462 460 463 461 464 -
generic/src/proc/thread.c
rd90ca68 re16e036a 71 71 * 72 72 */ 73 void cushion(void)73 static void cushion(void) 74 74 { 75 75 void (*f)(void *) = THREAD->thread_code;
Note:
See TracChangeset
for help on using the changeset viewer.