diff options
Diffstat (limited to 'linuxthreads/sysdeps')
-rw-r--r-- | linuxthreads/sysdeps/hppa/pspinlock.c | 81 | ||||
-rw-r--r-- | linuxthreads/sysdeps/hppa/pt-machine.h | 54 | ||||
-rw-r--r-- | linuxthreads/sysdeps/pthread/bits/initspin.h | 28 | ||||
-rw-r--r-- | linuxthreads/sysdeps/pthread/bits/libc-lock.h | 23 | ||||
-rw-r--r-- | linuxthreads/sysdeps/pthread/pthread.h | 15 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h | 27 |
6 files changed, 214 insertions, 14 deletions
diff --git a/linuxthreads/sysdeps/hppa/pspinlock.c b/linuxthreads/sysdeps/hppa/pspinlock.c new file mode 100644 index 0000000000..1b1511fba8 --- /dev/null +++ b/linuxthreads/sysdeps/hppa/pspinlock.c @@ -0,0 +1,81 @@ +/* POSIX spinlock implementation. hppa version. + Copyright (C) 2000 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 + 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 <pthread.h> + + +int +__pthread_spin_lock (pthread_spinlock_t *lock) +{ + unsigned int val; + + do + asm volatile ("ldcw %1,%0" + : "=r" (val), "=m" (*lock) + : "m" (*lock)); + while (!val); + + return 0; +} +weak_alias (__pthread_spin_lock, pthread_spin_lock) + + +int +__pthread_spin_trylock (pthread_spinlock_t *lock) +{ + unsigned int val; + + asm volatile ("ldcw %1,%0" + : "=r" (val), "=m" (*lock) + : "m" (*lock)); + + return val ? 0 : EBUSY; +} +weak_alias (__pthread_spin_trylock, pthread_spin_trylock) + + +int +__pthread_spin_unlock (pthread_spinlock_t *lock) +{ + *lock = 1; + return 0; +} +weak_alias (__pthread_spin_unlock, pthread_spin_unlock) + + +int +__pthread_spin_init (pthread_spinlock_t *lock, int pshared) +{ + /* We can ignore the `pshared' parameter. Since we are busy-waiting + all processes which can access the memory location `lock' points + to can use the spinlock. */ + *lock = 1; + return 0; +} +weak_alias (__pthread_spin_init, pthread_spin_init) + + +int +__pthread_spin_destroy (pthread_spinlock_t *lock) +{ + /* Nothing to do. */ + return 0; +} +weak_alias (__pthread_spin_destroy, pthread_spin_destroy) diff --git a/linuxthreads/sysdeps/hppa/pt-machine.h b/linuxthreads/sysdeps/hppa/pt-machine.h new file mode 100644 index 0000000000..bc0d2d655f --- /dev/null +++ b/linuxthreads/sysdeps/hppa/pt-machine.h @@ -0,0 +1,54 @@ +/* Machine-dependent pthreads configuration and inline functions. + hppa version. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Richard Henderson <rth@tamu.edu>. + + 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 <bits/initspin.h> + +#ifndef PT_EI +# define PT_EI extern inline +#endif + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#define CURRENT_STACK_FRAME stack_pointer +register char * stack_pointer __asm__ ("%r30"); + + +/* The hppa only has one atomic read and modify memory operation, + load and clear, so hppa spinlocks must use zero to signify that + someone is holding the lock. */ + +#define xstr(s) str(s) +#define str(s) #s +/* Spinlock implementation; required. */ +PT_EI int +testandset (int *spinlock) +{ + int ret; + + __asm__ __volatile__( + "ldcw 0(%2),%0" + : "=r"(ret), "=m"(*spinlock) + : "r"(spinlock)); + + return ret == 0; +} +#undef str +#undef xstr diff --git a/linuxthreads/sysdeps/pthread/bits/initspin.h b/linuxthreads/sysdeps/pthread/bits/initspin.h new file mode 100644 index 0000000000..050983c4c1 --- /dev/null +++ b/linuxthreads/sysdeps/pthread/bits/initspin.h @@ -0,0 +1,28 @@ +/* Generic definitions for spinlock initializers. + Copyright (C) 2000 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 + 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. */ + +/* Initial value of a spinlock. Most platforms should use zero, + unless they only implement a "test and clear" operation instead of + the usual "test and set". */ +#define LT_SPINLOCK_INIT 0 + +/* Macros for lock initializers, using the above definition. */ +#define LOCK_INITIALIZER { 0, LT_SPINLOCK_INIT } +#define ALT_LOCK_INITIALIZER { 0, LT_SPINLOCK_INIT } +#define ATOMIC_INITIALIZER { 0, LT_SPINLOCK_INIT } diff --git a/linuxthreads/sysdeps/pthread/bits/libc-lock.h b/linuxthreads/sysdeps/pthread/bits/libc-lock.h index d0e9a8d9b4..41bca4de3f 100644 --- a/linuxthreads/sysdeps/pthread/bits/libc-lock.h +++ b/linuxthreads/sysdeps/pthread/bits/libc-lock.h @@ -48,12 +48,21 @@ typedef pthread_key_t __libc_key_t; /* Define an initialized lock variable NAME with storage class CLASS. - For the C library we take a deeper look at the initializer. For this - implementation all fields are initialized to zero. Therefore we - don't initialize the variable which allows putting it into the BSS - section. */ -#define __libc_lock_define_initialized(CLASS,NAME) \ + For the C library we take a deeper look at the initializer. For + this implementation all fields are initialized to zero. Therefore + we don't initialize the variable which allows putting it into the + BSS section. (Except on PA-RISC and other odd architectures, where + initialized locks must be set to one due to the lack of normal + atomic operations.) */ + +#if LT_SPINLOCK_INIT == 0 +# define __libc_lock_define_initialized(CLASS,NAME) \ CLASS __libc_lock_t NAME; +#else +# define __libc_lock_define_initialized(CLASS,NAME) \ + CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER; +#endif + #define __libc_rwlock_define_initialized(CLASS,NAME) \ CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; @@ -143,9 +152,9 @@ typedef pthread_key_t __libc_key_t; do { \ if (__pthread_once != NULL) \ __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \ - else if ((ONCE_CONTROL) == 0) { \ + else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \ INIT_FUNCTION (); \ - (ONCE_CONTROL) = 1; \ + (ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \ } \ } while (0) diff --git a/linuxthreads/sysdeps/pthread/pthread.h b/linuxthreads/sysdeps/pthread/pthread.h index f2a742e57e..45be6cf2b8 100644 --- a/linuxthreads/sysdeps/pthread/pthread.h +++ b/linuxthreads/sysdeps/pthread/pthread.h @@ -23,6 +23,7 @@ #define __need_sigset_t #include <signal.h> #include <bits/pthreadtypes.h> +#include <bits/initspin.h> __BEGIN_DECLS @@ -30,26 +31,26 @@ __BEGIN_DECLS /* Initializers. */ #define PTHREAD_MUTEX_INITIALIZER \ - {0, 0, 0, PTHREAD_MUTEX_TIMED_NP, {0, 0}} + {0, 0, 0, PTHREAD_MUTEX_TIMED_NP, LOCK_INITIALIZER} #ifdef __USE_GNU # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ - {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, {0, 0}} + {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, LOCK_INITIALIZER} # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ - {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}} + {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, LOCK_INITIALIZER} # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \ - {0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, {0, 0}} + {0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP, LOCK_INITIALIZER} #endif -#define PTHREAD_COND_INITIALIZER {{0, 0}, 0} +#define PTHREAD_COND_INITIALIZER {LOCK_INITIALIZER, 0} #ifdef __USE_UNIX98 # define PTHREAD_RWLOCK_INITIALIZER \ - { {0, 0}, 0, NULL, NULL, NULL, \ + { LOCK_INITIALIZER, 0, NULL, NULL, NULL, \ PTHREAD_RWLOCK_DEFAULT_NP, PTHREAD_PROCESS_PRIVATE } #endif #ifdef __USE_GNU # define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \ - { {0, 0}, 0, NULL, NULL, NULL, \ + { LOCK_INITIALIZER, 0, NULL, NULL, NULL, \ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, PTHREAD_PROCESS_PRIVATE } #endif diff --git a/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h new file mode 100644 index 0000000000..bb8d326348 --- /dev/null +++ b/linuxthreads/sysdeps/unix/sysv/linux/hppa/bits/initspin.h @@ -0,0 +1,27 @@ +/* PA-RISC specific definitions for spinlock initializers. + Copyright (C) 2000 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 + 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. */ + +/* Initial value of a spinlock. PA-RISC only implements atomic load + and clear so this must be non-zero. */ +#define LT_SPINLOCK_INIT 1 + +/* Macros for lock initializers, using the above definition. */ +#define LOCK_INITIALIZER { 0, LT_SPINLOCK_INIT } +#define ALT_LOCK_INITIALIZER { 0, LT_SPINLOCK_INIT } +#define ATOMIC_INITIALIZER { 0, LT_SPINLOCK_INIT } |