diff options
| -rw-r--r-- | GNUmakefile | 4 | ||||
| -rw-r--r-- | barrier.c | 27 | ||||
| -rw-r--r-- | implement.h | 5 | ||||
| -rw-r--r-- | pthread.h | 5 | ||||
| -rw-r--r-- | rwlock.c | 11 | ||||
| -rw-r--r-- | spin.c | 82 | ||||
| -rw-r--r-- | 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 @@ -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; @@ -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); @@ -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); @@ -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;  } | 
