Changes in kernel/generic/src/proc/task.c [5a5269d:f35749e] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/proc/task.c
r5a5269d rf35749e 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2010 Jakub Jermar 3 * Copyright (c) 2018 Jiri Svoboda4 4 * All rights reserved. 5 5 * … … 104 104 * 105 105 */ 106 void task_done( void)106 void task_done(task_t *cur_task) 107 107 { 108 108 size_t tasks_left; … … 112 112 task_t *task_0 = ipc_box_0->task; 113 113 ipc_box_0 = NULL; 114 114 115 /* 115 116 * The first task is held by kinit(), we need to release it or … … 129 130 task = task_first(); 130 131 while (task != NULL) { 131 if (task != TASK) {132 if (task != cur_task) { 132 133 tasks_left++; 133 134 #ifdef CONFIG_DEBUG … … 158 159 return rc; 159 160 160 atomic_store(&task->refcount, 0);161 161 atomic_store(&task->lifecount, 0); 162 162 … … 201 201 if (!task) 202 202 return NULL; 203 204 refcount_init(&task->refcount); 203 205 204 206 task_create_arch(task); … … 224 226 225 227 task->answerbox.active = true; 228 229 task->debug_sections = NULL; 226 230 227 231 #ifdef CONFIG_UDEBUG … … 266 270 * 267 271 */ 268 void task_destroy(task_t *task)272 static void task_destroy(task_t *task) 269 273 { 270 274 /* … … 297 301 void task_hold(task_t *task) 298 302 { 299 atomic_inc(&task->refcount);303 refcount_up(&task->refcount); 300 304 } 301 305 … … 309 313 void task_release(task_t *task) 310 314 { 311 if ( (atomic_predec(&task->refcount)) == 0)315 if (refcount_down(&task->refcount)) 312 316 task_destroy(task); 313 317 } … … 385 389 irq_spinlock_lock(&tasks_lock, true); 386 390 irq_spinlock_lock(&TASK->lock, false); 387 irq_spinlock_lock(&threads_lock, false);388 391 389 392 /* Set task name */ 390 393 str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf); 391 394 392 irq_spinlock_unlock(&threads_lock, false);393 395 irq_spinlock_unlock(&TASK->lock, false); 394 396 irq_spinlock_unlock(&tasks_lock, true); … … 416 418 /** Find task structure corresponding to task ID. 417 419 * 418 * The tasks_lock must be already held by the caller of this function and419 * interrupts must be disabled.420 *421 420 * @param id Task ID. 422 421 * 423 * @return Task structure addressor NULL if there is no such task ID.422 * @return Task reference or NULL if there is no such task ID. 424 423 * 425 424 */ 426 425 task_t *task_find_by_id(task_id_t id) 427 426 { 428 assert(interrupts_disabled()); 429 assert(irq_spinlock_locked(&tasks_lock)); 427 task_t *task = NULL; 428 429 irq_spinlock_lock(&tasks_lock, true); 430 430 431 431 odlink_t *odlink = odict_find_eq(&tasks, &id, NULL); 432 if (odlink != NULL) 433 return odict_get_instance(odlink, task_t, ltasks); 434 435 return NULL; 432 if (odlink != NULL) { 433 task = odict_get_instance(odlink, task_t, ltasks); 434 435 /* 436 * The directory of tasks can't hold a reference, since that would 437 * prevent task from ever being destroyed. That means we have to 438 * check for the case where the task is already being destroyed, but 439 * not yet removed from the directory. 440 */ 441 if (!refcount_try_up(&task->refcount)) 442 task = NULL; 443 } 444 445 irq_spinlock_unlock(&tasks_lock, true); 446 447 return task; 436 448 } 437 449 … … 506 518 /* Current values of threads */ 507 519 list_foreach(task->threads, th_link, thread_t, thread) { 508 irq_spinlock_lock(&thread->lock, false);509 510 520 /* Process only counted threads */ 511 521 if (!thread->uncounted) { … … 515 525 } 516 526 517 uret += thread->ucycles;518 kret += thread->kcycles;527 uret += atomic_time_read(&thread->ucycles); 528 kret += atomic_time_read(&thread->kcycles); 519 529 } 520 521 irq_spinlock_unlock(&thread->lock, false);522 530 } 523 531 … … 528 536 static void task_kill_internal(task_t *task) 529 537 { 530 irq_spinlock_lock(&task->lock, false); 531 irq_spinlock_lock(&threads_lock, false); 538 irq_spinlock_lock(&task->lock, true); 532 539 533 540 /* … … 536 543 537 544 list_foreach(task->threads, th_link, thread_t, thread) { 538 bool sleeping = false; 539 540 irq_spinlock_lock(&thread->lock, false); 541 542 thread->interrupted = true; 543 if (thread->state == Sleeping) 544 sleeping = true; 545 546 irq_spinlock_unlock(&thread->lock, false); 547 548 if (sleeping) 549 waitq_interrupt_sleep(thread); 545 thread_interrupt(thread); 550 546 } 551 547 552 irq_spinlock_unlock(&threads_lock, false); 553 irq_spinlock_unlock(&task->lock, false); 548 irq_spinlock_unlock(&task->lock, true); 554 549 } 555 550 … … 569 564 return EPERM; 570 565 571 irq_spinlock_lock(&tasks_lock, true);572 573 566 task_t *task = task_find_by_id(id); 574 if (!task) { 575 irq_spinlock_unlock(&tasks_lock, true); 567 if (!task) 576 568 return ENOENT; 577 }578 569 579 570 task_kill_internal(task); 580 irq_spinlock_unlock(&tasks_lock, true); 581 571 task_release(task); 582 572 return EOK; 583 573 } … … 609 599 } 610 600 611 irq_spinlock_lock(&tasks_lock, true);612 601 task_kill_internal(TASK); 613 irq_spinlock_unlock(&tasks_lock, true);614 615 602 thread_exit(); 616 603 } … … 641 628 if (additional) 642 629 printf("%-8" PRIu64 " %9zu", task->taskid, 643 atomic_load(&task-> refcount));630 atomic_load(&task->lifecount)); 644 631 else 645 632 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %10p %10p" … … 653 640 printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c " 654 641 "%9zu\n", task->taskid, ucycles, usuffix, kcycles, 655 ksuffix, atomic_load(&task-> refcount));642 ksuffix, atomic_load(&task->lifecount)); 656 643 else 657 644 printf("%-8" PRIu64 " %-14s %-5" PRIu32 " %18p %18p\n",
Note:
See TracChangeset
for help on using the changeset viewer.