diff options
-rwxr-xr-x | arch/i386/bits/alltypes.h.sh | 2 | ||||
-rwxr-xr-x | arch/x86_64/bits/alltypes.h.sh | 2 | ||||
-rw-r--r-- | src/time/timer_create.c | 24 | ||||
-rw-r--r-- | src/time/timer_delete.c | 13 | ||||
-rw-r--r-- | src/time/timer_getoverrun.c | 4 | ||||
-rw-r--r-- | src/time/timer_gettime.c | 4 | ||||
-rw-r--r-- | src/time/timer_settime.c | 4 |
7 files changed, 22 insertions, 31 deletions
diff --git a/arch/i386/bits/alltypes.h.sh b/arch/i386/bits/alltypes.h.sh index 13658cc2..c6201b9d 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 cd84a2da..b0aecd9c 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 89099dd6..c5894f48 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 caf04895..437de2e0 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 1334e451..fa7715bb 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 3d3156a0..2320873e 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 d109570b..00708f0e 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); } |