aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-06-26 01:47:56 +0000
committerUlrich Drepper <drepper@redhat.com>2000-06-26 01:47:56 +0000
commitd82e4c7bb231c9e0f835bd46467563ac3b56cebe (patch)
treea408089f079a086df0ed1602c67612d12fc7ac2a /linuxthreads
parent7475d01602e881e206a29ee30bc8c3e85c235379 (diff)
downloadglibc-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/ChangeLog29
-rw-r--r--linuxthreads/Examples/ex10.c105
-rw-r--r--linuxthreads/Makefile5
-rw-r--r--linuxthreads/Versions4
-rw-r--r--linuxthreads/condvar.c8
-rw-r--r--linuxthreads/mutex.c65
-rw-r--r--linuxthreads/rwlock.c121
-rw-r--r--linuxthreads/spinlock.c258
-rw-r--r--linuxthreads/spinlock.h32
-rw-r--r--linuxthreads/sysdeps/pthread/pthread.h32
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