diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/internal/pthread_impl.h | 2 | ||||
| -rw-r--r-- | src/time/timer_create.c | 29 | ||||
| -rw-r--r-- | src/time/timer_delete.c | 9 | ||||
| -rw-r--r-- | src/time/timer_getoverrun.c | 6 | ||||
| -rw-r--r-- | src/time/timer_gettime.c | 6 | ||||
| -rw-r--r-- | src/time/timer_settime.c | 6 | 
6 files changed, 36 insertions, 22 deletions
| diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 67b05753..2e910b3e 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -38,7 +38,7 @@ struct pthread {  		void *pending;  	} robust_list;  	int unblock_cancel; -	int delete_timer; +	int timer_id;  	locale_t locale;  	int killlock[2];  	int exitlock[2]; diff --git a/src/time/timer_create.c b/src/time/timer_create.c index f76b9ef8..2b4619d4 100644 --- a/src/time/timer_create.c +++ b/src/time/timer_create.c @@ -60,20 +60,18 @@ static void *start(void *arg)  {  	pthread_t self = __pthread_self();  	struct start_args *args = arg; -	sigset_t set; +	int id;  	/* 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; -	self->result = (void *)-1; - -	sigfillset(&set); -	pthread_sigmask(SIG_BLOCK, &set, 0);  	pthread_barrier_wait(&args->b); -	__wait(&self->delete_timer, 0, 0, 1); -	__syscall(SYS_timer_delete, self->result); +	if ((id = self->timer_id) >= 0) { +		__wait(&self->timer_id, 0, id, 1); +		__syscall(SYS_timer_delete, id); +	}  	return 0;  } @@ -86,6 +84,7 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict  	struct start_args args;  	struct ksigevent ksev, *ksevp=0;  	int timerid; +	sigset_t set;  	switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {  	case SIGEV_NONE: @@ -110,23 +109,25 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict  		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  		pthread_barrier_init(&args.b, 0, 2);  		args.sev = evp; + +		__block_app_sigs(&set);  		r = pthread_create(&td, &attr, start, &args); +		__restore_sigs(&set);  		if (r) {  			errno = r;  			return -1;  		} +  		ksev.sigev_value.sival_ptr = 0;  		ksev.sigev_signo = SIGTIMER;  		ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */  		ksev.sigev_tid = td->tid; -		r = syscall(SYS_timer_create, clk, &ksev, &timerid); +		if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0) +			timerid = -1; +		td->timer_id = timerid;  		pthread_barrier_wait(&args.b); -		if (r < 0) { -			pthread_cancel(td); -			return -1; -		} -		td->result = (void *)(intptr_t)timerid; -		*res = td; +		if (timerid < 0) return -1; +		*res = (void *)(INTPTR_MIN | (uintptr_t)td>>1);  		break;  	default:  		errno = EINVAL; diff --git a/src/time/timer_delete.c b/src/time/timer_delete.c index b5f8ca19..c81f921a 100644 --- a/src/time/timer_delete.c +++ b/src/time/timer_delete.c @@ -1,12 +1,13 @@  #include <time.h> +#include <limits.h>  #include "pthread_impl.h"  int timer_delete(timer_t t)  { -	if ((uintptr_t)t >= 0x100000) { -		pthread_t td = t; -		td->delete_timer = 1; -		__wake(&td->delete_timer, 1, 1); +	if ((intptr_t)t < 0) { +		pthread_t td = (void *)((uintptr_t)t << 1); +		a_store(&td->timer_id, td->timer_id | INT_MIN); +		__wake(&td->timer_id, 1, 1);  		return 0;  	}  	return __syscall(SYS_timer_delete, (long)t); diff --git a/src/time/timer_getoverrun.c b/src/time/timer_getoverrun.c index 8a86833d..53361285 100644 --- a/src/time/timer_getoverrun.c +++ b/src/time/timer_getoverrun.c @@ -1,8 +1,12 @@  #include <time.h> +#include <limits.h>  #include "pthread_impl.h"  int timer_getoverrun(timer_t t)  { -	if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; +	if ((intptr_t)t < 0) { +		pthread_t td = (void *)((uintptr_t)t << 1); +		t = (void *)(uintptr_t)(td->timer_id & INT_MAX); +	}  	return syscall(SYS_timer_getoverrun, (long)t);  } diff --git a/src/time/timer_gettime.c b/src/time/timer_gettime.c index 5a858218..1d902075 100644 --- a/src/time/timer_gettime.c +++ b/src/time/timer_gettime.c @@ -1,8 +1,12 @@  #include <time.h> +#include <limits.h>  #include "pthread_impl.h"  int timer_gettime(timer_t t, struct itimerspec *val)  { -	if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; +	if ((intptr_t)t < 0) { +		pthread_t td = (void *)((uintptr_t)t << 1); +		t = (void *)(uintptr_t)(td->timer_id & INT_MAX); +	}  	return syscall(SYS_timer_gettime, (long)t, val);  } diff --git a/src/time/timer_settime.c b/src/time/timer_settime.c index baf5076b..f5f36feb 100644 --- a/src/time/timer_settime.c +++ b/src/time/timer_settime.c @@ -1,8 +1,12 @@  #include <time.h> +#include <limits.h>  #include "pthread_impl.h"  int timer_settime(timer_t t, int flags, const struct itimerspec *restrict val, struct itimerspec *restrict old)  { -	if ((uintptr_t)t >= 0x100000) t = ((pthread_t)t)->result; +	if ((intptr_t)t < 0) { +		pthread_t td = (void *)((uintptr_t)t << 1); +		t = (void *)(uintptr_t)(td->timer_id & INT_MAX); +	}  	return syscall(SYS_timer_settime, (long)t, flags, val, old);  } | 
