Changeset ef1eab7 in mainline
- Timestamp:
- 2018-11-03T21:36:39Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- aab5e46
- Parents:
- ad2cf04
- Location:
- kernel
- Files:
-
- 4 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/Makefile
rad2cf04 ref1eab7 161 161 162 162 GENERIC_SOURCES = \ 163 generic/src/adt/avl.c \164 163 generic/src/adt/bitmap.c \ 165 164 generic/src/adt/btree.c \ … … 286 285 test/btree/btree1.c \ 287 286 test/cht/cht1.c \ 288 test/avltree/avltree1.c \289 287 test/fault/fault1.c \ 290 288 test/mm/falloc1.c \ -
kernel/generic/include/proc/task.h
rad2cf04 ref1eab7 44 44 #include <synch/futex.h> 45 45 #include <synch/workqueue.h> 46 #include <adt/avl.h>47 46 #include <adt/btree.h> 48 47 #include <adt/cht.h> 49 48 #include <adt/list.h> 49 #include <adt/odict.h> 50 50 #include <security/perm.h> 51 51 #include <arch/proc/task.h> … … 70 70 /** Task structure. */ 71 71 typedef struct task { 72 /** Task's linkage for the tasks_tree AVL tree.*/73 avltree_node_t tasks_tree_node;72 /** Link to @c tasks ordered dictionary */ 73 odlink_t ltasks; 74 74 75 75 /** Task lock. … … 146 146 } task_t; 147 147 148 /** Synchronize access to @c tasks */ 148 149 IRQ_SPINLOCK_EXTERN(tasks_lock); 149 extern avltree_t tasks_tree; 150 /** Ordered dictionary of all tasks by ID (of task_t structures) */ 151 extern odict_t tasks; 150 152 151 153 extern void task_init(void); -
kernel/generic/include/proc/thread.h
rad2cf04 ref1eab7 42 42 #include <synch/spinlock.h> 43 43 #include <synch/rcu_types.h> 44 #include <adt/ avl.h>44 #include <adt/odict.h> 45 45 #include <mm/slab.h> 46 46 #include <arch/cpu.h> … … 75 75 link_t th_link; /**< Links to threads within containing task. */ 76 76 77 /** Threads linkage to the threads_tree. */78 avltree_node_t threads_tree_node;77 /** Link to @c threads ordered dictionary. */ 78 odlink_t lthreads; 79 79 80 80 /** Lock protecting thread structure. … … 224 224 } thread_t; 225 225 226 /** Thread list lock.227 *228 * This lock protects the threads_tree.229 * Must be acquired before T.lock for each T of type thread_t.230 *231 */232 226 IRQ_SPINLOCK_EXTERN(threads_lock); 233 234 /** AVL tree containing all threads. */ 235 extern avltree_t threads_tree; 227 extern odict_t threads; 236 228 237 229 extern void thread_init(void); -
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 */ -
kernel/generic/src/proc/thread.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 * … … 52 53 #include <str.h> 53 54 #include <context.h> 54 #include <adt/avl.h>55 55 #include <adt/list.h> 56 #include <adt/odict.h> 56 57 #include <time/clock.h> 57 58 #include <time/timeout.h> … … 80 81 }; 81 82 82 typedef struct { 83 thread_id_t thread_id; 84 thread_t *thread; 85 } thread_iterator_t; 86 87 /** Lock protecting the threads_tree AVL tree. 83 /** Lock protecting the @c threads ordered dictionary . 88 84 * 89 85 * For locking rules, see declaration thereof. 90 *91 86 */ 92 87 IRQ_SPINLOCK_INITIALIZE(threads_lock); 93 88 94 /** AVL tree of all threads. 95 * 96 * When a thread is found in the threads_tree AVL tree, it is guaranteed to 97 * exist as long as the threads_lock is held. 98 * 99 */ 100 avltree_t threads_tree; 89 /** Ordered dictionary of all threads by their address (i.e. pointer to 90 * the thread_t structure). 91 * 92 * When a thread is found in the @c threads ordered dictionary, it is 93 * guaranteed to exist as long as the @c threads_lock is held. 94 * 95 * Members are of type thread_t. 96 */ 97 odict_t threads; 101 98 102 99 IRQ_SPINLOCK_STATIC_INITIALIZE(tidlock); … … 108 105 slab_cache_t *fpu_context_cache; 109 106 #endif 107 108 static void *threads_getkey(odlink_t *); 109 static int threads_cmp(void *, void *); 110 110 111 111 /** Thread wrapper. … … 252 252 #endif 253 253 254 avltree_create(&threads_tree);254 odict_initialize(&threads, threads_getkey, threads_cmp); 255 255 } 256 256 … … 404 404 thread->fpu_context_engaged = false; 405 405 406 avltree_node_initialize(&thread->threads_tree_node); 407 thread->threads_tree_node.key = (uintptr_t) thread; 406 odlink_initialize(&thread->lthreads); 408 407 409 408 #ifdef CONFIG_UDEBUG … … 447 446 irq_spinlock_pass(&thread->lock, &threads_lock); 448 447 449 avltree_delete(&threads_tree, &thread->threads_tree_node);448 odict_remove(&thread->lthreads); 450 449 451 450 irq_spinlock_pass(&threads_lock, &thread->task->lock); … … 492 491 493 492 /* 494 * Register this thread in the system-wide list.495 */ 496 avltree_insert(&threads_tree, &thread->threads_tree_node);493 * Register this thread in the system-wide dictionary. 494 */ 495 odict_insert(&thread->lthreads, &threads, NULL); 497 496 irq_spinlock_unlock(&threads_lock, true); 498 497 } … … 710 709 } 711 710 712 static bool thread_walker(avltree_node_t *node, void *arg) 713 { 714 bool *additional = (bool *) arg; 715 thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node); 716 711 static void thread_print(thread_t *thread, bool additional) 712 { 717 713 uint64_t ucycles, kcycles; 718 714 char usuffix, ksuffix; … … 727 723 728 724 #ifdef __32_BITS__ 729 if ( *additional)725 if (additional) 730 726 printf("%-8" PRIu64 " %10p %10p %9" PRIu64 "%c %9" PRIu64 "%c ", 731 727 thread->tid, thread->thread_code, thread->kstack, … … 738 734 739 735 #ifdef __64_BITS__ 740 if ( *additional)736 if (additional) 741 737 printf("%-8" PRIu64 " %18p %18p\n" 742 738 " %9" PRIu64 "%c %9" PRIu64 "%c ", … … 749 745 #endif 750 746 751 if ( *additional) {747 if (additional) { 752 748 if (thread->cpu) 753 749 printf("%-5u", thread->cpu->id); … … 767 763 printf("\n"); 768 764 } 769 770 return true;771 765 } 772 766 … … 778 772 void thread_print_list(bool additional) 779 773 { 774 odlink_t *odlink; 775 thread_t *thread; 776 780 777 /* Messing with thread structures, avoid deadlock */ 781 778 irq_spinlock_lock(&threads_lock, true); … … 799 796 #endif 800 797 801 avltree_walk(&threads_tree, thread_walker, &additional); 798 odlink = odict_first(&threads); 799 while (odlink != NULL) { 800 thread = odict_get_instance(odlink, thread_t, lthreads); 801 thread_print(thread, additional); 802 odlink = odict_next(odlink, &threads); 803 } 802 804 803 805 irq_spinlock_unlock(&threads_lock, true); … … 819 821 assert(irq_spinlock_locked(&threads_lock)); 820 822 821 avltree_node_t *node = 822 avltree_search(&threads_tree, (avltree_key_t) ((uintptr_t) thread)); 823 824 return node != NULL; 823 odlink_t *odlink = odict_find_eq(&threads, thread, NULL); 824 return odlink != NULL; 825 825 } 826 826 … … 848 848 } 849 849 850 static bool thread_search_walker(avltree_node_t *node, void *arg)851 {852 thread_t *thread =853 (thread_t *) avltree_get_instance(node, thread_t, threads_tree_node);854 thread_iterator_t *iterator = (thread_iterator_t *) arg;855 856 if (thread->tid == iterator->thread_id) {857 iterator->thread = thread;858 return false;859 }860 861 return true;862 }863 864 850 /** Find thread structure corresponding to thread ID. 865 851 * … … 874 860 thread_t *thread_find_by_id(thread_id_t thread_id) 875 861 { 862 odlink_t *odlink; 863 thread_t *thread; 864 876 865 assert(interrupts_disabled()); 877 866 assert(irq_spinlock_locked(&threads_lock)); 878 867 879 thread_iterator_t iterator; 880 881 iterator.thread_id = thread_id; 882 iterator.thread = NULL; 883 884 avltree_walk(&threads_tree, thread_search_walker, (void *) &iterator); 885 886 return iterator.thread; 868 odlink = odict_first(&threads); 869 while (odlink != NULL) { 870 thread = odict_get_instance(odlink, thread_t, lthreads); 871 if (thread->tid == thread_id) 872 return thread; 873 874 odlink = odict_next(odlink, &threads); 875 } 876 877 return NULL; 887 878 } 888 879 … … 933 924 934 925 #endif /* CONFIG_UDEBUG */ 926 927 /** Get key function for the @c threads ordered dictionary. 928 * 929 * @param odlink Link 930 * @return Pointer to thread structure cast as 'void *' 931 */ 932 static void *threads_getkey(odlink_t *odlink) 933 { 934 thread_t *thread = odict_get_instance(odlink, thread_t, lthreads); 935 return (void *) thread; 936 } 937 938 /** Key comparison function for the @c threads ordered dictionary. 939 * 940 * @param a Pointer to thread A 941 * @param b Pointer to thread B 942 * @return -1, 0, 1 iff pointer to A is less than, equal to, greater than B 943 */ 944 static int threads_cmp(void *a, void *b) 945 { 946 if (a > b) 947 return -1; 948 else if (a == b) 949 return 0; 950 else 951 return +1; 952 } 935 953 936 954 /** Process syscall to create new thread. -
kernel/generic/src/sysinfo/stats.c
rad2cf04 ref1eab7 2 2 * Copyright (c) 2010 Stanislav Kozina 3 3 * Copyright (c) 2010 Martin Decky 4 * Copyright (c) 2018 Jiri Svoboda 4 5 * All rights reserved. 5 6 * … … 123 124 } 124 125 125 /** Count number of nodes in an AVL tree126 *127 * AVL tree walker for counting nodes.128 *129 * @param node AVL tree node (unused).130 * @param arg Pointer to the counter (size_t).131 *132 * @param Always true (continue the walk).133 *134 */135 static bool avl_count_walker(avltree_node_t *node, void *arg)136 {137 size_t *count = (size_t *) arg;138 (*count)++;139 140 return true;141 }142 143 126 /** Get the size of a virtual address space 144 127 * … … 245 228 } 246 229 247 /** Gather statistics of all tasks248 *249 * AVL task tree walker for gathering task statistics. Interrupts should250 * be already disabled while walking the tree.251 *252 * @param node AVL task tree node.253 * @param arg Pointer to the iterator into the array of stats_task_t.254 *255 * @param Always true (continue the walk).256 *257 */258 static bool task_serialize_walker(avltree_node_t *node, void *arg)259 {260 stats_task_t **iterator = (stats_task_t **) arg;261 task_t *task = avltree_get_instance(node, task_t, tasks_tree_node);262 263 /* Interrupts are already disabled */264 irq_spinlock_lock(&(task->lock), false);265 266 /* Record the statistics and increment the iterator */267 produce_stats_task(task, *iterator);268 (*iterator)++;269 270 irq_spinlock_unlock(&(task->lock), false);271 272 return true;273 }274 275 230 /** Get task statistics 276 231 * … … 290 245 irq_spinlock_lock(&tasks_lock, true); 291 246 292 /* First walk the task tree to count the tasks */ 293 size_t count = 0; 294 avltree_walk(&tasks_tree, avl_count_walker, (void *) &count); 247 /* Count the tasks */ 248 size_t count = odict_count(&tasks); 295 249 296 250 if (count == 0) { … … 315 269 } 316 270 317 /* Walk tha task tree again to gather the statistics */ 318 stats_task_t *iterator = stats_tasks; 319 avltree_walk(&tasks_tree, task_serialize_walker, (void *) &iterator); 271 /* Gather the statistics for each task */ 272 size_t i = 0; 273 odlink_t *odlink = odict_first(&tasks); 274 while (odlink != NULL) { 275 task_t *task = odict_get_instance(odlink, task_t, ltasks); 276 277 /* Interrupts are already disabled */ 278 irq_spinlock_lock(&(task->lock), false); 279 280 /* Record the statistics and increment the index */ 281 produce_stats_task(task, &stats_tasks[i]); 282 i++; 283 284 irq_spinlock_unlock(&(task->lock), false); 285 odlink = odict_next(odlink, &tasks); 286 } 320 287 321 288 irq_spinlock_unlock(&tasks_lock, true); … … 351 318 } 352 319 353 /** Gather statistics of all threads354 *355 * AVL three tree walker for gathering thread statistics. Interrupts should356 * be already disabled while walking the tree.357 *358 * @param node AVL thread tree node.359 * @param arg Pointer to the iterator into the array of thread statistics.360 *361 * @param Always true (continue the walk).362 *363 */364 static bool thread_serialize_walker(avltree_node_t *node, void *arg)365 {366 stats_thread_t **iterator = (stats_thread_t **) arg;367 thread_t *thread = avltree_get_instance(node, thread_t, threads_tree_node);368 369 /* Interrupts are already disabled */370 irq_spinlock_lock(&thread->lock, false);371 372 /* Record the statistics and increment the iterator */373 produce_stats_thread(thread, *iterator);374 (*iterator)++;375 376 irq_spinlock_unlock(&thread->lock, false);377 378 return true;379 }380 381 320 /** Get thread statistics 382 321 * … … 396 335 irq_spinlock_lock(&threads_lock, true); 397 336 398 /* First walk the thread tree to count the threads */ 399 size_t count = 0; 400 avltree_walk(&threads_tree, avl_count_walker, (void *) &count); 337 /* Count the threads */ 338 size_t count = odict_count(&threads); 401 339 402 340 if (count == 0) { … … 422 360 423 361 /* Walk tha thread tree again to gather the statistics */ 424 stats_thread_t *iterator = stats_threads; 425 avltree_walk(&threads_tree, thread_serialize_walker, (void *) &iterator); 362 size_t i = 0; 363 364 odlink_t *odlink = odict_first(&threads); 365 while (odlink != NULL) { 366 thread_t *thread = odict_get_instance(odlink, thread_t, 367 lthreads); 368 369 /* Interrupts are already disabled */ 370 irq_spinlock_lock(&thread->lock, false); 371 372 /* Record the statistics and increment the index */ 373 produce_stats_thread(thread, &stats_threads[i]); 374 i++; 375 376 irq_spinlock_unlock(&thread->lock, false); 377 378 odlink = odict_next(odlink, &threads); 379 } 426 380 427 381 irq_spinlock_unlock(&threads_lock, true); -
kernel/test/test.c
rad2cf04 ref1eab7 41 41 test_t tests[] = { 42 42 #include <atomic/atomic1.def> 43 #include <avltree/avltree1.def>44 43 #include <btree/btree1.def> 45 44 #include <cht/cht1.def>
Note:
See TracChangeset
for help on using the changeset viewer.