diff --git a/bin/tests/task_test.c b/bin/tests/task_test.c index f48bd97b9a..3a66b1374e 100644 --- a/bin/tests/task_test.c +++ b/bin/tests/task_test.c @@ -7,6 +7,9 @@ #include #include +#include + +mem_context_t mctx = NULL; /*ARGSUSED*/ static boolean_t @@ -37,9 +40,49 @@ my_shutdown(task_t __attribute__((unused)) task, return (TRUE); } +/*ARGSUSED*/ +static boolean_t +my_tick(task_t __attribute__((unused)) task, + void *arg, + generic_event_t __attribute__((unused)) event) +{ + char *name = arg; + + printf("tick %s\n", name); + return (FALSE); +} + +void * +simple_timer_run(void *arg) { + task_t task = arg; + generic_event_t event; + int i; + + for (i = 0; i < 10; i++) { + sleep(1); + printf("sending timer to %p\n", task); + event = event_get(mctx, 2, my_tick, sizeof *event); + INSIST(event != NULL); + (void)task_send_event(task, &event); + } + + task_detach(&task); + return (NULL); +} + +void +simple_timer_init(task_t task) { + os_thread_t t; + task_t task_clone; + + task_clone = NULL; + task_attach(task, &task_clone); + INSIST(os_thread_create(simple_timer_run, task_clone, &t)); + (void)os_thread_detach(t); +} + void main(int argc, char *argv[]) { - mem_context_t mctx = NULL; task_manager_t manager = NULL; task_t t1 = NULL, t2 = NULL; task_t t3 = NULL, t4 = NULL; @@ -61,36 +104,42 @@ main(int argc, char *argv[]) { INSIST(task_create(manager, "3", my_shutdown, 0, &t3)); INSIST(task_create(manager, "4", my_shutdown, 0, &t4)); + simple_timer_init(t1); + simple_timer_init(t2); + printf("task 1 = %p\n", t1); + printf("task 2 = %p\n", t2); + sleep(2); + event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t1, event); + task_send_event(t1, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t2, event); + task_send_event(t2, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t3, event); + task_send_event(t3, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t4, event); + task_send_event(t4, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t2, event); + task_send_event(t2, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t3, event); + task_send_event(t3, &event); event = event_get(mctx, 1, my_callback, sizeof *event); - task_send_event(t4, event); + task_send_event(t4, &event); task_detach(&t1); task_detach(&t2); diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index c3feb549e1..1bce80b231 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -92,10 +92,10 @@ boolean_t task_create(task_manager_t, event_action_t, unsigned int, task_t *); -boolean_t task_attach(task_t, task_t *); +void task_attach(task_t, task_t *); void task_detach(task_t *); boolean_t task_send_event(task_t, - generic_event_t); + generic_event_t *); void task_shutdown(task_t); void task_destroy(task_t *); diff --git a/lib/isc/mem.c b/lib/isc/mem.c index ec96405ecc..545add6f5d 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -24,11 +24,14 @@ #include "attribute.h" #include -#include #include +#ifdef MULTITHREADED +#include +#endif + #if !defined(LINT) && !defined(CODECENTER) -static char rcsid[] __attribute__((unused)) = "$Id: mem.c,v 1.3 1998/08/18 00:47:51 halley Exp $"; +static char rcsid[] __attribute__((unused)) = "$Id: mem.c,v 1.4 1998/08/18 19:28:28 halley Exp $"; #endif /* not lint */ /* @@ -91,12 +94,17 @@ static size_t quantize(size_t); #define ALIGNMENT_SIZE sizeof (void *) #define NUM_BASIC_BLOCKS 64 /* must be > 1 */ -#define LOCK_CONTEXT(ctx) os_mutex_lock(&(ctx)->mutex) -#define UNLOCK_CONTEXT(ctx) os_mutex_unlock(&(ctx)->mutex) +#ifdef MULTITHREADED +#define LOCK_CONTEXT(ctx) INSIST(os_mutex_lock(&(ctx)->mutex)) +#define UNLOCK_CONTEXT(ctx) INSIST(os_mutex_unlock(&(ctx)->mutex)) +#else +#define LOCK_CONTEXT(ctx) +#define UNLOCK_CONTEXT(ctx) +#endif /* Private Inline-able. */ -static __inline__ size_t +static inline size_t quantize(size_t size) { int remainder; @@ -149,7 +157,12 @@ mem_context_create(size_t init_max_size, size_t target_size, ctx->basic_blocks = NULL; ctx->lowest = NULL; ctx->highest = NULL; - os_mutex_init(&ctx->mutex); + if (!os_mutex_init(&ctx->mutex)) { + free(ctx->stats); + free(ctx->freelists); + free(ctx); + return (-1); + } *ctxp = ctx; return (0); } diff --git a/lib/isc/pthreads/include/isc/condition.h b/lib/isc/pthreads/include/isc/condition.h index 1d8832d10c..ff118e9ece 100644 --- a/lib/isc/pthreads/include/isc/condition.h +++ b/lib/isc/pthreads/include/isc/condition.h @@ -2,28 +2,16 @@ #ifndef CONDITION_H #define CONDITION_H 1 -#ifdef MULTITHREADED - #include #include typedef pthread_cond_t os_condition_t; #define OS_CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER -#define os_condition_init(cp) INSIST(pthread_cond_init((cp), NULL) \ - == 0) -#define os_condition_wait(cp, mp) INSIST(pthread_cond_wait((cp), (mp)) \ - == 0) -#define os_condition_signal(cp) INSIST(pthread_cond_signal((cp)) == 0) -#define os_condition_broadcast(cp) INSIST(pthread_cond_broadcast((cp)) \ - == 0) -#define os_condition_destroy(cp) INSIST(pthread_cond_destroy((cp)) \ - == 0) - -#else - -#error Condition variables are not meaningful for a non-threaded program. - -#endif +#define os_condition_init(cp) (pthread_cond_init((cp), NULL) == 0) +#define os_condition_wait(cp, mp) (pthread_cond_wait((cp), (mp)) == 0) +#define os_condition_signal(cp) (pthread_cond_signal((cp)) == 0) +#define os_condition_broadcast(cp) (pthread_cond_broadcast((cp)) == 0) +#define os_condition_destroy(cp) (pthread_cond_destroy((cp)) == 0) #endif /* CONDITION_H */ diff --git a/lib/isc/pthreads/include/isc/mutex.h b/lib/isc/pthreads/include/isc/mutex.h index 24346fa90c..724408a0c2 100644 --- a/lib/isc/pthreads/include/isc/mutex.h +++ b/lib/isc/pthreads/include/isc/mutex.h @@ -2,28 +2,14 @@ #ifndef MUTEX_H #define MUTEX_H 1 -#ifdef MULTITHREADED - #include -#include -typedef pthread_mutex_t os_mutex_t; -#define OS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t os_mutex_t; +#define OS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -#define os_mutex_init(mp) INSIST(pthread_mutex_init((mp), NULL) == 0) -#define os_mutex_lock(mp) INSIST(pthread_mutex_lock((mp)) == 0) -#define os_mutex_unlock(mp) INSIST(pthread_mutex_unlock((mp)) == 0) -#define os_mutex_destroy(mp) INSIST(pthread_mutex_destroy((mp)) == 0) - -#else - -typedef int os_mutex_t; -#define OS_MUTEX_INITIALIZER 0 - -#define os_mutex_init(mp) -#define os_mutex_lock(mp) -#define os_mutex_unlock(mp) - -#endif +#define os_mutex_init(mp) (pthread_mutex_init((mp), NULL) == 0) +#define os_mutex_lock(mp) (pthread_mutex_lock((mp)) == 0) +#define os_mutex_unlock(mp) (pthread_mutex_unlock((mp)) == 0) +#define os_mutex_destroy(mp) (pthread_mutex_destroy((mp)) == 0) #endif /* MUTEX_H */ diff --git a/lib/isc/pthreads/include/isc/thread.h b/lib/isc/pthreads/include/isc/thread.h index 3afca332f3..33dbe6709c 100644 --- a/lib/isc/pthreads/include/isc/thread.h +++ b/lib/isc/pthreads/include/isc/thread.h @@ -2,8 +2,6 @@ #ifndef THREAD_H #define THREAD_H 1 -#ifdef MULTITHREADED - #include #include @@ -12,12 +10,6 @@ typedef pthread_t os_thread_t; #define os_thread_create(s, a, tp) (pthread_create((tp), NULL, (s), (a)) \ == 0) -#define os_thread_detach(t) INSIST(pthread_detach((t)) == 0) - -#else - -#error Threads are not meaningful for a non-threaded program. - -#endif +#define os_thread_detach(t) (pthread_detach((t)) == 0) #endif /* THREAD_H */ diff --git a/lib/isc/task.c b/lib/isc/task.c index cc3fec0105..821485355d 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -12,14 +12,16 @@ (t)->magic == TASK_MAGIC) /* - * We use macros instead of calling the os_ routines - * directly because the capital letters make the - * locking stand out. + * We use macros instead of calling the os_ routines directly because + * the capital letters make the locking stand out. + * + * We INSIST that they succeed since there's no way for us to continue + * if they fail. */ -#define LOCK(lp) os_mutex_lock((lp)) -#define UNLOCK(lp) os_mutex_unlock((lp)) -#define WAIT(cvp, lp) os_condition_wait((cvp), (lp)) -#define BROADCAST(cvp) os_condition_broadcast((cvp)) +#define LOCK(lp) INSIST(os_mutex_lock((lp))) +#define UNLOCK(lp) INSIST(os_mutex_unlock((lp))) +#define WAIT(cvp, lp) INSIST(os_condition_wait((cvp), (lp))) +#define BROADCAST(cvp) INSIST(os_condition_broadcast((cvp))) #define DEFAULT_DEFAULT_QUANTUM 5 @@ -85,7 +87,7 @@ task_free(task_t task) { BROADCAST(&manager->work_available); } UNLOCK(&manager->lock); - os_mutex_destroy(&task->lock); + (void)os_mutex_destroy(&task->lock); task->magic = 0; mem_put(manager->mctx, task, sizeof *task); } @@ -106,7 +108,10 @@ task_create(task_manager_t manager, void *arg, task->magic = TASK_MAGIC; task->manager = manager; - os_mutex_init(&task->lock); + if (!os_mutex_init(&task->lock)) { + mem_put(manager->mctx, task, sizeof *task); + return (FALSE); + } task->state = task_state_idle; task->references = 1; INIT_LIST(task->events); @@ -128,7 +133,7 @@ task_create(task_manager_t manager, void *arg, return (TRUE); } -boolean_t +void task_attach(task_t task, task_t *taskp) { REQUIRE(VALID_TASK(task)); @@ -139,8 +144,6 @@ task_attach(task_t task, task_t *taskp) { UNLOCK(&task->lock); *taskp = task; - - return (TRUE); } void @@ -173,11 +176,14 @@ task_detach(task_t *taskp) { } boolean_t -task_send_event(task_t task, generic_event_t event) { +task_send_event(task_t task, generic_event_t *eventp) { boolean_t was_idle = FALSE; boolean_t discard = FALSE; + generic_event_t event; REQUIRE(VALID_TASK(task)); + REQUIRE(eventp != NULL); + event = *eventp; REQUIRE(event != NULL); XTRACE("sending"); @@ -202,6 +208,7 @@ task_send_event(task_t task, generic_event_t event) { if (discard) { event_put(event); + *eventp = NULL; return (TRUE); } @@ -245,6 +252,8 @@ task_send_event(task_t task, generic_event_t event) { BROADCAST(&manager->work_available); } + *eventp = NULL; + XTRACE("sent"); return (TRUE); } @@ -557,9 +566,9 @@ void *task_manager_run(void *uap) { static void manager_free(task_manager_t manager) { - os_condition_destroy(&manager->work_available); - os_condition_destroy(&manager->no_workers); - os_mutex_destroy(&manager->lock); + (void)os_condition_destroy(&manager->work_available); + (void)os_condition_destroy(&manager->no_workers); + (void)os_mutex_destroy(&manager->lock); manager->magic = 0; mem_put(manager->mctx, manager, sizeof *manager); } @@ -577,16 +586,28 @@ task_manager_create(mem_context_t mctx, unsigned int workers, return (0); manager->magic = TASK_MANAGER_MAGIC; manager->mctx = mctx; - os_mutex_init(&manager->lock); + if (!os_mutex_init(&manager->lock)) { + mem_put(mctx, manager, sizeof *manager); + return (0); + } if (default_quantum == 0) default_quantum = DEFAULT_DEFAULT_QUANTUM; manager->default_quantum = default_quantum; INIT_LIST(manager->tasks); INIT_LIST(manager->ready_tasks); - os_condition_init(&manager->work_available); + if (!os_condition_init(&manager->work_available)) { + (void)os_mutex_destroy(&manager->lock); + mem_put(mctx, manager, sizeof *manager); + return (0); + } manager->exiting = FALSE; manager->workers = 0; - os_condition_init(&manager->no_workers); + if (!os_condition_init(&manager->no_workers)) { + (void)os_condition_destroy(&manager->work_available); + (void)os_mutex_destroy(&manager->lock); + mem_put(mctx, manager, sizeof *manager); + return (0); + } LOCK(&manager->lock); /* @@ -596,7 +617,7 @@ task_manager_create(mem_context_t mctx, unsigned int workers, if (os_thread_create(task_manager_run, manager, &thread)) { manager->workers++; started++; - os_thread_detach(thread); + (void)os_thread_detach(thread); } } UNLOCK(&manager->lock);