Changeset ef1eab7 in mainline for kernel/generic/src/proc/thread.c


Ignore:
Timestamp:
2018-11-03T21:36:39Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aab5e46
Parents:
ad2cf04
Message:

Replace AVL trees in kernel with ordered dictionary.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/proc/thread.c

    rad2cf04 ref1eab7  
    11/*
    22 * Copyright (c) 2010 Jakub Jermar
     3 * Copyright (c) 2018 Jiri Svoboda
    34 * All rights reserved.
    45 *
     
    5253#include <str.h>
    5354#include <context.h>
    54 #include <adt/avl.h>
    5555#include <adt/list.h>
     56#include <adt/odict.h>
    5657#include <time/clock.h>
    5758#include <time/timeout.h>
     
    8081};
    8182
    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 .
    8884 *
    8985 * For locking rules, see declaration thereof.
    90  *
    9186 */
    9287IRQ_SPINLOCK_INITIALIZE(threads_lock);
    9388
    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 */
     97odict_t threads;
    10198
    10299IRQ_SPINLOCK_STATIC_INITIALIZE(tidlock);
     
    108105slab_cache_t *fpu_context_cache;
    109106#endif
     107
     108static void *threads_getkey(odlink_t *);
     109static int threads_cmp(void *, void *);
    110110
    111111/** Thread wrapper.
     
    252252#endif
    253253
    254         avltree_create(&threads_tree);
     254        odict_initialize(&threads, threads_getkey, threads_cmp);
    255255}
    256256
     
    404404        thread->fpu_context_engaged = false;
    405405
    406         avltree_node_initialize(&thread->threads_tree_node);
    407         thread->threads_tree_node.key = (uintptr_t) thread;
     406        odlink_initialize(&thread->lthreads);
    408407
    409408#ifdef CONFIG_UDEBUG
     
    447446        irq_spinlock_pass(&thread->lock, &threads_lock);
    448447
    449         avltree_delete(&threads_tree, &thread->threads_tree_node);
     448        odict_remove(&thread->lthreads);
    450449
    451450        irq_spinlock_pass(&threads_lock, &thread->task->lock);
     
    492491
    493492        /*
    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);
    497496        irq_spinlock_unlock(&threads_lock, true);
    498497}
     
    710709}
    711710
    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 
     711static void thread_print(thread_t *thread, bool additional)
     712{
    717713        uint64_t ucycles, kcycles;
    718714        char usuffix, ksuffix;
     
    727723
    728724#ifdef __32_BITS__
    729         if (*additional)
     725        if (additional)
    730726                printf("%-8" PRIu64 " %10p %10p %9" PRIu64 "%c %9" PRIu64 "%c ",
    731727                    thread->tid, thread->thread_code, thread->kstack,
     
    738734
    739735#ifdef __64_BITS__
    740         if (*additional)
     736        if (additional)
    741737                printf("%-8" PRIu64 " %18p %18p\n"
    742738                    "         %9" PRIu64 "%c %9" PRIu64 "%c ",
     
    749745#endif
    750746
    751         if (*additional) {
     747        if (additional) {
    752748                if (thread->cpu)
    753749                        printf("%-5u", thread->cpu->id);
     
    767763                printf("\n");
    768764        }
    769 
    770         return true;
    771765}
    772766
     
    778772void thread_print_list(bool additional)
    779773{
     774        odlink_t *odlink;
     775        thread_t *thread;
     776
    780777        /* Messing with thread structures, avoid deadlock */
    781778        irq_spinlock_lock(&threads_lock, true);
     
    799796#endif
    800797
    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        }
    802804
    803805        irq_spinlock_unlock(&threads_lock, true);
     
    819821        assert(irq_spinlock_locked(&threads_lock));
    820822
    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;
    825825}
    826826
     
    848848}
    849849
    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 
    864850/** Find thread structure corresponding to thread ID.
    865851 *
     
    874860thread_t *thread_find_by_id(thread_id_t thread_id)
    875861{
     862        odlink_t *odlink;
     863        thread_t *thread;
     864
    876865        assert(interrupts_disabled());
    877866        assert(irq_spinlock_locked(&threads_lock));
    878867
    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;
    887878}
    888879
     
    933924
    934925#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 */
     932static 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 */
     944static 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}
    935953
    936954/** Process syscall to create new thread.
Note: See TracChangeset for help on using the changeset viewer.