Changeset ef1eab7 in mainline for kernel/generic/src/proc/thread.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.
Note:
See TracChangeset
for help on using the changeset viewer.