thread deadlines, first implementation
This commit is contained in:
parent
cc4dc25f4a
commit
7371db8a2c
2 changed files with 100 additions and 0 deletions
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
//TODO: System includes//
|
//TODO: System includes//
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,6 +137,8 @@ lumiera_thread_run (enum lumiera_thread_class kind,
|
||||||
self->function = function;
|
self->function = function;
|
||||||
self->arguments = arg;
|
self->arguments = arg;
|
||||||
|
|
||||||
|
self->deadline.tv_sec = 0;
|
||||||
|
|
||||||
// and let it really run (signal the condition var, the thread waits on it)
|
// and let it really run (signal the condition var, the thread waits on it)
|
||||||
self->state = LUMIERA_THREADSTATE_WAKEUP;
|
self->state = LUMIERA_THREADSTATE_WAKEUP;
|
||||||
|
|
||||||
|
|
@ -169,6 +172,8 @@ lumiera_thread_new (enum lumiera_thread_class kind,
|
||||||
self->state = LUMIERA_THREADSTATE_STARTUP;
|
self->state = LUMIERA_THREADSTATE_STARTUP;
|
||||||
self->function = NULL;
|
self->function = NULL;
|
||||||
self->arguments = NULL;
|
self->arguments = NULL;
|
||||||
|
self->deadline.tv_sec = 0;
|
||||||
|
self->deadline.tv_nsec = 0;
|
||||||
|
|
||||||
int error = pthread_create (&self->id, attrs, &thread_loop, self);
|
int error = pthread_create (&self->id, attrs, &thread_loop, self);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
@ -223,6 +228,65 @@ lumiera_thread_self (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a threads deadline
|
||||||
|
* A thread must finish before its deadline is hit. Otherwise it counts as stalled
|
||||||
|
* which is a fatal error which might pull the application down.
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_set (struct timespec deadline)
|
||||||
|
{
|
||||||
|
LumieraThread self = lumiera_thread_self ();
|
||||||
|
if (self)
|
||||||
|
self->deadline = deadline;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend a threads deadline
|
||||||
|
* sets the deadline to now+ms in future. This can be used to implement a heartbeat.
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_extend (unsigned ms)
|
||||||
|
{
|
||||||
|
LumieraThread self = lumiera_thread_self ();
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
struct timespec deadline;
|
||||||
|
clock_gettime (CLOCK_REALTIME, &deadline);
|
||||||
|
deadline.tv_sec += ms / 1000;
|
||||||
|
deadline.tv_nsec += 1000000 * (ms % 1000);
|
||||||
|
if (deadline.tv_nsec > 1000000000)
|
||||||
|
{
|
||||||
|
deadline.tv_sec += (deadline.tv_nsec / 1000000000);
|
||||||
|
deadline.tv_nsec %= 1000000000;
|
||||||
|
}
|
||||||
|
self->deadline = deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a threads deadline
|
||||||
|
* Threads without deadline will not be checked against deadlocks (this is the default)
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_clear (void)
|
||||||
|
{
|
||||||
|
LumieraThread self = lumiera_thread_self ();
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
self->deadline.tv_sec = 0;
|
||||||
|
self->deadline.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LumieraThread
|
LumieraThread
|
||||||
lumiera_thread_sync_other (LumieraThread other, int state)
|
lumiera_thread_sync_other (LumieraThread other, int state)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,8 @@ struct lumiera_thread_struct
|
||||||
// TODO: maybe this condition variable should be renamed when we have a better understanding of how it will be used
|
// TODO: maybe this condition variable should be renamed when we have a better understanding of how it will be used
|
||||||
lumiera_condition signal; // control signal, state change signal
|
lumiera_condition signal; // control signal, state change signal
|
||||||
|
|
||||||
|
struct timespec deadline;
|
||||||
|
|
||||||
struct nobug_resource_user** rh;
|
struct nobug_resource_user** rh;
|
||||||
|
|
||||||
// the following member could have been called "class" except that it would conflict with C++ keyword
|
// the following member could have been called "class" except that it would conflict with C++ keyword
|
||||||
|
|
@ -210,6 +212,40 @@ lumiera_thread_run (enum lumiera_thread_class kind,
|
||||||
LumieraThread
|
LumieraThread
|
||||||
lumiera_thread_self (void);
|
lumiera_thread_self (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Heartbeat and Deadlines
|
||||||
|
*
|
||||||
|
* Any thread can have an optional 'deadline' which must never be hit.
|
||||||
|
* This deadlines are lazily checked and if hit this is a fatal error which triggers
|
||||||
|
* an emergency shutdown. Thus threads are obliged to set and extend their deadlines
|
||||||
|
* accordingly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a threads deadline
|
||||||
|
* A thread must finish before its deadline is hit. Otherwise it counts as stalled
|
||||||
|
* which is a fatal error which might pull the application down.
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_set (struct timespec deadline);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend a threads deadline
|
||||||
|
* sets the deadline to now+ms in future. This can be used to implement a heartbeat.
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_extend (unsigned ms);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear a threads deadline
|
||||||
|
* Threads without deadline will not be checked against deadlocks (this is the default)
|
||||||
|
*/
|
||||||
|
LumieraThread
|
||||||
|
lumiera_thread_deadline_clear (void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread syncronization
|
* Thread syncronization
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue