diff --git a/Knot.files b/Knot.files index 71a588fae70685bdffae660699ae4c7c41040af2..18cc91d314569f4e789c1a391ba9afa96f891b12 100644 --- a/Knot.files +++ b/Knot.files @@ -75,6 +75,8 @@ src/common/mempattern.c src/common/mempattern.h src/common/lists.h src/common/lists.c +src/common/heap.h +src/common/heap.c src/common/base32.h src/common/base32.c src/common/print.c diff --git a/src/Makefile.am b/src/Makefile.am index 60c51c6517b3c3aeebe6e11782eedc9c359afb0c..5465c169200de91ca40547de4842d04b270f6130 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -226,6 +226,8 @@ libknots_la_SOURCES = \ common/lists.c \ common/base32.c \ common/lists.h \ + common/heap.h \ + common/heap.c \ common/base32.h \ common/print.c \ common/print.h \ diff --git a/src/common/evsched.c b/src/common/evsched.c index cc2cf7cd7a113048bcb5d5865a2ee9ad118a5dd5..3ab47b68e36ff04b39de3bc17c462fe4cb3e911f 100644 --- a/src/common/evsched.c +++ b/src/common/evsched.c @@ -26,6 +26,14 @@ #define OPENBSD_SLAB_BROKEN #endif +static int compare_event_heap_nodes(event_t *e1, event_t *e2) +{ + if (timercmp(&e1->tv, &e2->tv, <)) return -1; + if (timercmp(&e1->tv, &e2->tv, >)) return 1; + return 0; +} + + /*! * \brief Set event timer to T (now) + dt miliseconds. */ @@ -69,7 +77,7 @@ evsched_t *evsched_new() #ifndef OPENBSD_SLAB_BROKEN slab_cache_init(&s->cache.alloc, sizeof(event_t)); #endif - init_list(&s->calendar); + heap_init(&s->heap, sizeof(void *), compare_event_heap_nodes, 0, NULL); return s; } @@ -86,10 +94,15 @@ void evsched_delete(evsched_t **s) pthread_mutex_destroy(&(*s)->rl); pthread_mutex_destroy(&(*s)->mx); pthread_cond_destroy(&(*s)->notify); - node *n = 0, *nxt = 0; - WALK_LIST_DELSAFE(n, nxt, (*s)->calendar) { - evsched_event_free((*s), (event_t*)n); + + while (! EMPTY_HEAP(&(*s)->heap)) /* FIXME: Would be faster to simply walk through the array */ + { + evsched_event_free((*s), (HHEAD(&(*s)->heap))); + heap_delmin(&(*s)->heap); } + + free((*s)->heap.data); + (*s)->heap.data = NULL;; #ifndef OPENBSD_SLAB_BROKEN /* Free allocator. */ @@ -154,14 +167,14 @@ event_t* evsched_next(evsched_t *s) while(1) { /* Check event queue. */ - if (!EMPTY_LIST(s->calendar)) { + if (!EMPTY_HEAP(&s->heap)) { /* Get current time. */ struct timeval dt; gettimeofday(&dt, 0); /* Get next event. */ - event_t *next_ev = HEAD(s->calendar); + event_t *next_ev = HHEAD(&s->heap); /* Immediately return. */ if (timercmp(&dt, &next_ev->tv, >=)) { @@ -173,6 +186,7 @@ event_t* evsched_next(evsched_t *s) } /* Wait for next event or interrupt. Unlock calendar. */ + /* FIXME: Blocks this the possibility to add any event earlier? */ struct timespec ts; ts.tv_sec = next_ev->tv.tv_sec; ts.tv_nsec = next_ev->tv.tv_usec * 1000L; @@ -218,27 +232,7 @@ int evsched_schedule(evsched_t *s, event_t *ev, uint32_t dt) /* Lock calendar. */ pthread_mutex_lock(&s->mx); - /* Schedule event. */ - node *n = 0, *prev = 0; - if (!EMPTY_LIST(s->calendar)) { - WALK_LIST(n, s->calendar) { - event_t* cur = (event_t *)n; - if (timercmp(&cur->tv, &ev->tv, <)) { - prev = n; - } else { - break; - } - } - } - - /* Append to list. */ - ev->parent = s; - if (prev) { - insert_node(&ev->n, prev); - } else { - add_head(&s->calendar, &ev->n); - } - + heap_insert(&s->heap, ev); /* Unlock calendar. */ pthread_cond_signal(&s->notify); @@ -293,6 +287,8 @@ event_t* evsched_schedule_term(evsched_t *s, uint32_t dt) int evsched_cancel(evsched_t *s, event_t *ev) { + int found; + if (!s || !ev) { return -1; } @@ -303,19 +299,8 @@ int evsched_cancel(evsched_t *s, event_t *ev) /* Lock calendar. */ pthread_mutex_lock(&s->mx); - /* Find in list. */ - event_t *n = 0; - int found = 0; - WALK_LIST(n, s->calendar) { - if (n == ev) { - found = 1; - break; - } - } - - /* Remove from list. */ - if (found) { - rem_node(&ev->n); + if ((found = heap_find(&s->heap, ev))) { + heap_delete(&s->heap, found); } /* Unlock calendar. */ diff --git a/src/common/evsched.h b/src/common/evsched.h index 8ca9c622d4e09ca8ae996c5566caf6f8ead2826f..47bf672a17e6fc9d75428b059720ea5ef0abf846 100644 --- a/src/common/evsched.h +++ b/src/common/evsched.h @@ -68,7 +68,7 @@ #include <pthread.h> #include "common/slab/slab.h" -#include "common/lists.h" +#include "common/heap.h" #include "common/evqueue.h" /*! @@ -92,7 +92,7 @@ typedef struct { event_t *current; /*!< Current running event. */ pthread_mutex_t mx; /*!< Event queue locking. */ pthread_cond_t notify; /*!< Event queue notification. */ - list calendar; /*!< Event calendar. */ + struct heap heap; struct { slab_cache_t alloc; /*!< Events SLAB cache. */ pthread_mutex_t lock; /*!< Events cache spin lock. */