Changeset ef1eab7 in mainline for kernel/generic/src/proc/task.c
- Timestamp:
- 2018-11-03T21:36:39Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- aab5e46
- Parents:
- ad2cf04
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/proc/task.c
rad2cf04 ref1eab7 1 1 /* 2 2 * Copyright (c) 2010 Jakub Jermar 3 * Copyright (c) 2018 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 47 48 #include <arch.h> 48 49 #include <barrier.h> 49 #include <adt/avl.h>50 50 #include <adt/btree.h> 51 51 #include <adt/list.h> 52 #include <adt/odict.h> 52 53 #include <cap/cap.h> 53 54 #include <ipc/ipc.h> … … 61 62 #include <macros.h> 62 63 63 /** Spinlock protecting the tasks_tree AVL tree. */64 /** Spinlock protecting the @c tasks ordered dictionary. */ 64 65 IRQ_SPINLOCK_INITIALIZE(tasks_lock); 65 66 66 /** AVL treeof active tasks.67 * 68 * The task is guaranteed to exist after it was found in the tasks_tree as69 * long as:67 /** Ordered dictionary of active tasks. 68 * 69 * The task is guaranteed to exist after it was found in the @c tasks 70 * dictionary as long as: 70 71 * 71 72 * @li the tasks_lock is held, … … 75 76 * 76 77 */ 77 avltree_t tasks_tree;78 odict_t tasks; 78 79 79 80 static task_id_t task_counter = 0; … … 84 85 static void task_kill_internal(task_t *); 85 86 static errno_t tsk_constructor(void *, unsigned int); 86 static size_t tsk_destructor(void *obj); 87 static size_t tsk_destructor(void *); 88 89 static void *tasks_getkey(odlink_t *); 90 static int tasks_cmp(void *, void *); 87 91 88 92 /** Initialize kernel tasks support. … … 92 96 { 93 97 TASK = NULL; 94 avltree_create(&tasks_tree);98 odict_initialize(&tasks, tasks_getkey, tasks_cmp); 95 99 task_cache = slab_cache_create("task_t", sizeof(task_t), 0, 96 100 tsk_constructor, tsk_destructor, 0); 97 101 } 98 102 99 /** Task finish walker.100 *101 * The idea behind this walker is to kill and count all tasks different from102 * TASK.103 *104 */105 static bool task_done_walker(avltree_node_t *node, void *arg)106 {107 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);108 size_t *cnt = (size_t *) arg;109 110 if (task != TASK) {111 (*cnt)++;112 113 #ifdef CONFIG_DEBUG114 printf("[%" PRIu64 "] ", task->taskid);115 #endif116 117 task_kill_internal(task);118 }119 120 /* Continue the walk */121 return true;122 }123 124 103 /** Kill all tasks except the current task. 125 104 * … … 128 107 { 129 108 size_t tasks_left; 109 odlink_t *odlink; 110 task_t *task; 130 111 131 112 if (ipc_box_0) { … … 144 125 printf("Killing tasks... "); 145 126 #endif 146 147 127 irq_spinlock_lock(&tasks_lock, true); 148 128 tasks_left = 0; 149 avltree_walk(&tasks_tree, task_done_walker, &tasks_left); 129 130 odlink = odict_first(&tasks); 131 while (odlink != NULL) { 132 task = odict_get_instance(odlink, task_t, ltasks); 133 134 if (task != TASK) { 135 tasks_left++; 136 #ifdef CONFIG_DEBUG 137 printf("[%" PRIu64 "] ", task->taskid); 138 #endif 139 task_kill_internal(task); 140 } 141 142 odlink = odict_next(odlink, &tasks); 143 } 144 150 145 irq_spinlock_unlock(&tasks_lock, true); 151 146 … … 269 264 270 265 task->taskid = ++task_counter; 271 avltree_node_initialize(&task->tasks_tree_node); 272 task->tasks_tree_node.key = task->taskid; 273 avltree_insert(&tasks_tree, &task->tasks_tree_node); 266 odlink_initialize(&task->ltasks); 267 odict_insert(&task->ltasks, &tasks, NULL); 274 268 275 269 irq_spinlock_unlock(&tasks_lock, true); … … 289 283 */ 290 284 irq_spinlock_lock(&tasks_lock, true); 291 avltree_delete(&tasks_tree, &task->tasks_tree_node);285 odict_remove(&task->ltasks); 292 286 irq_spinlock_unlock(&tasks_lock, true); 293 287 … … 451 445 assert(irq_spinlock_locked(&tasks_lock)); 452 446 453 avltree_node_t *node = 454 avltree_search(&tasks_tree, (avltree_key_t) id); 455 456 if (node) 457 return avltree_get_instance(node, task_t, tasks_tree_node); 447 odlink_t *odlink = odict_find_eq(&tasks, &id, NULL); 448 if (odlink != NULL) 449 return odict_get_instance(odlink, task_t, ltasks); 458 450 459 451 return NULL; … … 604 596 } 605 597 606 static bool task_print_walker(avltree_node_t *node, void *arg) 607 { 608 bool *additional = (bool *) arg; 609 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node); 598 static void task_print(task_t *task, bool additional) 599 { 610 600 irq_spinlock_lock(&task->lock, false); 611 601 … … 618 608 619 609 #ifdef __32_BITS__ 620 if ( *additional)610 if (additional) 621 611 printf("%-8" PRIu64 " %9zu", task->taskid, 622 612 atomic_load(&task->refcount)); … … 629 619 630 620 #ifdef __64_BITS__ 631 if ( *additional)621 if (additional) 632 622 printf("%-8" PRIu64 " %9" PRIu64 "%c %9" PRIu64 "%c " 633 623 "%9zu\n", task->taskid, ucycles, usuffix, kcycles, … … 639 629 640 630 irq_spinlock_unlock(&task->lock, false); 641 return true;642 631 } 643 632 … … 669 658 #endif 670 659 671 avltree_walk(&tasks_tree, task_print_walker, &additional); 660 odlink_t *odlink; 661 task_t *task; 662 663 odlink = odict_first(&tasks); 664 while (odlink != NULL) { 665 task = odict_get_instance(odlink, task_t, ltasks); 666 task_print(task, additional); 667 odlink = odict_next(odlink, &tasks); 668 } 672 669 673 670 irq_spinlock_unlock(&tasks_lock, true); 674 671 } 675 672 673 /** Get key function for the @c tasks ordered dictionary. 674 * 675 * @param odlink Link 676 * @return Pointer to task ID cast as 'void *' 677 */ 678 static void *tasks_getkey(odlink_t *odlink) 679 { 680 task_t *task = odict_get_instance(odlink, task_t, ltasks); 681 return (void *) &task->taskid; 682 } 683 684 /** Key comparison function for the @c tasks ordered dictionary. 685 * 686 * @param a Pointer to thread A ID 687 * @param b Pointer to thread B ID 688 * @return -1, 0, 1 iff ID A is less than, equal to, greater than B 689 */ 690 static int tasks_cmp(void *a, void *b) 691 { 692 task_id_t ida = *(task_id_t *)a; 693 task_id_t idb = *(task_id_t *)b; 694 695 if (ida < idb) 696 return -1; 697 else if (ida == idb) 698 return 0; 699 else 700 return +1; 701 } 702 676 703 /** @} 677 704 */
Note:
See TracChangeset
for help on using the changeset viewer.