diff --git a/arch/i386/bits/alltypes.h.sh b/arch/i386/bits/alltypes.h.sh index 13658cc2716ae001ec204f204a0b9a2f5e490e22..c6201b9dc2e9fae35c13fa00516ac815c0be0867 100755 --- a/arch/i386/bits/alltypes.h.sh +++ b/arch/i386/bits/alltypes.h.sh @@ -107,7 +107,7 @@ TYPEDEF long long blkcnt_t; TYPEDEF unsigned long long fsblkcnt_t; TYPEDEF unsigned long long fsfilcnt_t; -TYPEDEF struct __timer * timer_t; +TYPEDEF void * timer_t; TYPEDEF int clockid_t; TYPEDEF unsigned long clock_t; diff --git a/arch/x86_64/bits/alltypes.h.sh b/arch/x86_64/bits/alltypes.h.sh index cd84a2dad79dae90876dcf88fa32fac322fdcac9..b0aecd9c94c875c5eef4ae8a3395f2fc3624ee5a 100755 --- a/arch/x86_64/bits/alltypes.h.sh +++ b/arch/x86_64/bits/alltypes.h.sh @@ -107,7 +107,7 @@ TYPEDEF long long blkcnt_t; TYPEDEF unsigned long long fsblkcnt_t; TYPEDEF unsigned long long fsfilcnt_t; -TYPEDEF struct __timer * timer_t; +TYPEDEF void * timer_t; TYPEDEF int clockid_t; TYPEDEF long clock_t; diff --git a/src/time/timer_create.c b/src/time/timer_create.c index 89099dd6b8961ed816d1fd0bc998006431374fb6..c5894f48060f195e5d16e99a4636f1cd28565ab0 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -11,7 +11,6 @@ struct ksigevent { struct start_args { pthread_barrier_t b; struct sigevent *sev; - timer_t t; }; static void sighandler(int sig, siginfo_t *si, void *ctx) @@ -26,30 +25,21 @@ static void sighandler(int sig, siginfo_t *si, void *ctx) pthread_setcancelstate(st, 0); } -static void killtimer(void *arg) -{ - timer_t t = arg; - if (t->timerid >= 0) __syscall(SYS_timer_delete, t->timerid); -} - static void *start(void *arg) { pthread_t self = __pthread_self(); struct start_args *args = arg; - struct __timer t = { .timerid = -1 }; /* Reuse no-longer-needed thread structure fields to avoid * needing the timer address in the signal handler. */ self->start = (void *(*)(void *))args->sev->sigev_notify_function; self->start_arg = args->sev->sigev_value.sival_ptr; - args->t = &t; + self->result = (void *)-1; - pthread_cleanup_push(killtimer, &t); pthread_barrier_wait(&args->b); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); /* Loop on async-signal-safe cancellation point */ for (;;) sleep(1); - pthread_cleanup_pop(1); return 0; } @@ -79,11 +69,7 @@ int timer_create(clockid_t clk, struct sigevent *evp, timer_t *res) ksev.sigev_tid = 0; if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0) return -1; - if (!(t = calloc(1, sizeof *t))) { - syscall(SYS_timer_delete, timerid); - return -1; - } - t->timerid = timerid; + *res = (void *)(2*timerid+1); break; case SIGEV_THREAD: if (!libc.sigtimer) libc.sigtimer = sighandler; @@ -105,19 +91,17 @@ int timer_create(clockid_t clk, struct sigevent *evp, timer_t *res) ksev.sigev_tid = td->tid; r = syscall(SYS_timer_create, clk, &ksev, &timerid); pthread_barrier_wait(&args.b); - t = args.t; if (r < 0) { pthread_cancel(td); return -1; } - t->timerid = timerid; - t->thread = td; + td->result = (void *)timerid; + *res = td; break; default: errno = EINVAL; return -1; } - *res = t; return 0; } diff --git a/src/time/timer_delete.c b/src/time/timer_delete.c index caf048954c040c36e7d98806400b687f56da0710..437de2e06a32926cdb71ef3709f420f23eb83146 100644 --- a/src/time/timer_delete.c +++ b/src/time/timer_delete.c @@ -3,10 +3,11 @@ int timer_delete(timer_t t) { - if (t->thread) pthread_cancel(t->thread); - else { - __syscall(SYS_timer_delete, t->timerid); - free(t); - } - return 0; + pthread_t td = 0; + int r; + if ((uintptr_t)t & 1) t = (void *)((unsigned long)t / 2); + else td = t, t = td->result; + r = __syscall(SYS_timer_delete, (long)t); + if (td) pthread_cancel(td); + return r; } diff --git a/src/time/timer_getoverrun.c b/src/time/timer_getoverrun.c index 1334e451cb1a259f22249adf0da147dea63dc1c9..fa7715bbe73f47e03a3a28d5a66210f771eb6e74 100644 --- a/src/time/timer_getoverrun.c +++ b/src/time/timer_getoverrun.c @@ -3,5 +3,7 @@ int timer_getoverrun(timer_t t) { - return syscall(SYS_timer_getoverrun, t->timerid); + if ((uintptr_t)t & 1) t = (void *)((unsigned long)t / 2); + else t = ((pthread_t)t)->result; + return syscall(SYS_timer_getoverrun, (long)t); } diff --git a/src/time/timer_gettime.c b/src/time/timer_gettime.c index 3d3156a060290cf3b743eda1cb9526e9fe7dba72..2320873eecf22c06f8cc30735e7b2df82e74239a 100644 --- a/src/time/timer_gettime.c +++ b/src/time/timer_gettime.c @@ -3,5 +3,7 @@ int timer_gettime(timer_t t, struct itimerspec *val) { - return syscall(SYS_timer_gettime, t->timerid, val); + if ((uintptr_t)t & 1) t = (void *)((unsigned long)t / 2); + else t = ((pthread_t)t)->result; + return syscall(SYS_timer_gettime, (long)t, val); } diff --git a/src/time/timer_settime.c b/src/time/timer_settime.c index d109570b3fe660cf193b8b6ae4e180714f391164..00708f0e47a6d90a1c50094beeb0c1f965b407ad 100644 --- a/src/time/timer_settime.c +++ b/src/time/timer_settime.c @@ -3,5 +3,7 @@ int timer_settime(timer_t t, int flags, const struct itimerspec *val, struct itimerspec *old) { - return syscall(SYS_timer_settime, t->timerid, flags, val, old); + if ((uintptr_t)t & 1) t = (void *)((unsigned long)t / 2); + else t = ((pthread_t)t)->result; + return syscall(SYS_timer_settime, (long)t, flags, val, old); }