summaryrefslogtreecommitdiff
path: root/sysdeps/generic
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2005-05-12 20:55:38 +0000
committerNeal H. Walfield <neal@gnu.org>2005-05-12 20:55:38 +0000
commita2c46ac956613c162b5162d2ef2c725229b08aca (patch)
treee32ddcbb1888e6c92f1408a73a10795ebb4e1c18 /sysdeps/generic
parenta6dffc4afcfb78fbb043971ecffdf5a2cfa60989 (diff)
libpthread/
2005-05-12 Neal H. Walfield <neal@gnu.org> * include/pthread/pthread.h (pthread_exit): Add noreturn attribute. * sysdeps/generic/bits/condition.h (__PTHREAD_COND_INITIALIZER): Don't create a compound literal. * sysdeps/generic/bits/mutex.h (__PTHREAD_MUTEX_INITIALIZER): Don't create a compound literal. (pthread_mutex_init): Don't assign to *__MUTEX directly. Initialize an intermediate local variable and then copy the result. * sysdeps/generic/bits/rwlock.h (__PTHREAD_RWLOCK_INITIALIZER): Don't create a compound literal. (pthread_rwlock_init): Don't assign to *__RWLOCK directly. Initialize an intermediate local variable and then copy the result. * sysdeps/i386/bits/spin-lock.h (__SPIN_LOCK_INITIALIZER): Don't create a compound literal. * pthread/pt-alloc.c (initialize_pthread): Cast PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER to create a compound literal. * tests/test-1.c (main): Use pthread_mutex_init, not PTHREAD_MUTEX_INIT for mutex initialization * sysdeps/generic/pt-barrier-init.c (pthread_barrier_init): Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-init.c (pthread_cond_init): Include <string.h>. Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Cast PTHREAD_MUTEX_INITIALIZER to create a compound literal. * sysdeps/generic/pt-rwlock-init.c: Include <string.h>. (_pthread_rwlock_init): Cast __PTHREAD_RWLOCK_INITIALIZER to create a compound literal. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-timedwait.c (__pthread_cond_timedwait_internal): Check that ABSTIME->TV_NSEC is valid. Don't shadow ERR. Don't return before cleaning up. * sysdeps/generic/pt-mutex-timedlock.c (pthread_mutex_timedlock): Move after __pthread_mutex_timedlock_internal. Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedrdlock.c (pthread_rwlock_timedrdlock): Move after. __pthread_rwlock_timedrdlock_internal. (__pthread_rwlock_timedrdlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedwrlock.c (pthread_rwlock_timedwrlock): Move after __pthread_rwlock_timedwrlock_internal. (__pthread_rwlock_timedwrlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal): Check that TIMEOUT->TV_NSEC is valid before enqueuing the thread. * sysdeps/generic/pt-rwlock-rdlock.c (__pthread_rwlock_timedrdlock_internal): Fix declaration. * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock): Don't return EDEADLK. POSIX does not allow it. * sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Calculate the relative timeout without overflowing. * sysdeps/mach/hurd/i386/pt-setup.c (stack_setup): Cast THREAD.
Diffstat (limited to 'sysdeps/generic')
-rw-r--r--sysdeps/generic/bits/condition.h5
-rw-r--r--sysdeps/generic/bits/mutex.h10
-rw-r--r--sysdeps/generic/bits/rwlock.h8
-rw-r--r--sysdeps/generic/pt-barrier-init.c16
-rw-r--r--sysdeps/generic/pt-cond-init.c17
-rw-r--r--sysdeps/generic/pt-cond-timedwait.c9
-rw-r--r--sysdeps/generic/pt-mutex-init.c4
-rw-r--r--sysdeps/generic/pt-mutex-timedlock.c19
-rw-r--r--sysdeps/generic/pt-mutex-trylock.c5
-rw-r--r--sysdeps/generic/pt-rwlock-init.c18
-rw-r--r--sysdeps/generic/pt-rwlock-rdlock.c4
-rw-r--r--sysdeps/generic/pt-rwlock-timedrdlock.c19
-rw-r--r--sysdeps/generic/pt-rwlock-timedwrlock.c19
-rw-r--r--sysdeps/generic/sem-timedwait.c12
14 files changed, 104 insertions, 61 deletions
diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h
index cb7e935..f3b09be 100644
--- a/sysdeps/generic/bits/condition.h
+++ b/sysdeps/generic/bits/condition.h
@@ -1,5 +1,5 @@
/* Condition type. Generic version.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -34,7 +34,6 @@ struct __pthread_cond
/* Initializer for a condition variable. */
#define __PTHREAD_COND_INITIALIZER \
- ((struct __pthread_cond) \
- { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL })
+ { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL }
#endif /* bits/condition.h */
diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h
index 9958b8d..2e32d78 100644
--- a/sysdeps/generic/bits/mutex.h
+++ b/sysdeps/generic/bits/mutex.h
@@ -1,5 +1,5 @@
/* Mutex type. Generic version.
- Copyright (C) 2000,02 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -52,9 +52,7 @@ struct __pthread_mutex
/* Initializer for a mutex. N.B. this also happens to be compatible
with the cthread mutex initializer. */
# define __PTHREAD_MUTEX_INITIALIZER \
- ((struct __pthread_mutex) \
- { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, \
- NULL, 0, 0 })
+ { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 }
# endif
#endif /* Not __pthread_mutex_defined. */
@@ -74,13 +72,15 @@ _EXTERN_INLINE int
pthread_mutex_init (struct __pthread_mutex *__mutex,
const pthread_mutexattr_t *attr)
{
+ struct __pthread_mutex initialized_mutex = __PTHREAD_MUTEX_INITIALIZER;
+
extern int _pthread_mutex_init (struct __pthread_mutex *,
const pthread_mutexattr_t *);
if (attr)
return _pthread_mutex_init (__mutex, attr);
- *__mutex = __PTHREAD_MUTEX_INITIALIZER;
+ *__mutex = initialized_mutex;
return 0;
}
diff --git a/sysdeps/generic/bits/rwlock.h b/sysdeps/generic/bits/rwlock.h
index d089b0c..5793f65 100644
--- a/sysdeps/generic/bits/rwlock.h
+++ b/sysdeps/generic/bits/rwlock.h
@@ -1,5 +1,5 @@
/* rwlock type. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -40,21 +40,21 @@ struct __pthread_rwlock
/* Initializer for a rwlock. */
#define __PTHREAD_RWLOCK_INITIALIZER \
- ((struct __pthread_rwlock) \
- { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 })
+ { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 }
_EXTERN_INLINE int
pthread_rwlock_init (struct __pthread_rwlock *__rwlock,
const struct __pthread_rwlockattr *__attr)
{
+ struct __pthread_rwlock initialized_rwlock = __PTHREAD_RWLOCK_INITIALIZER;
extern int _pthread_rwlock_init (struct __pthread_rwlock *,
const struct __pthread_rwlockattr *);
if (__attr)
return _pthread_rwlock_init (__rwlock, __attr);
- *__rwlock = __PTHREAD_RWLOCK_INITIALIZER;
+ *__rwlock = initialized_rwlock;
return 0;
}
diff --git a/sysdeps/generic/pt-barrier-init.c b/sysdeps/generic/pt-barrier-init.c
index 57911d5..c42b3bb 100644
--- a/sysdeps/generic/pt-barrier-init.c
+++ b/sysdeps/generic/pt-barrier-init.c
@@ -1,5 +1,5 @@
/* pthread_barrier_init. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -28,8 +28,6 @@ pthread_barrier_init (pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr,
unsigned count)
{
- assert (attr->pshared == PTHREAD_PROCESS_PRIVATE);
-
if (count == 0)
return EINVAL;
@@ -39,5 +37,17 @@ pthread_barrier_init (pthread_barrier_t *barrier,
barrier->pending = count;
barrier->count = count;
+ if (! attr
+ || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0))
+ /* Use the default attributes. */
+ return 0;
+
+ /* Non-default attributes. */
+
+ barrier->attr = malloc (sizeof *attr);
+ if (! barrier->attr)
+ return ENOMEM;
+
+ *barrier->attr = *attr;
return 0;
}
diff --git a/sysdeps/generic/pt-cond-init.c b/sysdeps/generic/pt-cond-init.c
index 4afcc94..b9e9fb7 100644
--- a/sysdeps/generic/pt-cond-init.c
+++ b/sysdeps/generic/pt-cond-init.c
@@ -19,6 +19,7 @@
#include <pthread.h>
#include <assert.h>
+#include <string.h>
#include <pt-internal.h>
@@ -26,9 +27,19 @@ int
pthread_cond_init (pthread_cond_t *cond,
const pthread_condattr_t *attr)
{
- if (attr)
- assert (attr->pshared == PTHREAD_PROCESS_PRIVATE);
+ *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER;
- *cond = __PTHREAD_COND_INITIALIZER;
+ if (! attr
+ || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0))
+ /* Use the default attributes. */
+ return 0;
+
+ /* Non-default attributes. */
+
+ cond->__attr = malloc (sizeof *attr);
+ if (! cond->__attr)
+ return ENOMEM;
+
+ *cond->__attr = *attr;
return 0;
}
diff --git a/sysdeps/generic/pt-cond-timedwait.c b/sysdeps/generic/pt-cond-timedwait.c
index 4abeb71..c10bdb3 100644
--- a/sysdeps/generic/pt-cond-timedwait.c
+++ b/sysdeps/generic/pt-cond-timedwait.c
@@ -1,5 +1,5 @@
/* Wait on a condition. Generic version.
- Copyright (C) 2000,02 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -58,6 +58,9 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
__pthread_mutex_lock (mutex);
}
+ if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+ return EINVAL;
+
struct __pthread *self = _pthread_self ();
/* Add ourselves to the list of waiters. */
@@ -74,8 +77,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
if (abstime)
{
- error_t err;
-
err = __pthread_timedblock (self, abstime);
if (err)
/* We timed out. We may need to disconnect ourself from the
@@ -91,8 +92,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
if (self->prevp)
__pthread_dequeue (self);
__pthread_spin_unlock (&mutex->__lock);
-
- return err;
}
}
else
diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c
index 2902f6e..23c9f0d 100644
--- a/sysdeps/generic/pt-mutex-init.c
+++ b/sysdeps/generic/pt-mutex-init.c
@@ -1,5 +1,5 @@
/* Initialize a mutex. Generic version.
- Copyright (C) 2000,02 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -28,7 +28,7 @@ int
_pthread_mutex_init (pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr)
{
- *mutex = __PTHREAD_MUTEX_INITIALIZER;
+ *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER;
if (! attr
|| memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0))
diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c
index 3603986..5e222bd 100644
--- a/sysdeps/generic/pt-mutex-timedlock.c
+++ b/sysdeps/generic/pt-mutex-timedlock.c
@@ -1,5 +1,5 @@
/* Lock a mutex with a timeout. Generic version.
- Copyright (C) 2000,02 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -24,13 +24,6 @@
#define LOSE do { * (int *) 0 = 0; } while (1)
-int
-pthread_mutex_timedlock (struct __pthread_mutex *mutex,
- const struct timespec *abstime)
-{
- return __pthread_mutex_timedlock_internal (mutex, abstime);
-}
-
/* Try to lock MUTEX, block until *ABSTIME if it is already held. As
a GNU extension, if TIMESPEC is NULL then wait forever. */
int
@@ -96,6 +89,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
}
}
+ if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+ return EINVAL;
+
/* Add ourselves to the queue. */
__pthread_enqueue (&mutex->__queue, self);
__pthread_spin_unlock (&mutex->__lock);
@@ -146,3 +142,10 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex,
return 0;
}
+
+int
+pthread_mutex_timedlock (struct __pthread_mutex *mutex,
+ const struct timespec *abstime)
+{
+ return __pthread_mutex_timedlock_internal (mutex, abstime);
+}
diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c
index 9457dda..6fdea1a 100644
--- a/sysdeps/generic/pt-mutex-trylock.c
+++ b/sysdeps/generic/pt-mutex-trylock.c
@@ -65,8 +65,9 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex)
break;
case PTHREAD_MUTEX_ERRORCHECK:
- if (mutex->owner == self)
- err = EDEADLK;
+ /* We could check if MUTEX->OWNER is SELF, however, POSIX
+ does not permit pthread_mutex_trylock to return EDEADLK
+ instead of EBUSY, only pthread_mutex_lock. */
break;
case PTHREAD_MUTEX_RECURSIVE:
diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c
index 8fe8764..d6c8c1a 100644
--- a/sysdeps/generic/pt-rwlock-init.c
+++ b/sysdeps/generic/pt-rwlock-init.c
@@ -1,5 +1,5 @@
/* Initialize a rwlock. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -18,13 +18,27 @@
Boston, MA 02111-1307, USA. */
#include <pthread.h>
+#include <string.h>
#include <pt-internal.h>
int
_pthread_rwlock_init (pthread_rwlock_t *rwlock,
const pthread_rwlockattr_t *attr)
{
- *rwlock = __PTHREAD_RWLOCK_INITIALIZER;
+ *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER;
+
+ if (! attr
+ || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0))
+ /* Use the default attributes. */
+ return 0;
+
+ /* Non-default attributes. */
+
+ rwlock->__attr = malloc (sizeof *attr);
+ if (! rwlock->__attr)
+ return ENOMEM;
+
+ *rwlock->__attr = *attr;
return 0;
}
diff --git a/sysdeps/generic/pt-rwlock-rdlock.c b/sysdeps/generic/pt-rwlock-rdlock.c
index 22c1120..480cf48 100644
--- a/sysdeps/generic/pt-rwlock-rdlock.c
+++ b/sysdeps/generic/pt-rwlock-rdlock.c
@@ -1,5 +1,5 @@
/* Acquire a rwlock for reading. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -21,7 +21,7 @@
#include <pt-internal.h>
/* Implemented in pt-rwlock-timedrdlock.c. */
-extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_mutex *mutex,
+extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
const struct timespec *abstime);
/* Acquire RWLOCK for reading, block if we can't get it. */
diff --git a/sysdeps/generic/pt-rwlock-timedrdlock.c b/sysdeps/generic/pt-rwlock-timedrdlock.c
index 85cb946..ba610fa 100644
--- a/sysdeps/generic/pt-rwlock-timedrdlock.c
+++ b/sysdeps/generic/pt-rwlock-timedrdlock.c
@@ -1,5 +1,5 @@
/* Acquire a rwlock for reading. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,13 +22,6 @@
#include <pt-internal.h>
-int
-pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,
- const struct timespec *abstime)
-{
- return __pthread_rwlock_timedrdlock_internal (rwlock, abstime);
-}
-
/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if
it is already held. As a GNU extension, if TIMESPEC is NULL then
wait forever. */
@@ -66,6 +59,9 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
/* Better be blocked by a writer. */
assert (rwlock->readers == 0);
+ if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+ return EINVAL;
+
self = _pthread_self ();
/* Add ourself to the queue. */
@@ -108,3 +104,10 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
return 0;
}
+
+int
+pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,
+ const struct timespec *abstime)
+{
+ return __pthread_rwlock_timedrdlock_internal (rwlock, abstime);
+}
diff --git a/sysdeps/generic/pt-rwlock-timedwrlock.c b/sysdeps/generic/pt-rwlock-timedwrlock.c
index edf6413..04eab51 100644
--- a/sysdeps/generic/pt-rwlock-timedwrlock.c
+++ b/sysdeps/generic/pt-rwlock-timedwrlock.c
@@ -1,5 +1,5 @@
/* Acquire a rwlock for writing. Generic version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,13 +22,6 @@
#include <pt-internal.h>
-int
-pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,
- const struct timespec *abstime)
-{
- return __pthread_rwlock_timedwrlock_internal (rwlock, abstime);
-}
-
/* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get
it. As a special GNU extension, if ABSTIME is NULL then the wait
shall not time out. */
@@ -52,6 +45,9 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
/* The lock is busy. */
+ if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000))
+ return EINVAL;
+
self = _pthread_self ();
/* Add ourselves to the queue. */
@@ -90,3 +86,10 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
return 0;
}
+
+int
+pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,
+ const struct timespec *abstime)
+{
+ return __pthread_rwlock_timedwrlock_internal (rwlock, abstime);
+}
diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c
index f3d280b..0c52111 100644
--- a/sysdeps/generic/sem-timedwait.c
+++ b/sysdeps/generic/sem-timedwait.c
@@ -39,6 +39,12 @@ __sem_timedwait_internal (sem_t *restrict sem,
return 0;
}
+ if (timeout && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
/* Add ourselves to the queue. */
self = _pthread_self ();
@@ -50,12 +56,6 @@ __sem_timedwait_internal (sem_t *restrict sem,
{
error_t err;
- if (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)
- {
- errno = EINVAL;
- return -1;
- }
-
err = __pthread_timedblock (self, timeout);
if (err)
/* We timed out. We may need to disconnect ourself from the