summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile4
-rw-r--r--barrier.c27
-rw-r--r--implement.h5
-rw-r--r--pthread.h5
-rw-r--r--rwlock.c11
-rw-r--r--spin.c82
-rw-r--r--tests/spin1.c8
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;
}