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()
This commit is contained in:
parent
414b8b99c3
commit
d6d81f2e44
5 changed files with 66 additions and 8 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ struct lumiera_threadpool_struct
|
|||
void
|
||||
lumiera_threadpool_init(void);
|
||||
|
||||
void
|
||||
lumiera_threadpool_destroy(void);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue