2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 16:15:27 +00:00
This commit is contained in:
Bob Halley
1998-08-18 19:28:30 +00:00
parent d6da3b9e10
commit 50f339a799
7 changed files with 139 additions and 90 deletions

View File

@@ -7,6 +7,9 @@
#include <isc/memcluster.h> #include <isc/memcluster.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/thread.h>
mem_context_t mctx = NULL;
/*ARGSUSED*/ /*ARGSUSED*/
static boolean_t static boolean_t
@@ -37,9 +40,49 @@ my_shutdown(task_t __attribute__((unused)) task,
return (TRUE); 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 void
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
mem_context_t mctx = NULL;
task_manager_t manager = NULL; task_manager_t manager = NULL;
task_t t1 = NULL, t2 = NULL; task_t t1 = NULL, t2 = NULL;
task_t t3 = NULL, t4 = 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, "3", my_shutdown, 0, &t3));
INSIST(task_create(manager, "4", my_shutdown, 0, &t4)); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); event = event_get(mctx, 1, my_callback, sizeof *event);
task_send_event(t4, event); task_send_event(t4, &event);
task_detach(&t1); task_detach(&t1);
task_detach(&t2); task_detach(&t2);

View File

@@ -92,10 +92,10 @@ boolean_t task_create(task_manager_t,
event_action_t, event_action_t,
unsigned int, unsigned int,
task_t *); task_t *);
boolean_t task_attach(task_t, task_t *); void task_attach(task_t, task_t *);
void task_detach(task_t *); void task_detach(task_t *);
boolean_t task_send_event(task_t, boolean_t task_send_event(task_t,
generic_event_t); generic_event_t *);
void task_shutdown(task_t); void task_shutdown(task_t);
void task_destroy(task_t *); void task_destroy(task_t *);

View File

@@ -24,11 +24,14 @@
#include "attribute.h" #include "attribute.h"
#include <isc/assertions.h> #include <isc/assertions.h>
#include <isc/mutex.h>
#include <isc/memcluster.h> #include <isc/memcluster.h>
#ifdef MULTITHREADED
#include <isc/mutex.h>
#endif
#if !defined(LINT) && !defined(CODECENTER) #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 */ #endif /* not lint */
/* /*
@@ -91,12 +94,17 @@ static size_t quantize(size_t);
#define ALIGNMENT_SIZE sizeof (void *) #define ALIGNMENT_SIZE sizeof (void *)
#define NUM_BASIC_BLOCKS 64 /* must be > 1 */ #define NUM_BASIC_BLOCKS 64 /* must be > 1 */
#define LOCK_CONTEXT(ctx) os_mutex_lock(&(ctx)->mutex) #ifdef MULTITHREADED
#define UNLOCK_CONTEXT(ctx) os_mutex_unlock(&(ctx)->mutex) #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. */ /* Private Inline-able. */
static __inline__ size_t static inline size_t
quantize(size_t size) { quantize(size_t size) {
int remainder; int remainder;
@@ -149,7 +157,12 @@ mem_context_create(size_t init_max_size, size_t target_size,
ctx->basic_blocks = NULL; ctx->basic_blocks = NULL;
ctx->lowest = NULL; ctx->lowest = NULL;
ctx->highest = 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; *ctxp = ctx;
return (0); return (0);
} }

View File

@@ -2,28 +2,16 @@
#ifndef CONDITION_H #ifndef CONDITION_H
#define CONDITION_H 1 #define CONDITION_H 1
#ifdef MULTITHREADED
#include <pthread.h> #include <pthread.h>
#include <isc/assertions.h> #include <isc/assertions.h>
typedef pthread_cond_t os_condition_t; typedef pthread_cond_t os_condition_t;
#define OS_CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER #define OS_CONDITION_INITIALIZER PTHREAD_COND_INITIALIZER
#define os_condition_init(cp) INSIST(pthread_cond_init((cp), NULL) \ #define os_condition_init(cp) (pthread_cond_init((cp), NULL) == 0)
== 0) #define os_condition_wait(cp, mp) (pthread_cond_wait((cp), (mp)) == 0)
#define os_condition_wait(cp, mp) INSIST(pthread_cond_wait((cp), (mp)) \ #define os_condition_signal(cp) (pthread_cond_signal((cp)) == 0)
== 0) #define os_condition_broadcast(cp) (pthread_cond_broadcast((cp)) == 0)
#define os_condition_signal(cp) INSIST(pthread_cond_signal((cp)) == 0) #define os_condition_destroy(cp) (pthread_cond_destroy((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
#endif /* CONDITION_H */ #endif /* CONDITION_H */

View File

@@ -2,28 +2,14 @@
#ifndef MUTEX_H #ifndef MUTEX_H
#define MUTEX_H 1 #define MUTEX_H 1
#ifdef MULTITHREADED
#include <pthread.h> #include <pthread.h>
#include <isc/assertions.h>
typedef pthread_mutex_t os_mutex_t; typedef pthread_mutex_t os_mutex_t;
#define OS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define OS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define os_mutex_init(mp) INSIST(pthread_mutex_init((mp), NULL) == 0) #define os_mutex_init(mp) (pthread_mutex_init((mp), NULL) == 0)
#define os_mutex_lock(mp) INSIST(pthread_mutex_lock((mp)) == 0) #define os_mutex_lock(mp) (pthread_mutex_lock((mp)) == 0)
#define os_mutex_unlock(mp) INSIST(pthread_mutex_unlock((mp)) == 0) #define os_mutex_unlock(mp) (pthread_mutex_unlock((mp)) == 0)
#define os_mutex_destroy(mp) INSIST(pthread_mutex_destroy((mp)) == 0) #define os_mutex_destroy(mp) (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
#endif /* MUTEX_H */ #endif /* MUTEX_H */

View File

@@ -2,8 +2,6 @@
#ifndef THREAD_H #ifndef THREAD_H
#define THREAD_H 1 #define THREAD_H 1
#ifdef MULTITHREADED
#include <pthread.h> #include <pthread.h>
#include <isc/assertions.h> #include <isc/assertions.h>
@@ -12,12 +10,6 @@ typedef pthread_t os_thread_t;
#define os_thread_create(s, a, tp) (pthread_create((tp), NULL, (s), (a)) \ #define os_thread_create(s, a, tp) (pthread_create((tp), NULL, (s), (a)) \
== 0) == 0)
#define os_thread_detach(t) INSIST(pthread_detach((t)) == 0) #define os_thread_detach(t) (pthread_detach((t)) == 0)
#else
#error Threads are not meaningful for a non-threaded program.
#endif
#endif /* THREAD_H */ #endif /* THREAD_H */

View File

@@ -12,14 +12,16 @@
(t)->magic == TASK_MAGIC) (t)->magic == TASK_MAGIC)
/* /*
* We use macros instead of calling the os_ routines * We use macros instead of calling the os_ routines directly because
* directly because the capital letters make the * the capital letters make the locking stand out.
* 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 LOCK(lp) INSIST(os_mutex_lock((lp)))
#define UNLOCK(lp) os_mutex_unlock((lp)) #define UNLOCK(lp) INSIST(os_mutex_unlock((lp)))
#define WAIT(cvp, lp) os_condition_wait((cvp), (lp)) #define WAIT(cvp, lp) INSIST(os_condition_wait((cvp), (lp)))
#define BROADCAST(cvp) os_condition_broadcast((cvp)) #define BROADCAST(cvp) INSIST(os_condition_broadcast((cvp)))
#define DEFAULT_DEFAULT_QUANTUM 5 #define DEFAULT_DEFAULT_QUANTUM 5
@@ -85,7 +87,7 @@ task_free(task_t task) {
BROADCAST(&manager->work_available); BROADCAST(&manager->work_available);
} }
UNLOCK(&manager->lock); UNLOCK(&manager->lock);
os_mutex_destroy(&task->lock); (void)os_mutex_destroy(&task->lock);
task->magic = 0; task->magic = 0;
mem_put(manager->mctx, task, sizeof *task); mem_put(manager->mctx, task, sizeof *task);
} }
@@ -106,7 +108,10 @@ task_create(task_manager_t manager, void *arg,
task->magic = TASK_MAGIC; task->magic = TASK_MAGIC;
task->manager = manager; 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->state = task_state_idle;
task->references = 1; task->references = 1;
INIT_LIST(task->events); INIT_LIST(task->events);
@@ -128,7 +133,7 @@ task_create(task_manager_t manager, void *arg,
return (TRUE); return (TRUE);
} }
boolean_t void
task_attach(task_t task, task_t *taskp) { task_attach(task_t task, task_t *taskp) {
REQUIRE(VALID_TASK(task)); REQUIRE(VALID_TASK(task));
@@ -139,8 +144,6 @@ task_attach(task_t task, task_t *taskp) {
UNLOCK(&task->lock); UNLOCK(&task->lock);
*taskp = task; *taskp = task;
return (TRUE);
} }
void void
@@ -173,11 +176,14 @@ task_detach(task_t *taskp) {
} }
boolean_t 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 was_idle = FALSE;
boolean_t discard = FALSE; boolean_t discard = FALSE;
generic_event_t event;
REQUIRE(VALID_TASK(task)); REQUIRE(VALID_TASK(task));
REQUIRE(eventp != NULL);
event = *eventp;
REQUIRE(event != NULL); REQUIRE(event != NULL);
XTRACE("sending"); XTRACE("sending");
@@ -202,6 +208,7 @@ task_send_event(task_t task, generic_event_t event) {
if (discard) { if (discard) {
event_put(event); event_put(event);
*eventp = NULL;
return (TRUE); return (TRUE);
} }
@@ -245,6 +252,8 @@ task_send_event(task_t task, generic_event_t event) {
BROADCAST(&manager->work_available); BROADCAST(&manager->work_available);
} }
*eventp = NULL;
XTRACE("sent"); XTRACE("sent");
return (TRUE); return (TRUE);
} }
@@ -557,9 +566,9 @@ void *task_manager_run(void *uap) {
static void static void
manager_free(task_manager_t manager) { manager_free(task_manager_t manager) {
os_condition_destroy(&manager->work_available); (void)os_condition_destroy(&manager->work_available);
os_condition_destroy(&manager->no_workers); (void)os_condition_destroy(&manager->no_workers);
os_mutex_destroy(&manager->lock); (void)os_mutex_destroy(&manager->lock);
manager->magic = 0; manager->magic = 0;
mem_put(manager->mctx, manager, sizeof *manager); mem_put(manager->mctx, manager, sizeof *manager);
} }
@@ -577,16 +586,28 @@ task_manager_create(mem_context_t mctx, unsigned int workers,
return (0); return (0);
manager->magic = TASK_MANAGER_MAGIC; manager->magic = TASK_MANAGER_MAGIC;
manager->mctx = mctx; 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) if (default_quantum == 0)
default_quantum = DEFAULT_DEFAULT_QUANTUM; default_quantum = DEFAULT_DEFAULT_QUANTUM;
manager->default_quantum = default_quantum; manager->default_quantum = default_quantum;
INIT_LIST(manager->tasks); INIT_LIST(manager->tasks);
INIT_LIST(manager->ready_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->exiting = FALSE;
manager->workers = 0; 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); 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)) { if (os_thread_create(task_manager_run, manager, &thread)) {
manager->workers++; manager->workers++;
started++; started++;
os_thread_detach(thread); (void)os_thread_detach(thread);
} }
} }
UNLOCK(&manager->lock); UNLOCK(&manager->lock);