From 7a3104dc65b469cbb9c88b6a9c7b7bea4126a43e Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 5 Jul 2001 17:04:39 +0000 Subject: Fixups to last commit. --- GNUmakefile | 4 +-- barrier.c | 27 ++++++++++---------- implement.h | 5 ++-- pthread.h | 5 ++-- rwlock.c | 11 +++----- spin.c | 82 ++++++++++++++++++++++++++++++++++++++--------------------- tests/spin1.c | 8 ++---- 7 files changed, 80 insertions(+), 62 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 141a778..60bee78 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -44,9 +44,9 @@ CFLAGS = $(OPT) -I. -D_WIN32_WINNT=0x400 -DHAVE_CONFIG_H -DPTW32_BUILD -Wall ## Cygwin G++ #CFLAGS = $(OPT) -x $(GLANG) -fhandle-exceptions -D_WIN32_WINNT=0x400 -I. -DHAVE_CONFIG_H -DPTW32_BUILD -Wall -OBJS = attr.o cancel.o cleanup.o condvar.o create.o dll.o errno.o \ +OBJS = attr.o barrier.o cancel.o cleanup.o condvar.o create.o dll.o errno.o \ exit.o fork.o global.o misc.o mutex.o nonportable.o \ - private.o rwlock.o sched.o semaphore.o signal.o sync.o tsd.o + private.o rwlock.o sched.o semaphore.o signal.o spin.o sync.o tsd.o INCL = implement.h semaphore.h pthread.h windows.h diff --git a/barrier.c b/barrier.c index 5e22109..7d148ed 100644 --- a/barrier.c +++ b/barrier.c @@ -34,14 +34,14 @@ pthread_barrier_init(pthread_barrier_t * barrier, { int result = 0; int pshared = PTHREAD_PROCESS_PRIVATE; - pthread_barrier_t * b; + pthread_barrier_t b; if (barrier == NULL) { return EINVAL; } - b = (pthread_barrier_t *) calloc(1, sizeof(*b)); + b = (pthread_barrier_t) calloc(1, sizeof(*b)); if (b == NULL) { @@ -56,7 +56,7 @@ pthread_barrier_init(pthread_barrier_t * barrier, b->nCurrentBarrierHeight = b->nInitialBarrierHeight = count; - result = pthread_mutex_init(&b->mtxExclusiveAccess, NULL); + result = pthread_mutex_init(&(b->mtxExclusiveAccess), NULL); if (0 != result) { goto FAIL0; @@ -71,12 +71,13 @@ pthread_barrier_init(pthread_barrier_t * barrier, goto DONE; FAIL1: - (void) pthread_mutex_destroy(&b->mtxExclusiveAccess); + (void) pthread_mutex_destroy(&(b->mtxExclusiveAccess)); FAIL0: (void) free(b); DONE: + *barrier = b; return(result); } @@ -93,7 +94,7 @@ pthread_barrier_destroy(pthread_barrier_t *barrier) b = *barrier; - if (0 == pthread_mutex_trylock(&b->mtxExclusiveAccess)) + if (0 == pthread_mutex_trylock(&(b->mtxExclusiveAccess))) { /* * FIXME!!! @@ -127,16 +128,16 @@ pthread_barrier_wait(pthread_barrier_t *barrier) b = *barrier; - result = pthread_mutex_lock(b->mtxExclusiveAccess); + result = pthread_mutex_lock(&(b->mtxExclusiveAccess)); if (0 == result) { if (0 == --(b->nCurrentBarrierHeight)) { b->nCurrentBarrierHeight = b->nInitialBarrierHeight; - (void) pthread_mutex_unlock(b->mtxExclusiveAccess); + (void) pthread_mutex_unlock(&(b->mtxExclusiveAccess)); (void) sem_post_multiple(&(b->semBarrierBreeched), - b->InitialBarrierHeight); + b->nInitialBarrierHeight); /* * Would be better if the first thread to return * from this routine got this value. On a single @@ -152,13 +153,11 @@ pthread_barrier_wait(pthread_barrier_t *barrier) * so temporarily prevent sem_wait() from being one. */ pthread_t self = pthread_self(); - int cancelType = pthread_getcanceltype(self); int oldCancelState; - if (cancelType == PTHREAD_CANCEL_DEFERRED) + if (self->cancelType == PTHREAD_CANCEL_DEFERRED) { - oldCancelState = pthread_setcancelstate(self, - PTHREAD_CANCEL_DISABLED); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldCancelState); } /* Could still be PTHREAD_CANCEL_ASYNCHRONOUS. */ @@ -170,9 +169,9 @@ pthread_barrier_wait(pthread_barrier_t *barrier) result = errno; } - if (cancelType == PTHREAD_CANCEL_DEFERRED) + if (self->cancelType == PTHREAD_CANCEL_DEFERRED) { - pthread_setcancelstate(self, oldCancelState); + pthread_setcancelstate(oldCancelState, NULL); } pthread_cleanup_pop(1); diff --git a/implement.h b/implement.h index 34055dd..8d19406 100644 --- a/implement.h +++ b/implement.h @@ -136,8 +136,9 @@ struct sem_t_ { #define PTW32_OBJECT_AUTO_INIT ((void *) -1) #define PTW32_OBJECT_INVALID NULL -#define PTW32_SPIN_UNLOCKED ((void *) 1) -#define PTW32_SPIN_LOCKED ((void *) 2) +#define PTW32_SPIN_UNLOCKED (1) +#define PTW32_SPIN_LOCKED (2) +#define PTW32_SPIN_INTERLOCK_MASK (~3L) struct pthread_mutex_t_ { LONG lock_idx; diff --git a/pthread.h b/pthread.h index f6d02fe..16e514d 100644 --- a/pthread.h +++ b/pthread.h @@ -361,8 +361,9 @@ typedef struct pthread_condattr_t_ *pthread_condattr_t; #endif typedef struct pthread_rwlock_t_ *pthread_rwlock_t; typedef struct pthread_rwlockattr_t_ *pthread_rwlockattr_t; -typedef struct pthread_spinlock_t_ pthread_spinlock_t; +typedef struct pthread_spinlock_t_ *pthread_spinlock_t; typedef struct pthread_barrier_t_ *pthread_barrier_t; +typedef struct pthread_barrierattr_t_ *pthread_barrierattr_t; /* * ==================== @@ -810,7 +811,7 @@ int pthread_mutex_unlock (pthread_mutex_t * mutex); /* * Spinlock Functions */ -int pthread_spin_init (pthread_spinlock_t * lock); +int pthread_spin_init (pthread_spinlock_t * lock, int pshared); int pthread_spin_destroy (pthread_spinlock_t * lock); diff --git a/rwlock.c b/rwlock.c index c2d85d8..819507b 100644 --- a/rwlock.c +++ b/rwlock.c @@ -383,16 +383,13 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock) * so temporarily prevent pthread_cond_wait() from being one. */ pthread_t self = pthread_self(); - int cancelType = pthread_getcanceltype(self); int oldCancelState; rwl->nCompletedSharedAccessCount = -rwl->nSharedAccessCount; - if (cancelType == PTHREAD_CANCEL_DEFERRED) + if (self->cancelType == PTHREAD_CANCEL_DEFERRED) { - oldCancelState = - pthread_setcancelstate(self, - PTHREAD_CANCEL_DISABLED); + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldCancelState); } /* Could still be PTHREAD_CANCEL_ASYNCHRONOUS. */ @@ -405,9 +402,9 @@ pthread_rwlock_wrlock(pthread_rwlock_t * rwlock) } while (result == 0 && rwl->nCompletedSharedAccessCount < 0); - if (cancelType == PTHREAD_CANCEL_DEFERRED) + if (self->cancelType == PTHREAD_CANCEL_DEFERRED) { - pthread_setcancelstate(self, oldCancelState); + pthread_setcancelstate(oldCancelState, NULL); } pthread_cleanup_pop ((result != 0) ? 1 : 0); diff --git a/spin.c b/spin.c index 5f30cfc..90e8e0a 100644 --- a/spin.c +++ b/spin.c @@ -34,20 +34,28 @@ * using a non-simple struct for spinlocks. */ #define PTW32_SPIN_SPINS(_lock) \ - (0 == (_lock->u.mx & (pthread_mutex_t) ~(PTW32_OBJECT_INVALID | PTW32_SPIN_UNLOCK | PTW32_SPIN_LOCKED))) + (0 == ((long) ((_lock->u).mx) & ~(PTW32_SPIN_LOCKED | PTW32_SPIN_UNLOCKED | (long) PTW32_OBJECT_INVALID))) int pthread_spin_init(pthread_spinlock_t *lock, int pshared) { + pthread_spinlock_t s; int CPUs = 1; int result = 0; - if (lock == NULL) + if (lock == NULL || *lock == NULL) { return EINVAL; } + s = (pthread_spinlock_t) calloc(1, sizeof(*s)); + + if (s == NULL) + { + return ENOMEM; + } + (void) pthread_getprocessors_np(&CPUs); if (CPUs > 1) @@ -76,7 +84,7 @@ pthread_spin_init(pthread_spinlock_t *lock, int pshared) } - lock->u.interlock = PTW32_SPIN_UNLOCKED; + s->u.interlock = PTW32_SPIN_UNLOCKED; } else { @@ -86,29 +94,33 @@ pthread_spin_init(pthread_spinlock_t *lock, int pshared) if (0 == result) { ma->pshared = pshared; - result = pthread_mutex_init(&(lock->u.mx), &ma); + result = pthread_mutex_init(&(s->u.mx), &ma); } } FAIL0: - + *lock = (0 == result ? s : NULL); return(result); } int pthread_spin_destroy(pthread_spinlock_t *lock) { - if (lock == NULL) + pthread_spinlock_t s; + + if (lock == NULL || *lock == NULL) { return EINVAL; } - if (PTW32_SPIN_SPINS(lock)) + s = *lock; + + if (PTW32_SPIN_SPINS(s)) { if ( PTW32_SPIN_UNLOCKED != - InterlockedCompareExchange((LPLONG) &(lock->u.interlock), - (LPLONG) PTW32_OBJECT_INVALID, - (LPLONG) PTW32_SPIN_UNLOCKED)) + InterlockedCompareExchange((LPLONG) &(s->u.interlock), + (LONG) PTW32_OBJECT_INVALID, + (LONG) PTW32_SPIN_UNLOCKED)) { return EINVAL; } @@ -119,7 +131,7 @@ pthread_spin_destroy(pthread_spinlock_t *lock) } else { - return pthread_mutex_destroy(&(lock->u.mx)); + return pthread_mutex_destroy(&(s->u.mx)); } } @@ -127,24 +139,28 @@ pthread_spin_destroy(pthread_spinlock_t *lock) int pthread_spin_lock(pthread_spinlock_t *lock) { - if (lock == NULL) + pthread_spinlock_t s; + + if (lock == NULL || *lock == NULL) { return EINVAL; } - if (PTW32_SPIN_SPINS(lock)) + s = *lock; + + if (PTW32_SPIN_SPINS(s)) { while ( PTW32_SPIN_UNLOCKED != - InterlockedCompareExchange((LPLONG) &(lock->u.interlock), - (LPLONG) PTW32_SPIN_LOCKED, - (LPLONG) PTW32_SPIN_UNLOCKED) ) + InterlockedCompareExchange((LPLONG) &(s->u.interlock), + (LONG) PTW32_SPIN_LOCKED, + (LONG) PTW32_SPIN_UNLOCKED) ) { /* Spin */ } } else { - return pthread_mutex_lock(&(lock->u.mx)); + return pthread_mutex_lock(&(s->u.mx)); } return 0; @@ -153,17 +169,21 @@ pthread_spin_lock(pthread_spinlock_t *lock) int pthread_spin_unlock(pthread_spinlock_t *lock) { - if (lock == NULL) + pthread_spinlock_t s; + + if (lock == NULL || lock == NULL) { return EINVAL; } - if (PTW32_SPIN_SPINS(lock)) + s = *lock; + + if (PTW32_SPIN_SPINS(s)) { if (PTW32_SPIN_LOCKED != - InterlockedCompareExchange((LPLONG) &(lock->u.interlock), - (LPLONG) PTW32_SPIN_UNLOCKED, - (LPLONG) PTW32_SPIN_LOCKED ) ) + InterlockedCompareExchange((LPLONG) &(s->u.interlock), + (LONG) PTW32_SPIN_UNLOCKED, + (LONG) PTW32_SPIN_LOCKED ) ) { return 0; } @@ -174,24 +194,28 @@ pthread_spin_unlock(pthread_spinlock_t *lock) } else { - return pthread_mutex_unlock(&(lock->u.mx)); + return pthread_mutex_unlock(&(s->u.mx)); } } int pthread_spin_trylock(pthread_spinlock_t *lock) { - if (lock == NULL) + pthread_spinlock_t s; + + if (lock == NULL || *lock == NULL) { return EINVAL; } - if (PTW32_SPIN_SPINS(lock)) + s = *lock; + + if (PTW32_SPIN_SPINS(s)) { if (PTW32_SPIN_UNLOCKED != - InterlockedCompareExchange((LPLONG) &(lock->u.interlock), - (LPLONG) PTW32_SPIN_LOCKED, - (LPLONG) PTW32_SPIN_UNLOCKED ) ) + InterlockedCompareExchange((LPLONG) &(s->u.interlock), + (LONG) PTW32_SPIN_LOCKED, + (LONG) PTW32_SPIN_UNLOCKED ) ) { return EBUSY; } @@ -202,6 +226,6 @@ pthread_spin_trylock(pthread_spinlock_t *lock) } else { - return pthread_mutex_trylock(&(lock->u.mx)); + return pthread_mutex_trylock(&(s->u.mx)); } } diff --git a/tests/spin1.c b/tests/spin1.c index e9e5731..347cf18 100644 --- a/tests/spin1.c +++ b/tests/spin1.c @@ -8,24 +8,20 @@ #include "test.h" -pthread_spinlock_t lock = NULL; +pthread_spinlock_t lock; int main() { - assert(lock == NULL); - assert(pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE) == 0); - assert(lock != NULL); - assert(pthread_spin_lock(&lock) == 0); assert(pthread_spin_unlock(&lock) == 0); assert(pthread_spin_destroy(&lock) == 0); - assert(lock == NULL); + assert(pthread_spin_lock(&lock) == EINVAL); return 0; } -- cgit v1.2.3