diff options
| author | Ulrich Drepper <drepper@redhat.com> | 2000-06-26 01:47:56 +0000 |
|---|---|---|
| committer | Ulrich Drepper <drepper@redhat.com> | 2000-06-26 01:47:56 +0000 |
| commit | d82e4c7bb231c9e0f835bd46467563ac3b56cebe (patch) | |
| tree | a408089f079a086df0ed1602c67612d12fc7ac2a /linuxthreads | |
| parent | 7475d01602e881e206a29ee30bc8c3e85c235379 (diff) | |
| download | glibc-d82e4c7bb231c9e0f835bd46467563ac3b56cebe.tar.xz glibc-d82e4c7bb231c9e0f835bd46467563ac3b56cebe.zip | |
Update.
2000-06-25 Ulrich Drepper <drepper@redhat.com>
* Makefile (tests): Add ex10. Add rules to build it.
* Versions [GLIBC_2.2] (libpthread): Add pthread_mutex_timedlock,
pthread_rwlock_timedrdlock, and pthread_rwlock_timedwrlock.
* condvar.c (pthread_cond_wait): Allow mutex of kind
PTHREAD_MUTEX_TIMED_NP.
(pthread_cond_timedwait_relative): Likewise.
* mutex.c (__pthread_mutex_init): Default is PTHREAD_MUTEX_TIMED_NP.
(__pthread_mutex_trylock): Use __pthread_alt_trylock for
PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP.
(__pthread_mutex_lock): Use __pthread_alt_lock for
PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP.
(__pthread_mutex_timedlock): New function.
(__pthread_mutex_unlock): Use __pthread_alt_unlock for
PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP.
(__pthread_mutexattr_init): Use PTHREAD_MUTEX_TIMED_NP.
(__pthread_mutexattr_settype): Allow PTHREAD_MUTEX_TIMED_NP.
* spinlock.c: Implement alternate fastlocks.
* spinlock.h: Add prototypes.
* Examples/ex10.c: New file.
* sysdeps/pthread/pthread.h: Add prototypes for new functions.
Patch by Kaz Kylheku <kaz@ashi.footprints.net>.
* rwlock.c (__pthread_rwlock_rdlock): Optimize loop a bit.
(__pthread_rwlock_timedrdlock): New function.
(__pthread_rwlock_timedwrlock): New function.
Use laternate fastlock function everywhere.
Diffstat (limited to 'linuxthreads')
| -rw-r--r-- | linuxthreads/ChangeLog | 29 | ||||
| -rw-r--r-- | linuxthreads/Examples/ex10.c | 105 | ||||
| -rw-r--r-- | linuxthreads/Makefile | 5 | ||||
| -rw-r--r-- | linuxthreads/Versions | 4 | ||||
| -rw-r--r-- | linuxthreads/condvar.c | 8 | ||||
| -rw-r--r-- | linuxthreads/mutex.c | 65 | ||||
| -rw-r--r-- | linuxthreads/rwlock.c | 121 | ||||
| -rw-r--r-- | linuxthreads/spinlock.c | 258 | ||||
| -rw-r--r-- | linuxthreads/spinlock.h | 32 | ||||
| -rw-r--r-- | linuxthreads/sysdeps/pthread/pthread.h | 32 |
10 files changed, 622 insertions, 37 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index ceb350f613..7cb6477c62 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,32 @@ +2000-06-25 Ulrich Drepper <drepper@redhat.com> + + * Makefile (tests): Add ex10. Add rules to build it. + * Versions [GLIBC_2.2] (libpthread): Add pthread_mutex_timedlock, + pthread_rwlock_timedrdlock, and pthread_rwlock_timedwrlock. + * condvar.c (pthread_cond_wait): Allow mutex of kind + PTHREAD_MUTEX_TIMED_NP. + (pthread_cond_timedwait_relative): Likewise. + * mutex.c (__pthread_mutex_init): Default is PTHREAD_MUTEX_TIMED_NP. + (__pthread_mutex_trylock): Use __pthread_alt_trylock for + PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP. + (__pthread_mutex_lock): Use __pthread_alt_lock for + PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP. + (__pthread_mutex_timedlock): New function. + (__pthread_mutex_unlock): Use __pthread_alt_unlock for + PTHREAD_MUTEX_ERRORCHECK_NP. Handle PTHREAD_MUTEX_TIMED_NP. + (__pthread_mutexattr_init): Use PTHREAD_MUTEX_TIMED_NP. + (__pthread_mutexattr_settype): Allow PTHREAD_MUTEX_TIMED_NP. + * spinlock.c: Implement alternate fastlocks. + * spinlock.h: Add prototypes. + * Examples/ex10.c: New file. + * sysdeps/pthread/pthread.h: Add prototypes for new functions. + Patch by Kaz Kylheku <kaz@ashi.footprints.net>. + + * rwlock.c (__pthread_rwlock_rdlock): Optimize loop a bit. + (__pthread_rwlock_timedrdlock): New function. + (__pthread_rwlock_timedwrlock): New function. + Use laternate fastlock function everywhere. + 2000-06-21 Andreas Jaeger <aj@suse.de> * sysdeps/pthread/timer_routines.c: Include <string.h> for memset diff --git a/linuxthreads/Examples/ex10.c b/linuxthreads/Examples/ex10.c new file mode 100644 index 0000000000..d89f4f469d --- /dev/null +++ b/linuxthreads/Examples/ex10.c @@ -0,0 +1,105 @@ +/* Tests for pthread_mutex_timedlock function. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Kaz Kylheku <kaz@ashi.footprints.net>, 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <errno.h> +#include <error.h> +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <time.h> + +#define NUM_THREADS 10 +#define NUM_ITERS 50 +#define TIMEOUT_NS 100000000L + +static void *thread (void *); +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +int +main (void) +{ + pthread_t th; + int i; + + for (i = 0; i < NUM_THREADS; i++) + { + if (pthread_create (&th, NULL, thread, NULL) != 0) + error (EXIT_FAILURE, 0, "cannot create thread"); + } + + (void) thread (NULL); + /* notreached */ + return 0; +} + + +static void * +thread (void *arg) +{ + int i; + pthread_t self = pthread_self (); + static int linecount; /* protected by flockfile(stdout) */ + + for (i = 0; i < NUM_ITERS; i++) + { + struct timespec ts; + + for (;;) + { + + clock_gettime (CLOCK_REALTIME, &ts); + + ts.tv_nsec += TIMEOUT_NS; + + if (ts.tv_nsec > 1000000000L) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } + + switch (pthread_mutex_timedlock (&mutex, &ts)) + { + case 0: + flockfile (stdout); + printf ("%04d: thread %lu got mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + break; + case ETIMEDOUT: + flockfile (stdout); + printf ("%04d: thread %lu timed out on mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + continue; + } + break; + } + + ts.tv_sec = 0; + ts.tv_nsec = TIMEOUT_NS; + nanosleep (&ts, NULL); + + flockfile (stdout); + printf ("%04d: thread %lu releasing mutex\n", ++linecount, + (unsigned long) self); + funlockfile (stdout); + pthread_mutex_unlock (&mutex); + } + + pthread_exit (NULL); +} diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile index 1b4ecc0012..5c36bd22eb 100644 --- a/linuxthreads/Makefile +++ b/linuxthreads/Makefile @@ -38,7 +38,7 @@ libpthread-routines := attr cancel condvar join manager mutex ptfork \ oldsemaphore events getcpuclockid pspinlock barrier vpath %.c Examples -tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 joinrace +tests = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 joinrace include ../Rules @@ -56,8 +56,10 @@ $(objpfx)libpthread.so: $(common-objpfx)libc.so # Make sure we link with the thread library. ifeq ($(build-shared),yes) libpthread = $(objpfx)libpthread.so +librt = $(common-objpfx)rt/librt.so else libpthread = $(objpfx)libpthread.a +librt = $(common-objpfx)rt/librt.a endif $(objpfx)ex1: $(libpthread) @@ -69,4 +71,5 @@ $(objpfx)ex6: $(libpthread) $(objpfx)ex7: $(libpthread) $(objpfx)ex8: $(libpthread) $(objpfx)ex9: $(libpthread) +$(objpfx)ex10: $(libpthread) $(librt) $(objpfx)joinrace: $(libpthread) diff --git a/linuxthreads/Versions b/linuxthreads/Versions index 48f62ae0dd..85a58e112b 100644 --- a/linuxthreads/Versions +++ b/linuxthreads/Versions @@ -136,8 +136,10 @@ libpthread { pthread_spin_trylock; pthread_spin_unlock; pthread_getcpuclockid; pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait; - pthread_barrierattr_destroy; pthread_barrierattr_init; + pthread_barrierattr_destroy; pthread_barrierattr_init; pthread_barrierattr_getpshared; pthread_barrierattr_setpshared; + pthread_mutex_timedlock; + pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock; # Extensions. pthread_yield; diff --git a/linuxthreads/condvar.c b/linuxthreads/condvar.c index 536d88ed05..3bc672e909 100644 --- a/linuxthreads/condvar.c +++ b/linuxthreads/condvar.c @@ -62,7 +62,9 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) int already_canceled = 0; /* Check whether the mutex is locked and owned by this thread. */ - if (mutex->__m_kind != PTHREAD_MUTEX_FAST_NP && mutex->__m_owner != self) + if (mutex->__m_kind != PTHREAD_MUTEX_TIMED_NP + && mutex->__m_kind != PTHREAD_MUTEX_FAST_NP + && mutex->__m_owner != self) return EINVAL; /* Set up extrication interface */ @@ -121,7 +123,9 @@ pthread_cond_timedwait_relative(pthread_cond_t *cond, pthread_extricate_if extr; /* Check whether the mutex is locked and owned by this thread. */ - if (mutex->__m_kind != PTHREAD_MUTEX_FAST_NP && mutex->__m_owner != self) + if (mutex->__m_kind != PTHREAD_MUTEX_TIMED_NP + && mutex->__m_kind != PTHREAD_MUTEX_FAST_NP + && mutex->__m_owner != self) return EINVAL; /* Set up extrication interface */ diff --git a/linuxthreads/mutex.c b/linuxthreads/mutex.c index 6494323006..8b137043b2 100644 --- a/linuxthreads/mutex.c +++ b/linuxthreads/mutex.c @@ -29,7 +29,7 @@ int __pthread_mutex_init(pthread_mutex_t * mutex, { __pthread_init_lock(&mutex->__m_lock); mutex->__m_kind = - mutex_attr == NULL ? PTHREAD_MUTEX_FAST_NP : mutex_attr->__mutexkind; + mutex_attr == NULL ? PTHREAD_MUTEX_TIMED_NP : mutex_attr->__mutexkind; mutex->__m_count = 0; mutex->__m_owner = NULL; return 0; @@ -65,11 +65,14 @@ int __pthread_mutex_trylock(pthread_mutex_t * mutex) } return retcode; case PTHREAD_MUTEX_ERRORCHECK_NP: - retcode = __pthread_trylock(&mutex->__m_lock); + retcode = __pthread_alt_trylock(&mutex->__m_lock); if (retcode == 0) { mutex->__m_owner = thread_self(); } return retcode; + case PTHREAD_MUTEX_TIMED_NP: + retcode = __pthread_alt_trylock(&mutex->__m_lock); + return retcode; default: return EINVAL; } @@ -97,15 +100,61 @@ int __pthread_mutex_lock(pthread_mutex_t * mutex) case PTHREAD_MUTEX_ERRORCHECK_NP: self = thread_self(); if (mutex->__m_owner == self) return EDEADLK; - __pthread_lock(&mutex->__m_lock, self); + __pthread_alt_lock(&mutex->__m_lock, self); mutex->__m_owner = self; return 0; + case PTHREAD_MUTEX_TIMED_NP: + __pthread_alt_lock(&mutex->__m_lock, NULL); + return 0; default: return EINVAL; } } strong_alias (__pthread_mutex_lock, pthread_mutex_lock) +int __pthread_mutex_timedlock (pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + pthread_descr self; + int res; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + switch(mutex->__m_kind) { + case PTHREAD_MUTEX_FAST_NP: + __pthread_lock(&mutex->__m_lock, NULL); + return 0; + case PTHREAD_MUTEX_RECURSIVE_NP: + self = thread_self(); + if (mutex->__m_owner == self) { + mutex->__m_count++; + return 0; + } + __pthread_lock(&mutex->__m_lock, self); + mutex->__m_owner = self; + mutex->__m_count = 0; + return 0; + case PTHREAD_MUTEX_ERRORCHECK_NP: + self = thread_self(); + if (mutex->__m_owner == self) return EDEADLK; + res = __pthread_alt_timedlock(&mutex->__m_lock, self, abstime); + if (res != 0) + { + mutex->__m_owner = self; + return 0; + } + return ETIMEDOUT; + case PTHREAD_MUTEX_TIMED_NP: + /* Only this type supports timed out lock. */ + return (__pthread_alt_timedlock(&mutex->__m_lock, NULL, abstime) + ? 0 : ETIMEDOUT); + default: + return EINVAL; + } +} +strong_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock) + int __pthread_mutex_unlock(pthread_mutex_t * mutex) { switch (mutex->__m_kind) { @@ -124,7 +173,10 @@ int __pthread_mutex_unlock(pthread_mutex_t * mutex) if (mutex->__m_owner != thread_self() || mutex->__m_lock.__status == 0) return EPERM; mutex->__m_owner = NULL; - __pthread_unlock(&mutex->__m_lock); + __pthread_alt_unlock(&mutex->__m_lock); + return 0; + case PTHREAD_MUTEX_TIMED_NP: + __pthread_alt_unlock(&mutex->__m_lock); return 0; default: return EINVAL; @@ -134,7 +186,7 @@ strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock) int __pthread_mutexattr_init(pthread_mutexattr_t *attr) { - attr->__mutexkind = PTHREAD_MUTEX_FAST_NP; + attr->__mutexkind = PTHREAD_MUTEX_TIMED_NP; return 0; } strong_alias (__pthread_mutexattr_init, pthread_mutexattr_init) @@ -149,7 +201,8 @@ int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind) { if (kind != PTHREAD_MUTEX_FAST_NP && kind != PTHREAD_MUTEX_RECURSIVE_NP - && kind != PTHREAD_MUTEX_ERRORCHECK_NP) + && kind != PTHREAD_MUTEX_ERRORCHECK_NP + && kind != PTHREAD_MUTEX_TIMED_NP) return EINVAL; attr->__mutexkind = kind; return 0; diff --git a/linuxthreads/rwlock.c b/linuxthreads/rwlock.c index 9da87d25d1..6ee5b62247 100644 --- a/linuxthreads/rwlock.c +++ b/linuxthreads/rwlock.c @@ -184,7 +184,7 @@ rwlock_have_already(pthread_descr *pself, pthread_rwlock_t *rwlock, int __pthread_rwlock_init (pthread_rwlock_t *rwlock, - const pthread_rwlockattr_t *attr) + const pthread_rwlockattr_t *attr) { __pthread_init_lock(&rwlock->__rw_lock); rwlock->__rw_readers = 0; @@ -214,10 +214,10 @@ __pthread_rwlock_destroy (pthread_rwlock_t *rwlock) int readers; _pthread_descr writer; - __pthread_lock (&rwlock->__rw_lock, NULL); + __pthread_alt_lock (&rwlock->__rw_lock, NULL); readers = rwlock->__rw_readers; writer = rwlock->__rw_writer; - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); if (readers > 0 || writer != NULL) return EBUSY; @@ -236,23 +236,23 @@ __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) have_lock_already = rwlock_have_already(&self, rwlock, &existing, &out_of_mem); + if (self == NULL) + self = thread_self (); + for (;;) { - if (self == NULL) - self = thread_self (); - - __pthread_lock (&rwlock->__rw_lock, self); + __pthread_alt_lock (&rwlock->__rw_lock, self); if (rwlock_can_rdlock(rwlock, have_lock_already)) break; enqueue (&rwlock->__rw_read_waiting, self); - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); suspend (self); /* This is not a cancellation point */ } ++rwlock->__rw_readers; - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); if (have_lock_already || out_of_mem) { @@ -267,6 +267,51 @@ __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) strong_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock) int +__pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock, + const struct timespec *abstime) +{ + pthread_descr self = NULL; + pthread_readlock_info *existing; + int out_of_mem, have_lock_already; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + have_lock_already = rwlock_have_already(&self, rwlock, + &existing, &out_of_mem); + + if (self == NULL) + self = thread_self (); + + for (;;) + { + if (__pthread_alt_timedlock (&rwlock->__rw_lock, self, abstime) == 0) + return ETIMEDOUT; + + if (rwlock_can_rdlock(rwlock, have_lock_already)) + break; + + enqueue (&rwlock->__rw_read_waiting, self); + __pthread_alt_unlock (&rwlock->__rw_lock); + suspend (self); /* This is not a cancellation point */ + } + + ++rwlock->__rw_readers; + __pthread_alt_unlock (&rwlock->__rw_lock); + + if (have_lock_already || out_of_mem) + { + if (existing != NULL) + existing->pr_lock_count++; + else + self->p_untracked_readlock_count++; + } + + return 0; +} +strong_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock) + +int __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) { pthread_descr self = thread_self(); @@ -277,7 +322,7 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) have_lock_already = rwlock_have_already(&self, rwlock, &existing, &out_of_mem); - __pthread_lock (&rwlock->__rw_lock, self); + __pthread_alt_lock (&rwlock->__rw_lock, self); /* 0 is passed to here instead of have_lock_already. This is to meet Single Unix Spec requirements: @@ -291,7 +336,7 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) retval = 0; } - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); if (retval == 0) { @@ -316,17 +361,17 @@ __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) while(1) { - __pthread_lock (&rwlock->__rw_lock, self); + __pthread_alt_lock (&rwlock->__rw_lock, self); if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) { rwlock->__rw_writer = self; - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); return 0; } /* Suspend ourselves, then try again */ enqueue (&rwlock->__rw_write_waiting, self); - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); suspend (self); /* This is not a cancellation point */ } } @@ -334,17 +379,49 @@ strong_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock) int +__pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, + const struct timespec *abstime) +{ + pthread_descr self; + + if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000) + return EINVAL; + + self = thread_self (); + + while(1) + { + if (__pthread_alt_timedlock (&rwlock->__rw_lock, self, abstime) == 0) + return ETIMEDOUT; + + if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) + { + rwlock->__rw_writer = self; + __pthread_alt_unlock (&rwlock->__rw_lock); + return 0; + } + + /* Suspend ourselves, then try again */ + enqueue (&rwlock->__rw_write_waiting, self); + __pthread_alt_unlock (&rwlock->__rw_lock); + suspend (self); /* This is not a cancellation point */ + } +} +strong_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock) + + +int __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) { int result = EBUSY; - __pthread_lock (&rwlock->__rw_lock, NULL); + __pthread_alt_lock (&rwlock->__rw_lock, NULL); if (rwlock->__rw_readers == 0 && rwlock->__rw_writer == NULL) { rwlock->__rw_writer = thread_self (); result = 0; } - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); return result; } @@ -357,13 +434,13 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock) pthread_descr torestart; pthread_descr th; - __pthread_lock (&rwlock->__rw_lock, NULL); + __pthread_alt_lock (&rwlock->__rw_lock, NULL); if (rwlock->__rw_writer != NULL) { /* Unlocking a write lock. */ if (rwlock->__rw_writer != thread_self ()) { - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); return EPERM; } rwlock->__rw_writer = NULL; @@ -375,14 +452,14 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock) /* Restart all waiting readers. */ torestart = rwlock->__rw_read_waiting; rwlock->__rw_read_waiting = NULL; - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); while ((th = dequeue (&torestart)) != NULL) restart (th); } else { /* Restart one waiting writer. */ - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); restart (th); } } @@ -391,7 +468,7 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock) /* Unlocking a read lock. */ if (rwlock->__rw_readers == 0) { - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); return EPERM; } @@ -402,7 +479,7 @@ __pthread_rwlock_unlock (pthread_rwlock_t *rwlock) else th = NULL; - __pthread_unlock (&rwlock->__rw_lock); + __pthread_alt_unlock (&rwlock->__rw_lock); if (th != NULL) restart (th); diff --git a/linuxthreads/spinlock.c b/linuxthreads/spinlock.c index 60d056aada..5cd772602c 100644 --- a/linuxthreads/spinlock.c +++ b/linuxthreads/spinlock.c @@ -17,6 +17,8 @@ #include <errno.h> #include <sched.h> #include <time.h> +#include <stdlib.h> +#include <limits.h> #include "pthread.h" #include "internals.h" #include "spinl |
