diff options
| author | David Lamparter <equinox@diac24.net> | 2019-04-29 21:18:55 +0200 |
|---|---|---|
| committer | David Lamparter <equinox@diac24.net> | 2019-04-29 21:18:55 +0200 |
| commit | 8390828dacec2befdd8f71c7d08b17963a8a340a (patch) | |
| tree | 18d4b3635a8e6af66003476ffb1c4591cc7e8581 /lib/thread.c | |
| parent | 7629b6b79c7a2de2e83633b87ec420b30ed4173b (diff) | |
Revert "lib: use DECLARE_SKIPLIST for timers instead of pqueue"
This reverts commit 7c198e4e1ac07c043ecfc573aed9f1d107f87234.
Diffstat (limited to 'lib/thread.c')
| -rw-r--r-- | lib/thread.c | 94 |
1 files changed, 62 insertions, 32 deletions
diff --git a/lib/thread.c b/lib/thread.c index 12c65fbabd..5ca859a74d 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -27,6 +27,7 @@ #include "memory.h" #include "log.h" #include "hash.h" +#include "pqueue.h" #include "command.h" #include "sigevent.h" #include "network.h" @@ -41,18 +42,6 @@ DEFINE_MTYPE_STATIC(LIB, THREAD_STATS, "Thread stats") DECLARE_LIST(thread_list, struct thread, threaditem) -static int thread_timer_cmp(const struct thread *a, const struct thread *b) -{ - if (timercmp(&a->u.sands, &b->u.sands, <)) - return -1; - if (timercmp(&a->u.sands, &b->u.sands, >)) - return 1; - return 0; -} - -DECLARE_SKIPLIST_NONUNIQ(thread_timer_list, struct thread, timeritem, - thread_timer_cmp) - #if defined(__APPLE__) #include <mach/mach.h> #include <mach/mach_time.h> @@ -388,6 +377,25 @@ void thread_cmd_init(void) /* CLI end ------------------------------------------------------------------ */ +static int thread_timer_cmp(void *a, void *b) +{ + struct thread *thread_a = a; + struct thread *thread_b = b; + + if (timercmp(&thread_a->u.sands, &thread_b->u.sands, <)) + return -1; + if (timercmp(&thread_a->u.sands, &thread_b->u.sands, >)) + return 1; + return 0; +} + +static void thread_timer_update(void *node, int actual_position) +{ + struct thread *thread = node; + + thread->index = actual_position; +} + static void cancelreq_del(void *cr) { XFREE(MTYPE_TMP, cr); @@ -432,7 +440,11 @@ struct thread_master *thread_master_create(const char *name) thread_list_init(&rv->event); thread_list_init(&rv->ready); thread_list_init(&rv->unuse); - thread_timer_list_init(&rv->timer); + + /* Initialize the timer queues */ + rv->timer = pqueue_create(); + rv->timer->cmp = thread_timer_cmp; + rv->timer->update = thread_timer_update; /* Initialize thread_fetch() settings */ rv->spin = true; @@ -530,6 +542,16 @@ static void thread_array_free(struct thread_master *m, XFREE(MTYPE_THREAD_POLL, thread_array); } +static void thread_queue_free(struct thread_master *m, struct pqueue *queue) +{ + int i; + + for (i = 0; i < queue->size; i++) + thread_free(m, queue->array[i]); + + pqueue_delete(queue); +} + /* * thread_master_free_unused * @@ -552,8 +574,6 @@ void thread_master_free_unused(struct thread_master *m) /* Stop thread scheduler. */ void thread_master_free(struct thread_master *m) { - struct thread *t; - pthread_mutex_lock(&masters_mtx); { listnode_delete(masters, m); @@ -565,8 +585,7 @@ void thread_master_free(struct thread_master *m) thread_array_free(m, m->read); thread_array_free(m, m->write); - while ((t = thread_timer_list_pop(&m->timer))) - thread_free(m, t); + thread_queue_free(m, m->timer); thread_list_free(m, &m->event); thread_list_free(m, &m->ready); thread_list_free(m, &m->unuse); @@ -640,6 +659,7 @@ static struct thread *thread_get(struct thread_master *m, uint8_t type, thread->add_type = type; thread->master = m; thread->arg = arg; + thread->index = -1; thread->yield = THREAD_YIELD_TIME_SLOT; /* default */ thread->ref = NULL; @@ -798,6 +818,7 @@ funcname_thread_add_timer_timeval(struct thread_master *m, struct thread **t_ptr, debugargdef) { struct thread *thread; + struct pqueue *queue; assert(m != NULL); @@ -813,6 +834,7 @@ funcname_thread_add_timer_timeval(struct thread_master *m, return NULL; } + queue = m->timer; thread = thread_get(m, type, func, arg, debugargpass); pthread_mutex_lock(&thread->mtx); @@ -820,7 +842,7 @@ funcname_thread_add_timer_timeval(struct thread_master *m, monotime(&thread->u.sands); timeradd(&thread->u.sands, time_relative, &thread->u.sands); - thread_timer_list_add(&m->timer, thread); + pqueue_enqueue(thread, queue); if (t_ptr) { *t_ptr = thread; thread->ref = t_ptr; @@ -997,6 +1019,7 @@ static void thread_cancel_rw(struct thread_master *master, int fd, short state) static void do_thread_cancel(struct thread_master *master) { struct thread_list_head *list = NULL; + struct pqueue *queue = NULL; struct thread **thread_array = NULL; struct thread *thread; @@ -1052,7 +1075,7 @@ static void do_thread_cancel(struct thread_master *master) thread_array = master->write; break; case THREAD_TIMER: - thread_timer_list_del(&master->timer, thread); + queue = master->timer; break; case THREAD_EVENT: list = &master->event; @@ -1065,10 +1088,16 @@ static void do_thread_cancel(struct thread_master *master) break; } - if (list) { + if (queue) { + assert(thread->index >= 0); + assert(thread == queue->array[thread->index]); + pqueue_remove_at(thread->index, queue); + } else if (list) { thread_list_del(list, thread); } else if (thread_array) { thread_array[thread->u.fd] = NULL; + } else { + assert(!"Thread should be either in queue or list or array!"); } if (thread->ref) @@ -1186,15 +1215,15 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread, } /* ------------------------------------------------------------------------- */ -static struct timeval *thread_timer_wait(struct thread_timer_list_head *timers, +static struct timeval *thread_timer_wait(struct pqueue *queue, struct timeval *timer_val) { - if (!thread_timer_list_count(timers)) - return NULL; - - struct thread *next_timer = thread_timer_list_first(timers); - monotime_until(&next_timer->u.sands, timer_val); - return timer_val; + if (queue->size) { + struct thread *next_timer = queue->array[0]; + monotime_until(&next_timer->u.sands, timer_val); + return timer_val; + } + return NULL; } static struct thread *thread_run(struct thread_master *m, struct thread *thread, @@ -1286,16 +1315,17 @@ static void thread_process_io(struct thread_master *m, unsigned int num) } /* Add all timers that have popped to the ready list. */ -static unsigned int thread_process_timers(struct thread_timer_list_head *timers, +static unsigned int thread_process_timers(struct pqueue *queue, struct timeval *timenow) { struct thread *thread; unsigned int ready = 0; - while ((thread = thread_timer_list_first(timers))) { + while (queue->size) { + thread = queue->array[0]; if (timercmp(timenow, &thread->u.sands, <)) return ready; - thread_timer_list_pop(timers); + pqueue_dequeue(queue); thread->type = THREAD_READY; thread_list_add_tail(&thread->master->ready, thread); ready++; @@ -1377,7 +1407,7 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) * once per loop to avoid starvation by events */ if (!thread_list_count(&m->ready)) - tw = thread_timer_wait(&m->timer, &tv); + tw = thread_timer_wait(m->timer, &tv); if (thread_list_count(&m->ready) || (tw && !timercmp(tw, &zerotime, >))) @@ -1422,7 +1452,7 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch) /* Post timers to ready queue. */ monotime(&now); - thread_process_timers(&m->timer, &now); + thread_process_timers(m->timer, &now); /* Post I/O to ready queue. */ if (num > 0) |
