From d6d81f2e441b43d06021a025aabf06ebb2775fd8 Mon Sep 17 00:00:00 2001 From: Michael Ploujnikov Date: Tue, 24 Nov 2009 22:25:00 -0500 Subject: [PATCH] added lumiera_threadpool_destroy() added locking and checks to lumiera_threadpool_acquire_thread() added a nobug flag to threads.c added lumiera_thread_destroy() added lumiera_thread_delete() --- src/backend/threadpool.c | 36 +++++++++++++++++++++++++++------ src/backend/threadpool.h | 3 +++ src/backend/threads.c | 27 +++++++++++++++++++++++-- src/backend/threads.h | 6 ++++++ tests/backend/test-threadpool.c | 2 ++ 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/src/backend/threadpool.c b/src/backend/threadpool.c index 87ca3803c..970e7291c 100644 --- a/src/backend/threadpool.c +++ b/src/backend/threadpool.c @@ -37,7 +37,7 @@ static lumiera_threadpool threadpool; * @file * */ -NOBUG_DEFINE_FLAG_PARENT (threadpool, threads_dbg); +NOBUG_DEFINE_FLAG_PARENT (threadpool, threads_dbg); /*TODO insert a suitable/better parent flag here */ //code goes here// @@ -62,24 +62,48 @@ lumiera_threadpool_init(void) } } +void +lumiera_threadpool_destroy(void) +{ + for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) + { + // no locking is done at this point + LLIST_FOREACH(&threadpool.kind[i].pool, thread) + { + llist_unlink(thread); + lumiera_thread_delete((LumieraThread)thread); + } + + lumiera_mutex_destroy (&threadpool.kind[i].lock, &NOBUG_FLAG (threadpool)); + } +} + LumieraThread lumiera_threadpool_acquire_thread(enum lumiera_thread_class kind, const char* purpose, struct nobug_flag* flag) { - // TODO: do we need to check that index 'kind' is within range? - // TODO: do we need to check that we get a valid list? - // TODO: do proper locking when manipulating the list + LumieraThread ret; + + REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "unknown pool kind specified: %d", kind); + REQUIRE (&threadpool.kind[kind].pool, "threadpool kind %d does not exist", kind); if (llist_is_empty (&threadpool.kind[kind].pool)) { - return lumiera_thread_new (kind, NULL, purpose, flag); + // TODO: fill in the reccondition argument, currently NULL + ret = lumiera_thread_new (kind, NULL, purpose, flag); } else { + REQUIRE (&threadpool.kind[kind].lock, "invalid threadpool lock"); // use an existing thread, pick the first one // remove it from the pool's list - return (LumieraThread)(llist_unlink(llist_head (&threadpool.kind[kind].pool))); + LUMIERA_MUTEX_SECTION (threadpool, &threadpool.kind[kind].lock) + { + ret = (LumieraThread)(llist_unlink(llist_head (&threadpool.kind[kind].pool))); + } } + REQUIRE(ret, "did not find a valid thread"); + return ret; } void diff --git a/src/backend/threadpool.h b/src/backend/threadpool.h index f6b359150..0d2a0257f 100644 --- a/src/backend/threadpool.h +++ b/src/backend/threadpool.h @@ -80,6 +80,9 @@ struct lumiera_threadpool_struct void lumiera_threadpool_init(void); +void +lumiera_threadpool_destroy(void); + #endif /* // Local Variables: diff --git a/src/backend/threads.c b/src/backend/threads.c index e87853765..6104a8011 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -40,7 +40,7 @@ * */ -//NOBUG_DEFINE_FLAG_PARENT (threads, lumiera); /*TODO insert a suitable/better parent flag here */ +NOBUG_DEFINE_FLAG_PARENT (threads, threads_dbg); /*TODO insert a suitable/better parent flag here */ //code goes here// @@ -158,6 +158,7 @@ lumiera_thread_new (enum lumiera_thread_class kind, const char* purpose, struct nobug_flag* flag) { + // TODO: do something with these: (void) purpose; (void) flag; @@ -166,11 +167,15 @@ lumiera_thread_new (enum lumiera_thread_class kind, LumieraThread self = lumiera_malloc (sizeof (*self)); llist_init(&self->node); - // self->id = (pthread_t)NULL; initialized by pthread_create() self->finished = finished; + REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "invalid thread kind specified: %d", kind); self->kind = kind; self->state = LUMIERA_THREADSTATE_IDLE; + REQUIRE (&self->id); + //REQUIRE (&attrs); + //REQUIRE (&thread_loop); + REQUIRE (self); int error = pthread_create (&self->id, &attrs, &thread_loop, self); if (error) @@ -182,6 +187,24 @@ lumiera_thread_new (enum lumiera_thread_class kind, return self; } +LumieraThread +lumiera_thread_destroy (LumieraThread self) +{ + // TODO: stop the pthread + // TODO: empty the list/node? + //finished = NULL; // or free(finished)? + lumiera_reccondition_destroy (self->finished, &NOBUG_FLAG(threads)); + //kind = 0; + //state = 0; + return self; +} + +void +lumiera_thread_delete (LumieraThread self) +{ + lumiera_free (lumiera_thread_destroy (self)); +} + /* // Local Variables: // mode: C diff --git a/src/backend/threads.h b/src/backend/threads.h index ec93c4df6..51000782a 100644 --- a/src/backend/threads.h +++ b/src/backend/threads.h @@ -118,6 +118,12 @@ lumiera_thread_new (enum lumiera_thread_class kind, const char* purpose, struct nobug_flag* flag); +LumieraThread +lumiera_thread_destroy (LumieraThread self); + +void +lumiera_thread_delete (LumieraThread self); + /** * Start a thread. * Threads are implemented as procedures which take a void* and dont return anything. diff --git a/tests/backend/test-threadpool.c b/tests/backend/test-threadpool.c index 301688f48..be3b4311c 100644 --- a/tests/backend/test-threadpool.c +++ b/tests/backend/test-threadpool.c @@ -60,6 +60,8 @@ TEST ("basic-acquire-release") ECHO("releasing thread 2"); lumiera_threadpool_release_thread(t2); ECHO("thread 2 has been released"); + + lumiera_threadpool_destroy(); } TESTS_END