Commit fe91ab09 authored by Philippe Gerum's avatar Philippe Gerum

copperplate/threadobj: do not assume timer_id cannot be zero

Unlike glibc, libcobalt may return zero as a valid timer id. Use a
threadobj status flag to figure out whether a periodic timer was set
for the thread, instead of testing periodic_timer for NULLness.

This fixes set_periodic/wait_period services which have been broken
since commit #73de42cc was merged.
parent 7fffb263
......@@ -147,6 +147,7 @@ void threadobj_save_timeout(struct threadobj_corespec *corespec,
#define __THREAD_S_ACTIVE (1 << 4) /* Running user code. */
#define __THREAD_S_SUSPENDED (1 << 5) /* Suspended via threadobj_suspend(). */
#define __THREAD_S_SAFE (1 << 6) /* TCB release deferred. */
#define __THREAD_S_PERIODIC (1 << 7) /* Periodic timer set. */
#define __THREAD_S_DEBUG (1 << 31) /* Debug mode enabled. */
/*
* threadobj->run_state, locklessly updated by "current", merged
......
......@@ -1193,7 +1193,7 @@ static void uninit_thread(struct threadobj *thobj)
static void destroy_thread(struct threadobj *thobj)
{
threadobj_cleanup_corespec(thobj);
if (thobj->periodic_timer)
if (thobj->status & __THREAD_S_PERIODIC)
__RT(timer_delete(thobj->periodic_timer));
uninit_thread(thobj);
}
......@@ -1632,14 +1632,14 @@ int threadobj_set_periodic(struct threadobj *thobj,
timer = thobj->periodic_timer;
if (!timespec_scalar(idate) && !timespec_scalar(period)) {
if (timer) {
thobj->periodic_timer = NULL;
if (thobj->status & __THREAD_S_PERIODIC) {
thobj->status &= ~__THREAD_S_PERIODIC;
__RT(timer_delete(timer));
}
return 0;
}
if (timer == NULL) {
if (!(thobj->status & __THREAD_S_PERIODIC)) {
memset(&sev, 0, sizeof(sev));
sev.sigev_signo = SIGPERIOD;
sev.sigev_notify = SIGEV_SIGNAL|SIGEV_THREAD_ID;
......@@ -1648,6 +1648,7 @@ int threadobj_set_periodic(struct threadobj *thobj,
if (ret)
return __bt(-errno);
thobj->periodic_timer = timer;
thobj->status |= __THREAD_S_PERIODIC;
}
its.it_value = *idate;
......@@ -1666,7 +1667,7 @@ int threadobj_wait_period(unsigned long *overruns_r)
siginfo_t si;
int sig;
if (current->periodic_timer == NULL)
if (!(current->status & __THREAD_S_PERIODIC))
return -EWOULDBLOCK;
for (;;) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment