diff options
Diffstat (limited to 'sysdeps')
103 files changed, 2636 insertions, 592 deletions
diff --git a/sysdeps/generic/bits/barrier-attr.h b/sysdeps/generic/bits/barrier-attr.h index 86f3cb0..a9900b7 100644 --- a/sysdeps/generic/bits/barrier-attr.h +++ b/sysdeps/generic/bits/barrier-attr.h @@ -1,5 +1,5 @@ /* Thread barrier attribute type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,6 +20,8 @@ #ifndef _BITS_BARRIER_ATTR_H #define _BITS_BARRIER_ATTR_H 1 +enum __pthread_process_shared; + /* This structure describes the attributes of a POSIX thread barrier. Note that not all of them are supported on all systems. */ struct __pthread_barrierattr diff --git a/sysdeps/generic/bits/cancelation.h b/sysdeps/generic/bits/cancelation.h index bb6b58a..46486f5 100644 --- a/sysdeps/generic/bits/cancelation.h +++ b/sysdeps/generic/bits/cancelation.h @@ -1,5 +1,5 @@ /* Cancelation. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,8 +20,6 @@ #ifndef _BITS_CANCELATION_H #define _BITS_CANCELATION_H 1 -#include <assert.h> - struct __pthread_cancelation_handler { void (*handler)(void *); @@ -32,22 +30,21 @@ struct __pthread_cancelation_handler /* Returns the thread local location of the cleanup handler stack. */ struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void); -#define pthread_cleanup_push(rt, rtarg) \ +#define __pthread_cleanup_push(rt, rtarg) \ { \ struct __pthread_cancelation_handler **__handlers \ = __pthread_get_cleanup_stack (); \ struct __pthread_cancelation_handler __handler = \ { \ - handler: (rt), \ - arg: (rtarg), \ - next: *__handlers \ + (rt), \ + (rtarg), \ + *__handlers \ }; \ *__handlers = &__handler; -#define pthread_cleanup_pop(execute) \ +#define __pthread_cleanup_pop(execute) \ if (execute) \ __handler.handler (__handler.arg); \ - assert (*__handlers == &__handler); \ *__handlers = __handler.next; \ } diff --git a/sysdeps/generic/bits/condition-attr.h b/sysdeps/generic/bits/condition-attr.h index 2d48dfb..4cd4e8c 100644 --- a/sysdeps/generic/bits/condition-attr.h +++ b/sysdeps/generic/bits/condition-attr.h @@ -1,5 +1,5 @@ /* Condition attribute type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,13 +20,15 @@ #ifndef _BITS_CONDITION_ATTR_H #define _BITS_CONDITION_ATTR_H 1 -#include <time.h> +#include <bits/types.h> + +enum __pthread_process_shared; /* User visible part of a condition attribute variable. */ struct __pthread_condattr { enum __pthread_process_shared pshared; - clockid_t clock; + __clockid_t clock; }; #endif /* bits/condition.h */ diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h index f3b09be..bf13ada 100644 --- a/sysdeps/generic/bits/condition.h +++ b/sysdeps/generic/bits/condition.h @@ -1,5 +1,5 @@ /* Condition type. Generic version. - Copyright (C) 2000, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2005, 2009 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,6 +34,6 @@ struct __pthread_cond /* Initializer for a condition variable. */ #define __PTHREAD_COND_INITIALIZER \ - { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL } + { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL } #endif /* bits/condition.h */ diff --git a/sysdeps/generic/bits/mutex-attr.h b/sysdeps/generic/bits/mutex-attr.h index 883b074..8514ebe 100644 --- a/sysdeps/generic/bits/mutex-attr.h +++ b/sysdeps/generic/bits/mutex-attr.h @@ -1,5 +1,5 @@ /* Mutex attribute type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,6 +20,10 @@ #ifndef _BITS_MUTEX_ATTR_H #define _BITS_MUTEX_ATTR_H 1 +enum __pthread_mutex_protocol; +enum __pthread_process_shared; +enum __pthread_mutex_type; + /* This structure describes the attributes of a POSIX mutex attribute. */ struct __pthread_mutexattr @@ -30,4 +34,8 @@ struct __pthread_mutexattr enum __pthread_mutex_type mutex_type; }; +/* Attributes for a recursive mutex. */ +extern const struct __pthread_mutexattr __pthread_errorcheck_mutexattr; +extern const struct __pthread_mutexattr __pthread_recursive_mutexattr; + #endif /* bits/mutex-attr.h */ diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h index feb6d07..c734c39 100644 --- a/sysdeps/generic/bits/mutex.h +++ b/sysdeps/generic/bits/mutex.h @@ -1,5 +1,8 @@ /* Mutex type. Generic version. - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + + Copyright (C) 2000, 2002, 2005, 2006, 2007, 2008, 2009 + 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,88 +55,21 @@ struct __pthread_mutex /* Initializer for a mutex. N.B. this also happens to be compatible with the cthread mutex initializer. */ # define __PTHREAD_MUTEX_INITIALIZER \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } -# endif -#endif /* Not __pthread_mutex_defined. */ +# define __PTHREAD_ERRORCHECK_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_ERRORCHECK + 1)) -#ifdef _BITS_MUTEX_H +# define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ + __PTHREAD_ERRORCHECK_MUTEXATTR, 0, 0, 0 } -#include <errno.h> -#include <stddef.h> +# define __PTHREAD_RECURSIVE_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_RECURSIVE + 1)) -#ifdef __USE_EXTERN_INLINES +# define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ + __PTHREAD_RECURSIVE_MUTEXATTR, 0, 0, 0 } -# ifndef _EXTERN_INLINE -# define _EXTERN_INLINE extern __inline # endif - -_EXTERN_INLINE int -pthread_mutex_init (struct __pthread_mutex *__restrict __mutex, - const pthread_mutexattr_t *__restrict 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 = initialized_mutex; - return 0; -} - -_EXTERN_INLINE int -pthread_mutex_destroy (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_destroy (struct __pthread_mutex *); - - if (__mutex->attr || __mutex->data) - return _pthread_mutex_destroy (__mutex); - - return 0; -} - -_EXTERN_INLINE int -__pthread_mutex_lock (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_lock (struct __pthread_mutex *); - - if (__mutex->attr == NULL - && __mutex->data == NULL - && __pthread_spin_trylock (&__mutex->__held) == 0) - return 0; - - return _pthread_mutex_lock (__mutex); -} - -extern __inline int -__pthread_mutex_trylock (struct __pthread_mutex *__mutex) -{ - extern int _pthread_mutex_trylock (struct __pthread_mutex *); - - if (__mutex->attr == NULL - && __mutex->data == NULL) - return __pthread_spin_trylock (&__mutex->__held); - - return _pthread_mutex_trylock (__mutex); -} - -extern __inline int -pthread_mutex_lock (struct __pthread_mutex *__mutex) -{ - return __pthread_mutex_lock (__mutex); -} - -extern __inline int -pthread_mutex_trylock (struct __pthread_mutex *__mutex) -{ - return __pthread_mutex_trylock (__mutex); -} - -#endif /* Use extern inlines. */ - -#endif +#endif /* Not __pthread_mutex_defined. */ #endif /* bits/mutex.h */ diff --git a/sysdeps/generic/bits/once.h b/sysdeps/generic/bits/once.h index 7f572fa..f4985d6 100644 --- a/sysdeps/generic/bits/once.h +++ b/sysdeps/generic/bits/once.h @@ -1,5 +1,5 @@ /* Dynamic package initialization data structures. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2009 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 @@ -29,6 +29,6 @@ struct __pthread_once }; #define __PTHREAD_ONCE_INIT \ - { 0, __SPIN_LOCK_INITIALIZER } + { 0, __PTHREAD_SPIN_LOCK_INITIALIZER } #endif /* bits/once.h */ diff --git a/sysdeps/generic/bits/pthread-np.h b/sysdeps/generic/bits/pthread-np.h new file mode 100644 index 0000000..d5ddbb0 --- /dev/null +++ b/sysdeps/generic/bits/pthread-np.h @@ -0,0 +1,27 @@ +/* Non-portable functions. Generic version. + Copyright (C) 2008 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. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_PTHREAD_NP_H +#define _BITS_PTHREAD_NP_H 1 + +#endif /* bits/pthread-np.h */ diff --git a/sysdeps/generic/bits/pthread.h b/sysdeps/generic/bits/pthread.h index 3f9df13..80e6b09 100644 --- a/sysdeps/generic/bits/pthread.h +++ b/sysdeps/generic/bits/pthread.h @@ -1,5 +1,5 @@ /* Pthread data structures. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,14 +20,19 @@ #ifndef _BITS_PTHREAD_H #define _BITS_PTHREAD_H 1 -typedef int pthread_t; +typedef int __pthread_t; /* Return true if __T1 and __T2 both name the same thread. Otherwise, false. */ -extern __inline int -pthread_equal (pthread_t __t1, pthread_t __t2) +extern int +__pthread_equal (__pthread_t __t1, __pthread_t __t2); + +#ifdef __USE_EXTERN_INLINES +__extern_inline int +__pthread_equal (__pthread_t __t1, __pthread_t __t2) { return __t1 == __t2; } +#endif #endif /* bits/pthread.h */ diff --git a/sysdeps/generic/bits/pthreadtypes.h b/sysdeps/generic/bits/pthreadtypes.h new file mode 100644 index 0000000..e5cbfd2 --- /dev/null +++ b/sysdeps/generic/bits/pthreadtypes.h @@ -0,0 +1,29 @@ +/* + 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. */ + +#if !defined _BITS_TYPES_H && !defined _PTHREAD_H +# error "Never include <bits/pthreadtypes.h> directly; use <sys/types.h> instead." +#endif + +#ifndef _BITS_PTHREADTYPES_H +#define _BITS_PTHREADTYPES_H 1 + +#include <pthread.h> + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/generic/bits/rwlock-attr.h b/sysdeps/generic/bits/rwlock-attr.h index 44765bd..dba99f1 100644 --- a/sysdeps/generic/bits/rwlock-attr.h +++ b/sysdeps/generic/bits/rwlock-attr.h @@ -1,5 +1,5 @@ /* Thread rwlock attribute type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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 @@ -20,6 +20,8 @@ #ifndef _BITS_RWLOCK_ATTR_H #define _BITS_RWLOCK_ATTR_H 1 +enum __pthread_process_shared; + /* This structure describes the attributes of a POSIX thread rwlock. Note that not all of them are supported on all systems. */ struct __pthread_rwlockattr diff --git a/sysdeps/generic/bits/rwlock.h b/sysdeps/generic/bits/rwlock.h index fc429b4..af6b1c8 100644 --- a/sysdeps/generic/bits/rwlock.h +++ b/sysdeps/generic/bits/rwlock.h @@ -1,5 +1,5 @@ /* rwlock type. Generic version. - Copyright (C) 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006, 2007, 2009 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,34 +40,7 @@ struct __pthread_rwlock /* Initializer for a rwlock. */ #define __PTHREAD_RWLOCK_INITIALIZER \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } -_EXTERN_INLINE int -pthread_rwlock_init (struct __pthread_rwlock *__restrict __rwlock, - const struct __pthread_rwlockattr *__restrict __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 = initialized_rwlock; - return 0; -} - -_EXTERN_INLINE int -pthread_rwlock_destroy (struct __pthread_rwlock *__rwlock) -{ - extern int _pthread_rwlock_destroy (struct __pthread_rwlock *); - - if (__rwlock->__attr - || __rwlock->__data) - return _pthread_rwlock_destroy (__rwlock); - - return 0; -} - #endif /* bits/rwlock.h */ diff --git a/sysdeps/generic/bits/semaphore.h b/sysdeps/generic/bits/semaphore.h index b53f47e..5e987c1 100644 --- a/sysdeps/generic/bits/semaphore.h +++ b/sysdeps/generic/bits/semaphore.h @@ -1,5 +1,5 @@ /* Semaphore type. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2009 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 @@ -38,6 +38,6 @@ struct __semaphore /* Initializer for a semaphore. */ #define __SEMAPHORE_INITIALIZER(pshared, value) \ - { __SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL } + { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL } #endif /* bits/mutex.h */ diff --git a/sysdeps/generic/bits/thread-attr.h b/sysdeps/generic/bits/thread-attr.h index 3163022..f2e55f2 100644 --- a/sysdeps/generic/bits/thread-attr.h +++ b/sysdeps/generic/bits/thread-attr.h @@ -1,5 +1,5 @@ /* Thread attribute type. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2008 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 @@ -20,13 +20,18 @@ #ifndef _BITS_THREAD_ATTR_H #define _BITS_THREAD_ATTR_H 1 -#include <sched.h> +#define __need_schedparam +#include <bits/sched.h> + +enum __pthread_detachstate; +enum __pthread_inheritsched; +enum __pthread_contentionscope; /* This structure describes the attributes of a POSIX thread. Note that not all of them are supported on all systems. */ struct __pthread_attr { - struct sched_param schedparam; + struct __sched_param schedparam; void *stackaddr; size_t stacksize; size_t guardsize; diff --git a/sysdeps/generic/killpg.c b/sysdeps/generic/killpg.c new file mode 100644 index 0000000..7f7ed87 --- /dev/null +++ b/sysdeps/generic/killpg.c @@ -0,0 +1,27 @@ +/* killpg.c - Generic killpg implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +killpg (pid_t pid, int sig) +{ + return kill (-pid, sig); +} diff --git a/sysdeps/generic/pt-attr-getschedparam.c b/sysdeps/generic/pt-attr-getschedparam.c index 25afebd..190cf9d 100644 --- a/sysdeps/generic/pt-attr-getschedparam.c +++ b/sysdeps/generic/pt-attr-getschedparam.c @@ -19,6 +19,7 @@ #include <pthread.h> #include <sched.h> +#include <string.h> #include <pt-internal.h> @@ -26,6 +27,6 @@ int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param) { - *param = attr->schedparam; + memcpy (param, &attr->schedparam, sizeof *param); return 0; } diff --git a/sysdeps/generic/pt-attr-setschedparam.c b/sysdeps/generic/pt-attr-setschedparam.c index 18a575e..5459f10 100644 --- a/sysdeps/generic/pt-attr-setschedparam.c +++ b/sysdeps/generic/pt-attr-setschedparam.c @@ -30,7 +30,7 @@ pthread_attr_setschedparam (pthread_attr_t *attr, if (memcmp (param, &__pthread_default_attr.schedparam, sizeof *param) == 0) { - attr->schedparam = *param; + memcpy (&attr->schedparam, param, sizeof *param); return 0; } diff --git a/sysdeps/generic/pt-kill.c b/sysdeps/generic/pt-kill.c new file mode 100644 index 0000000..0dfac34 --- /dev/null +++ b/sysdeps/generic/pt-kill.c @@ -0,0 +1,32 @@ +/* pthread-kill.c - Generic pthread-kill implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +pthread_kill (pthread_t tid, int signo) +{ + siginfo_t si; + memset (&si, 0, sizeof (si)); + si.si_signo = signo; + + return pthread_kill_siginfo_np (tid, si); +} + diff --git a/sysdeps/generic/pt-mutex-destroy.c b/sysdeps/generic/pt-mutex-destroy.c index 72faefe..3bbc73f 100644 --- a/sysdeps/generic/pt-mutex-destroy.c +++ b/sysdeps/generic/pt-mutex-destroy.c @@ -1,5 +1,5 @@ /* Destroy a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2006 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 @@ -26,7 +26,11 @@ int _pthread_mutex_destroy (pthread_mutex_t *mutex) { - if (mutex->attr) + if (mutex->attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->attr == __PTHREAD_RECURSIVE_MUTEXATTR) + /* Static attributes. */ + ; + else free (mutex->attr); return 0; diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index da1781b..2f96028 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, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2006, 2008 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 @@ -32,12 +32,14 @@ _pthread_mutex_init (pthread_mutex_t *mutex, if (! attr || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0)) - /* Use the default attributes. */ + /* The default attributes. */ return 0; - /* Non-default attributes. */ + if (! mutex->attr + || mutex->attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->attr == __PTHREAD_RECURSIVE_MUTEXATTR) + mutex->attr = malloc (sizeof *attr); - mutex->attr = malloc (sizeof *attr); if (! mutex->attr) return ENOMEM; diff --git a/sysdeps/generic/pt-mutex-lock.c b/sysdeps/generic/pt-mutex-lock.c index 60fc55a..528e593 100644 --- a/sysdeps/generic/pt-mutex-lock.c +++ b/sysdeps/generic/pt-mutex-lock.c @@ -1,5 +1,5 @@ /* Lock a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2006 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 diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index 5e222bd..883e50a 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, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2008 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 @@ -31,13 +31,33 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, const struct timespec *abstime) { struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; __pthread_spin_lock (&mutex->__lock); if (__pthread_spin_trylock (&mutex->__held) == 0) /* Successfully acquired the lock. */ { - if (mutex->attr) - switch (mutex->attr->mutex_type) +#ifdef ALWAYS_TRACK_MUTEX_OWNER +#ifndef NDEBUG + self = _pthread_self (); + if (self) + /* The main thread may take a lock before the library is fully + initialized, in particular, before the main thread has a + TCB. */ + { + assert (! mutex->owner); + mutex->owner = _pthread_self (); + } +#endif +#endif + + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; @@ -59,14 +79,18 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, /* The lock is busy. */ self = _pthread_self (); + assert (self); - if (mutex->attr) + if (! attr || attr->mutex_type == PTHREAD_MUTEX_NORMAL) + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) + assert (mutex->owner != self); +#endif + } + else { - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { - case PTHREAD_MUTEX_NORMAL: - break; - case PTHREAD_MUTEX_ERRORCHECK: if (mutex->owner == self) { @@ -89,6 +113,11 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } } +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + assert (mutex->owner); + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) return EINVAL; @@ -123,8 +152,15 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, else __pthread_block (self); - if (mutex->attr) - switch (mutex->attr->mutex_type) +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + { + assert (mutex->owner == self); + } + + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; diff --git a/sysdeps/generic/pt-mutex-transfer-np.c b/sysdeps/generic/pt-mutex-transfer-np.c new file mode 100644 index 0000000..967f1c7 --- /dev/null +++ b/sysdeps/generic/pt-mutex-transfer-np.c @@ -0,0 +1,66 @@ +/* Transfer ownership of a mutex. Generic version. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid) +{ + assert (mutex->owner == _pthread_self ()); + + struct __pthread *thread = __pthread_getid (tid); + const struct __pthread_mutexattr *attr = mutex->attr; + + if (! thread) + return ESRCH; + + if (thread == _pthread_self ()) + return 0; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + if (attr && attr->mutex_type == PTHREAD_MUTEX_ERRORCHECK) + { + + if (mutex->owner != _pthread_self ()) + return EPERM; + + mutex->owner = thread; + } + +#ifndef NDEBUG +# if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +# endif + { + mutex->owner = thread; + } +#endif + + return 0; +} + +strong_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np) diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index d56f6e1..7a54cc9 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -1,5 +1,5 @@ /* Try to Lock a mutex. Generic version. - Copyright (C) 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2008 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 @@ -29,13 +29,33 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) { int err; struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; __pthread_spin_lock (&mutex->__lock); if (__pthread_spin_trylock (&mutex->__held) == 0) /* Acquired the lock. */ { - if (mutex->attr) - switch (mutex->attr->mutex_type) +#if defined(ALWAYS_TRACK_MUTEX_OWNER) +#ifndef NDEBUG + self = _pthread_self (); + if (self) + /* The main thread may take a lock before the library is fully + initialized, in particular, before the main thread has a + TCB. */ + { + assert (! mutex->owner); + mutex->owner = _pthread_self (); + } +#endif +#endif + + if (attr) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; @@ -56,10 +76,10 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) err = EBUSY; - if (mutex->attr) + if (attr) { self = _pthread_self (); - switch (mutex->attr->mutex_type) + switch (attr->mutex_type) { case PTHREAD_MUTEX_NORMAL: break; diff --git a/sysdeps/generic/pt-mutex-unlock.c b/sysdeps/generic/pt-mutex-unlock.c index 2f719d3..09d70f8 100644 --- a/sysdeps/generic/pt-mutex-unlock.c +++ b/sysdeps/generic/pt-mutex-unlock.c @@ -1,5 +1,5 @@ /* Unlock a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2008 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,15 +28,31 @@ int __pthread_mutex_unlock (pthread_mutex_t *mutex) { struct __pthread *wakeup; - + const struct __pthread_mutexattr *attr = mutex->attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + __pthread_spin_lock (&mutex->__lock); - if (mutex->attr) - switch (mutex->attr->mutex_type) + if (! attr || attr->mutex_type == PTHREAD_MUTEX_NORMAL) + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) +# ifndef NDEBUG + if (_pthread_self ()) + { + assert (mutex->owner); + assert (mutex->owner == _pthread_self ()); + mutex->owner = NULL; + } +# endif +#endif + } + else + switch (attr->mutex_type) { - case PTHREAD_MUTEX_NORMAL: - break; - case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_RECURSIVE: if (mutex->owner != _pthread_self ()) @@ -45,7 +61,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) return EPERM; } - if (mutex->attr->mutex_type == PTHREAD_MUTEX_RECURSIVE) + if (attr->mutex_type == PTHREAD_MUTEX_RECURSIVE) if (--mutex->locks > 0) { __pthread_spin_unlock (&mutex->__lock); @@ -59,6 +75,7 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) LOSE; } + if (mutex->__queue == NULL) { __pthread_spin_unlock (&mutex->__held); @@ -69,6 +86,15 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) wakeup = mutex->__queue; __pthread_dequeue (wakeup); +#ifndef NDEBUG +# if !defined (ALWAYS_TRACK_MUTEX_OWNER) + if (attr && attr->mutex_type != PTHREAD_MUTEX_NORMAL) +# endif + { + mutex->owner = wakeup; + } +#endif + /* We do not unlock MUTEX->held: we are transferring the ownership to the thread that we are waking up. */ diff --git a/sysdeps/generic/pt-mutexattr.c b/sysdeps/generic/pt-mutexattr.c index 647db24..5ebde6e 100644 --- a/sysdeps/generic/pt-mutexattr.c +++ b/sysdeps/generic/pt-mutexattr.c @@ -1,5 +1,5 @@ /* Default mutex attributes. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2008 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 @@ -27,3 +27,19 @@ const struct __pthread_mutexattr __pthread_default_mutexattr = pshared: PTHREAD_PROCESS_PRIVATE, mutex_type: PTHREAD_MUTEX_DEFAULT }; + +const struct __pthread_mutexattr __pthread_errorcheck_mutexattr = +{ + prioceiling: 0, + protocol: PTHREAD_PRIO_NONE, + pshared: PTHREAD_PROCESS_PRIVATE, + mutex_type: PTHREAD_MUTEX_ERRORCHECK +}; + +const struct __pthread_mutexattr __pthread_recursive_mutexattr = +{ + prioceiling: 0, + protocol: PTHREAD_PRIO_NONE, + pshared: PTHREAD_PROCESS_PRIVATE, + mutex_type: PTHREAD_MUTEX_RECURSIVE +}; diff --git a/sysdeps/generic/pt-rwlock-destroy.c b/sysdeps/generic/pt-rwlock-destroy.c index 034d930..045eebd 100644 --- a/sysdeps/generic/pt-rwlock-destroy.c +++ b/sysdeps/generic/pt-rwlock-destroy.c @@ -1,5 +1,5 @@ /* Destroy a rwlock. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2006 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 diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c index 8aa495e..c9ff9b2 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, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006 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 diff --git a/sysdeps/generic/pt-startup.c b/sysdeps/generic/pt-startup.c new file mode 100644 index 0000000..c21a181 --- /dev/null +++ b/sysdeps/generic/pt-startup.c @@ -0,0 +1,25 @@ +/* Thread initialization. Generic version. + Copyright (C) 2008 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 <pt-internal.h> + +void +__pthread_startup (void) +{ +} diff --git a/sysdeps/generic/raise.c b/sysdeps/generic/raise.c new file mode 100644 index 0000000..410f557 --- /dev/null +++ b/sysdeps/generic/raise.c @@ -0,0 +1,41 @@ +/* raise.c - Generic raise implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +raise (int signo) +{ + /* According to POSIX, if we implement threads (and we do), then + "the effect of the raise() function shall be equivalent to + calling: pthread_kill(pthread_self(), sig);" */ + +debug (0, ""); + int err = pthread_kill (pthread_self (), signo); +debug (0, ""); + if (err) + { + errno = err; + return -1; + } + + return 0; +} + diff --git a/sysdeps/generic/sem-destroy.c b/sysdeps/generic/sem-destroy.c index 985f4ad..6486599 100644 --- a/sysdeps/generic/sem-destroy.c +++ b/sysdeps/generic/sem-destroy.c @@ -1,5 +1,5 @@ /* Destroy a semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-getvalue.c b/sysdeps/generic/sem-getvalue.c index 8e418e3..7762089 100644 --- a/sysdeps/generic/sem-getvalue.c +++ b/sysdeps/generic/sem-getvalue.c @@ -1,5 +1,5 @@ /* Get the value of a semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-init.c b/sysdeps/generic/sem-init.c index 6c6d79e..d2414f5 100644 --- a/sysdeps/generic/sem-init.c +++ b/sysdeps/generic/sem-init.c @@ -1,5 +1,5 @@ /* Initialize a semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-open.c b/sysdeps/generic/sem-open.c index 9eb13aa..bae87ed 100644 --- a/sysdeps/generic/sem-open.c +++ b/sysdeps/generic/sem-open.c @@ -1,5 +1,5 @@ /* Open a named semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-post.c b/sysdeps/generic/sem-post.c index 0e20ea7..6d438bf 100644 --- a/sysdeps/generic/sem-post.c +++ b/sysdeps/generic/sem-post.c @@ -1,5 +1,5 @@ /* Post a semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c index d01bfdb..e34539a 100644 --- a/sysdeps/generic/sem-timedwait.c +++ b/sysdeps/generic/sem-timedwait.c @@ -1,5 +1,5 @@ /* Wait on a semaphore with a timeout. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2008 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,7 +18,6 @@ Boston, MA 02111-1307, USA. */ #include <semaphore.h> -#include <error.h> #include <errno.h> #include <assert.h> diff --git a/sysdeps/generic/sem-trywait.c b/sysdeps/generic/sem-trywait.c index 199f317..437e282 100644 --- a/sysdeps/generic/sem-trywait.c +++ b/sysdeps/generic/sem-trywait.c @@ -1,5 +1,5 @@ /* Lock a semaphore if it does not require blocking. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-unlink.c b/sysdeps/generic/sem-unlink.c index 519f4f7..570ed61 100644 --- a/sysdeps/generic/sem-unlink.c +++ b/sysdeps/generic/sem-unlink.c @@ -1,5 +1,5 @@ /* Unlink a named semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sem-wait.c b/sysdeps/generic/sem-wait.c index 50752f3..8347480 100644 --- a/sysdeps/generic/sem-wait.c +++ b/sysdeps/generic/sem-wait.c @@ -1,5 +1,5 @@ /* Wait on a semaphore. Generic version. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 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 diff --git a/sysdeps/generic/sigaddset.c b/sysdeps/generic/sigaddset.c new file mode 100644 index 0000000..14edb71 --- /dev/null +++ b/sysdeps/generic/sigaddset.c @@ -0,0 +1,35 @@ +/* sigaddset.c - Generic sigaddset implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +sigaddset (sigset_t *sigset, int signo) +{ + if (signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + *sigset |= sigmask (signo); + return 0; +} + diff --git a/sysdeps/generic/sigdelset.c b/sysdeps/generic/sigdelset.c new file mode 100644 index 0000000..5456467 --- /dev/null +++ b/sysdeps/generic/sigdelset.c @@ -0,0 +1,35 @@ +/* sigdelset.c - Generic sigdelset implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +sigdelset (sigset_t *sigset, int signo) +{ + if (signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + *sigset &= ~sigmask (signo); + return 0; +} + diff --git a/sysdeps/generic/sigemptyset.c b/sysdeps/generic/sigemptyset.c new file mode 100644 index 0000000..690c15b --- /dev/null +++ b/sysdeps/generic/sigemptyset.c @@ -0,0 +1,29 @@ +/* sigemptyset.c - Generic sigemptyset implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <signal.h> + +int +sigemptyset (sigset_t *sigset) +{ + *sigset = 0; + return 0; +} + diff --git a/sysdeps/generic/sigfillset.c b/sysdeps/generic/sigfillset.c new file mode 100644 index 0000000..f0ac078 --- /dev/null +++ b/sysdeps/generic/sigfillset.c @@ -0,0 +1,29 @@ +/* sigfillset.c - Generic sigfillset implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <signal.h> + +int +sigfillset (sigset_t *sigset) +{ + *sigset = (1ULL << (NSIG - 1)) - 1; + return 0; +} + diff --git a/sysdeps/generic/siginterrupt.c b/sysdeps/generic/siginterrupt.c new file mode 100644 index 0000000..0899efb --- /dev/null +++ b/sysdeps/generic/siginterrupt.c @@ -0,0 +1,36 @@ +/* siginterrupt.c - Generic siginterrupt implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +siginterrupt (int sig, int flag) +{ + int ret; + struct sigaction act; + + sigaction (sig, NULL, &act); + if (flag) + act.sa_flags &= ~SA_RESTART; + else + act.sa_flags |= SA_RESTART; + ret = sigaction(sig, &act, NULL); + return ret; +} diff --git a/sysdeps/generic/sigismember.c b/sysdeps/generic/sigismember.c new file mode 100644 index 0000000..b3d65c9 --- /dev/null +++ b/sysdeps/generic/sigismember.c @@ -0,0 +1,36 @@ +/* sigismember.c - Generic sigismember implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +sigismember (const sigset_t *sigset, int signo) +{ + if (signo <= 0 || signo >= NSIG) + { + errno = EINVAL; + return -1; + } + + if (*sigset & sigmask (signo)) + return 1; + else + return 0; +} diff --git a/sysdeps/generic/signal.c b/sysdeps/generic/signal.c new file mode 100644 index 0000000..7555d0a --- /dev/null +++ b/sysdeps/generic/signal.c @@ -0,0 +1,44 @@ +/* signal.c - Generic signal implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +void (*signal (int sig, void (*handler)(int)))(int) +{ + struct sigaction sa; + + sa.sa_handler = handler; + sa.sa_flags = SA_RESTART; + + if (sigemptyset (&sa.sa_mask) < 0 + || sigaddset (&sa.sa_mask, sig) < 0) + return SIG_ERR; + + struct sigaction osa; + if (sigaction (sig, &sa, &osa) < 0) + return SIG_ERR; + + return osa.sa_handler; +} + +void (*bsd_signal (int sig, void (*func)(int)))(int) +{ + return signal (sig, func); +} diff --git a/sysdeps/generic/sigwait.c b/sysdeps/generic/sigwait.c new file mode 100644 index 0000000..7d10bf8 --- /dev/null +++ b/sysdeps/generic/sigwait.c @@ -0,0 +1,34 @@ +/* sigwait.c - Generic sigwait implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include "sig-internal.h" + +int +sigwait (const sigset_t *restrict set, int *restrict signo) +{ + siginfo_t info; + + if (sigwaitinfo (set, &info) < 0) + return -1; + + *signo = info.si_signo; + return 0; +} + diff --git a/sysdeps/hurd/pt-kill.c b/sysdeps/hurd/pt-kill.c index f970e06..d204e3f 100644 --- a/sysdeps/hurd/pt-kill.c +++ b/sysdeps/hurd/pt-kill.c @@ -39,6 +39,9 @@ pthread_kill (pthread_t thread, int sig) ss = _hurd_thread_sigstate (pthread->kernel_thread); assert (ss); + if (!sig) + return 0; + detail.exc = 0; detail.code = sig; detail.error = 0; diff --git a/sysdeps/i386/bits/atomic.h b/sysdeps/ia32/bits/atomic.h index 0dfc1f6..0dfc1f6 100644 --- a/sysdeps/i386/bits/atomic.h +++ b/sysdeps/ia32/bits/atomic.h diff --git a/sysdeps/i386/bits/memory.h b/sysdeps/ia32/bits/memory.h index 201305b..932c408 100644 --- a/sysdeps/i386/bits/memory.h +++ b/sysdeps/ia32/bits/memory.h @@ -1,5 +1,5 @@ /* Memory barrier operations. i386 version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2008 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,14 +21,14 @@ #define _BITS_MEMORY_H 1 /* Prevent read and write reordering across this function. */ -inline void +static inline void __memory_barrier (void) { int i; /* Any lock'ed instruction will do. We just do a simple increment. */ - __asm__ __volatile ("lock; incl %0" : "=m" (i) : "m" (i)); + __asm__ __volatile ("lock; incl %0" : "=m" (i) : "m" (i) : "memory"); } /* Prevent read reordering across this function. */ diff --git a/sysdeps/i386/bits/spin-lock.h b/sysdeps/ia32/bits/spin-lock-inline.h index e86bc13..e5ed3de 100644 --- a/sysdeps/i386/bits/spin-lock.h +++ b/sysdeps/ia32/bits/spin-lock-inline.h @@ -1,5 +1,5 @@ /* Machine-specific definitions for spin locks. i386 version. - Copyright (C) 2000, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2005, 2008, 2009 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,19 +21,14 @@ * Never include this file directly; use <pthread.h> or <cthreads.h> instead. */ -#ifndef _BITS_SPIN_LOCK_H -#define _BITS_SPIN_LOCK_H 1 +#ifndef _BITS_SPIN_LOCK_INLINE_H +#define _BITS_SPIN_LOCK_INLINE_H 1 #include <features.h> +#include <bits/spin-lock.h> __BEGIN_DECLS -/* The type of a spin lock object. */ -typedef __volatile int __pthread_spinlock_t; - -/* Initializer for a spin lock object. */ -# define __SPIN_LOCK_INITIALIZER (0) - #if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES # ifndef __EBUSY @@ -42,7 +37,7 @@ typedef __volatile int __pthread_spinlock_t; # endif # ifndef __PT_SPIN_INLINE -# define __PT_SPIN_INLINE extern __inline +# define __PT_SPIN_INLINE __extern_inline # endif __PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock); @@ -59,7 +54,7 @@ __PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, __PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared) { - *__lock = __SPIN_LOCK_INITIALIZER; + *__lock = __PTHREAD_SPIN_LOCK_INITIALIZER; return 0; } @@ -70,14 +65,14 @@ __pthread_spin_trylock (__pthread_spinlock_t *__lock) { int __locked; __asm__ __volatile ("xchgl %0, %1" - : "=&r" (__locked), "=m" (*__lock) : "0" (1)); + : "=&r" (__locked), "=m" (*__lock) : "0" (1) : "memory"); return __locked ? __EBUSY : 0; } -extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); +__extern_inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); -extern __inline int +__extern_inline int __pthread_spin_lock (__pthread_spinlock_t *__lock) { if (__pthread_spin_trylock (__lock)) @@ -92,7 +87,7 @@ __pthread_spin_unlock (__pthread_spinlock_t *__lock) { int __unlocked; __asm__ __volatile ("xchgl %0, %1" - : "=&r" (__unlocked), "=m" (*__lock) : "0" (0)); + : "=&r" (__unlocked), "=m" (*__lock) : "0" (0) : "memory"); return 0; } diff --git a/sysdeps/ia32/bits/spin-lock.h b/sysdeps/ia32/bits/spin-lock.h new file mode 100644 index 0000000..5ae81e1 --- /dev/null +++ b/sysdeps/ia32/bits/spin-lock.h @@ -0,0 +1,39 @@ +/* Machine-specific definitions for spin locks. i386 version. + Copyright (C) 2000, 2005, 2008, 2009 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. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_SPIN_LOCK_H +#define _BITS_SPIN_LOCK_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* The type of a spin lock object. */ +typedef __volatile int __pthread_spinlock_t; + +/* Initializer for a spin lock object. */ +# define __PTHREAD_SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0) + +__END_DECLS + +#endif /* bits/spin-lock.h */ diff --git a/sysdeps/i386/machine-sp.h b/sysdeps/ia32/machine-sp.h index 945a36b..cef6ab7 100644 --- a/sysdeps/i386/machine-sp.h +++ b/sysdeps/ia32/machine-sp.h @@ -1,5 +1,5 @@ /* Machine-specific function to return the stack pointer. i386 version. - Copyright (C) 1994,97,2001 Free Software Foundation, Inc. + Copyright (C) 1994, 1997, 2001, 2006 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 diff --git a/sysdeps/i386/pt-machdep.h b/sysdeps/ia32/pt-machdep.h index 6d45636..6d45636 100644 --- a/sysdeps/i386/pt-machdep.h +++ b/sysdeps/ia32/pt-machdep.h diff --git a/sysdeps/l4/bits/pthread-np.h b/sysdeps/l4/bits/pthread-np.h new file mode 100644 index 0000000..6a02bdc --- /dev/null +++ b/sysdeps/l4/bits/pthread-np.h @@ -0,0 +1,35 @@ +/* Non-portable functions. L4 version. + Copyright (C) 2003, 2007 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. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_PTHREAD_NP_H +#define _BITS_PTHREAD_NP_H 1 + +#include <l4.h> + +/* Add the thread TID to the internal kernel thread pool. */ +extern int pthread_pool_add_np (l4_thread_id_t tid); + +/* Get the first thread from the pool. */ +extern l4_thread_id_t pthread_pool_get_np (void); + +#endif /* bits/pthread-np.h */ diff --git a/sysdeps/l4/hurd/bits/pthread-np.h b/sysdeps/l4/hurd/bits/pthread-np.h new file mode 100644 index 0000000..a90793d --- /dev/null +++ b/sysdeps/l4/hurd/bits/pthread-np.h @@ -0,0 +1,31 @@ +/* Non-portable functions. Viengoos version. + Copyright (C) 2008 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. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_PTHREAD_NP_H +#define _BITS_PTHREAD_NP_H 1 + +#include <hurd/addr.h> + +int pthread_setactivity_np (addr_t activity); + +#endif /* bits/pthread-np.h */ diff --git a/sysdeps/l4/hurd/i386/pt-machdep.c b/sysdeps/l4/hurd/ia32/pt-machdep.c index dbf5cd7..dbf5cd7 100644 --- a/sysdeps/l4/hurd/i386/pt-machdep.c +++ b/sysdeps/l4/hurd/ia32/pt-machdep.c diff --git a/sysdeps/l4/hurd/ia32/pt-setup.c b/sysdeps/l4/hurd/ia32/pt-setup.c new file mode 100644 index 0000000..579905c --- /dev/null +++ b/sysdeps/l4/hurd/ia32/pt-setup.c @@ -0,0 +1,117 @@ +/* Setup thread stack. Viengoos/i386 version. + Copyright (C) 2000, 2002, 2008 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 <l4.h> + +#include <pt-internal.h> +#include <hurd/thread.h> +#include <hurd/exceptions.h> + +/* The stack layout used on the i386 is: + + ----------------- + | ARG | + ----------------- + | START_ROUTINE | + ----------------- + | Return address | + ----------------- <- %ebp + | Frame pointer | + ----------------- + + We do the following: setup the stack to return to the entry routine. + + +*/ + +/* The stack contains: + + arg + start_routine + 0 <- fake return address + C entry_point +*/ +extern uintptr_t _pthread_entry_point; +__asm__ ("\n\ + .globl _pthread_entry_point, __pthread_entry_point\n\ +_pthread_entry_point:\n\ +__pthread_entry_point:\n\ + pushl $0\n\ + popf\n\ +\n\ + xor %ebp, %ebp\n\ + ret\n"); + +/* Set up the stack for THREAD, such that it appears as if + START_ROUTINE and ARG were passed to the new thread's entry-point. + Return the stack pointer for the new thread. We also take the + opportunity to install THREAD in our utcb. */ +static void * +stack_setup (struct __pthread *thread, + void *(*start_routine)(void *), void *arg, + void (*entry_point)(void *(*)(void *), void *)) +{ + uintptr_t *top; + + /* Calculate top of the new stack. */ + top = (uintptr_t *) ((uintptr_t) thread->stackaddr + thread->stacksize); + + /* Align on 0x10 for MMX operations. */ + top = (uintptr_t) top & ~0xf; + + if (start_routine) + { + /* Set up call frame. */ + *--top = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + *--top = (uintptr_t) start_routine; + *--top = 0; /* Fake return address. */ + *--top = (uintptr_t) entry_point; + } + + return top; +} + +int +__pthread_setup (struct __pthread *thread, + void (*entry_point)(void *(*)(void *), void *), + void *(*start_routine)(void *), void *arg) +{ + thread->mcontext.pc = (void *) &_pthread_entry_point; + thread->mcontext.sp = (void *) stack_setup (thread, start_routine, arg, + entry_point); + + if (__pthread_num_threads == 1) + return 0; + + assert (! ADDR_IS_VOID (thread->exception_area[0])); + + struct exception_page *exception_page = thread->exception_area_va; + + /* SP is set to the end of the exception area minus one word, which + is the location of the exception page. */ + exception_page->exception_handler_sp + = (uintptr_t) thread->exception_area_va + EXCEPTION_AREA_SIZE; + exception_page->exception_handler_sp -= sizeof (void *); + * (void **) exception_page->exception_handler_sp = thread->exception_area_va; + + exception_page->exception_handler_ip = (uintptr_t) &exception_handler_entry; + exception_page->exception_handler_end = (uintptr_t) &exception_handler_end; + + return 0; +} diff --git a/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c b/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c new file mode 100644 index 0000000..37ef821 --- /dev/null +++ b/sysdeps/l4/hurd/ia32/signal-dispatch-lowlevel.c @@ -0,0 +1,213 @@ +/* signal-dispatch-lowlevel.c - ia32 specific signal handling functions. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pt-internal.h> +#include <sig-internal.h> + +#include <hurd/thread.h> +#include <pthread.h> +#include <stdint.h> +#include <atomic.h> + +extern char _signal_dispatch_entry; +/* - 0(%esp) a pointer to the thread's struct signal_state. + - 4(%esp) a pointer to a siginfo_t. + - 8(%esp) is a pointer to the ss_flags field (or NULL). + - 12(%esp)+4 is the value of the sp when the thread was interrupted (intr_sp) + - 0(intr_sp) is the value of the ip when the thread was interrupted. + - 16(%esp) - 16 byte register save area +*/ +__asm__ ("\n\ + .globl _signal_dispatch_entry\n\ +_signal_dispatch_entry:\n\ + /* Save caller saved registers (16 bytes). */\n\ + mov %eax, 16(%esp)\n\ + mov %ecx, 16+4(%esp)\n\ + mov %edx, 16+8(%esp)\n\ + pushf\n\ + popl %eax\n\ + mov %eax, 16+12(%esp)\n\ +\n\ + /* Reset EFLAGS. */\n\ + cld\n\ + call signal_dispatch\n\ +\n\ + /* Get the original stack and begin restoration. */\n\ + mov 12(%esp), %edx\n\ +\n\ + /* Move the saved registers to the user stack. */\n\ + sub $16, %edx\n\ + /* eax. */\n\ + mov 16+0(%esp), %ecx\n\ + mov %ecx, 0(%edx)\n\ + /* ecx. */\n\ + mov 16+4(%esp), %ecx\n\ + mov %ecx, 4(%edx)\n\ + /* edx. */\n\ + mov 16+8(%esp), %ecx\n\ + mov %ecx, 8(%edx)\n\ + /* eflags. */\n\ + mov 16+12(%esp), %ecx\n\ + mov %ecx, 12(%edx)\n\ +\n\ + /* Get the pointer to the sigaltstack flags. */\n\ + mov 8(%esp), %ecx\n\ +\n\ + /* Restore the user stack. */\n\ + mov %edx, %esp\n\ +\n\ + /* Clear the SA_ONSTACK flag. */\n\ + and %ecx, %ecx\n\ + jz after_clear\n\ + lock; and $~1, 0(%ecx)\n\ +after_clear:\n\ +\n\ + /* Restore eflags, the scratch regs and the original sp and ip. */\n\ + popl %eax\n\ + popl %ecx\n\ + popl %edx\n\ + popf\n\ + ret\n"); + +extern char _signal_dispatch_entry_self; +/* - 0(%esp) is the return address (we ignore it) + - 4(%esp) is the sp to load + + Since we are returning to signal_dispatch_lowlevel's caller, we + also need to restore its frame pointer. */ +__asm__ ("\n\ + .globl _signal_dispatch_entry_self\n\ +_signal_dispatch_entry_self:\n\ + mov 0(%ebp), %ebp\n\ + mov 4(%esp), %esp\n\ + jmp _signal_dispatch_entry\n"); + +void +signal_dispatch_lowlevel (struct signal_state *ss, pthread_t tid, + siginfo_t si) +{ + assert (pthread_mutex_trylock (&ss->lock) == EBUSY); + + struct __pthread *thread = __pthread_getid (tid); + + bool self = tid == pthread_self (); + + uintptr_t intr_sp; + + if (self) + { + /* The return address is just before the first argument. */ + intr_sp = (uintptr_t) &ss - 4; + assert (* (void **) intr_sp == __builtin_return_address (0)); + } + else + { + struct hurd_thread_exregs_in in; + memset (&in, 0, sizeof (in)); + struct hurd_thread_exregs_out out; + + error_t err; + err = rm_thread_exregs (ADDR_VOID, thread->object, + HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC + | HURD_EXREGS_GET_REGS, + in, &out); + if (err) + panic ("Failed to modify thread " ADDR_FMT, + ADDR_PRINTF (thread->object)); + + intr_sp = out.sp; + + /* Push the ip on the user stack. */ + intr_sp -= 4; + * (uintptr_t *) intr_sp = out.ip; + } + + bool altstack = false; + uintptr_t sp; + if (! (ss->actions[si.si_signo - 1].sa_flags & SA_ONSTACK) + || (ss->stack.ss_flags & SS_DISABLE) + || (ss->stack.ss_flags & SS_ONSTACK)) + { + assert (! self); + sp = intr_sp; + } + else + { + /* The stack grows down. */ + sp = (uintptr_t) ss->stack.ss_sp + ss->stack.ss_size; + + /* We know intimately that SS_ONSTACK is the least significant + bit. */ + assert (SS_ONSTACK == 1); + atomic_bit_set (&ss->stack.ss_flags, 0); + + altstack = true; + } + + /* Set up the call frame for a call to signal_dispatch_entry. */ + + /* Allocate a siginfo structure on the stack. */ + sp = sp - sizeof (siginfo_t); + siginfo_t *sip = (void *) sp; + /* Copy the user supplied values. */ + *sip = si; + + /* Add space for the 4 caller saved registers. */ + sp -= 4 * sizeof (uintptr_t); + + /* Save the interrupted sp. */ + sp -= 4; + * (uintptr_t *) sp = intr_sp; + + /* Address of the ss_flags. */ + sp -= 4; + if (altstack) + * (uintptr_t *) sp = (uintptr_t) &ss->stack.ss_flags; + else + * (uintptr_t *) sp = 0; + + /* Push the parameters to signal_dispatch. */ + + /* signal info structure. */ + sp -= 4; + * (uintptr_t *) sp = (uintptr_t) sip; + + /* The ss. */ + sp -= 4; + * (uintptr_t *) sp = (uintptr_t) ss; + + pthread_mutex_transfer_np (&ss->lock, tid); + + if (self) + ((void (*) (uintptr_t)) &_signal_dispatch_entry_self) ((uintptr_t) sp); + else + { + struct hurd_thread_exregs_in in; + struct hurd_thread_exregs_out out; + + in.sp = sp; + in.ip = (uintptr_t) &_signal_dispatch_entry; + + rm_thread_exregs (ADDR_VOID, thread->object, + HURD_EXREGS_SET_SP_IP + | HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC, + in, &out); + } +} diff --git a/sysdeps/l4/hurd/powerpc/pt-machdep.c b/sysdeps/l4/hurd/powerpc/pt-machdep.c new file mode 100644 index 0000000..754d203 --- /dev/null +++ b/sysdeps/l4/hurd/powerpc/pt-machdep.c @@ -0,0 +1,20 @@ +/* Machine dependent pthreads code. Hurd/PowerPC version. + Copyright (C) 2003 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. */ + +/* Nothing to do. */ diff --git a/sysdeps/l4/hurd/i386/pt-setup.c b/sysdeps/l4/hurd/powerpc/pt-setup.c index fe77d53..d3cf4ec 100644 --- a/sysdeps/l4/hurd/i386/pt-setup.c +++ b/sysdeps/l4/hurd/powerpc/pt-setup.c @@ -1,5 +1,5 @@ -/* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. +/* Setup thread stack. Hurd/PowerPC version. + Copyright (C) 2003 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 @@ -17,19 +17,33 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <l4/l4.h> +#include <l4.h> #include <pt-internal.h> -/* The stack layout used on the i386 is: +/* Arguments is passed in registers on the PowerPC. But the + exchange registers syscall only allows us to set the PC and the + stack pointer so we put the entry point and start function on + the stack. */ +struct start_info +{ + void (*entry_point) (void *(*)(void *), void *); + void *(*start_routine) (void *); + void *arg; +}; + +void first_entry_1 (void); - ----------------- - | ARG | - ----------------- - | START_ROUTINE | - ----------------- - | 0 | - ----------------- */ +/* Stage 1 entry function. The start_info structure is inlined on the + stack. Put values into registers and call entry function. */ +asm (" ;\ +first_entry_1: ;\ + lwz 0, 0(1) ;\ + lwz 3, 4(1) ;\ + lwz 4, 8(1) ;\ + mtctr 0 ;\ + bctrl ;\ +"); /* Set up the stack for THREAD, such that it appears as if START_ROUTINE and ARG were passed to the new thread's entry-point. @@ -37,21 +51,27 @@ opportunity to install THREAD in our utcb. */ static void * stack_setup (struct __pthread *thread, + void (*entry_point)(void *(*)(void *), void *), void *(*start_routine)(void *), void *arg) { - L4_Word_t *top; + l4_word_t *top; /* Calculate top of the new stack. */ - top = (L4_Word_t *) ((L4_Word_t) thread->stackaddr + thread->stacksize); + top = (l4_word_t *) ((l4_word_t) thread->stackaddr + thread->stacksize); + + /* Initial stack frame. */ + top[-4] = 0; + top = top - 4; if (start_routine) { - /* Set up call frame. */ - *--top = (L4_Word_t) arg; /* Argument to START_ROUTINE. */ - *--top = (L4_Word_t) start_routine; - *--top = 0; /* Fake return address. */ - } + struct start_info *info = ((struct start_info *) top) - 1; + info->entry_point = entry_point; + info->start_routine = start_routine; + info->arg = arg; + return (void *) info; + } return top; } @@ -60,13 +80,14 @@ __pthread_setup (struct __pthread *thread, void (*entry_point)(void *(*)(void *), void *), void *(*start_routine)(void *), void *arg) { - thread->mcontext.pc = entry_point; - thread->mcontext.sp = stack_setup (thread, start_routine, arg); + thread->mcontext.pc = first_entry_1; + thread->mcontext.sp = stack_setup (thread, entry_point, + start_routine, arg); - if (L4_SameThreads (thread->threadid, L4_Myself ())) - L4_Set_MyUserDefinedHandle (thread); + if (l4_same_threads (thread->threadid, l4_myself ())) + l4_set_user_defined_handle ((l4_word_t) thread); else - L4_Set_UserDefinedHandle (thread->threadid, thread); - + l4_set_user_defined_handle_of (thread->threadid, + (l4_word_t) thread); return 0; } diff --git a/sysdeps/l4/hurd/pt-block.c b/sysdeps/l4/hurd/pt-block.c new file mode 100644 index 0000000..2315b1c --- /dev/null +++ b/sysdeps/l4/hurd/pt-block.c @@ -0,0 +1,30 @@ +/* Block a thread. Viengoos version. + Copyright (C) 2008 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 <pt-internal.h> + +#include <hurd/stddef.h> +#include <hurd/futex.h> + +/* Block THREAD. */ +void +__pthread_block (struct __pthread *thread) +{ + futex_wait (&thread->threadid, thread->threadid); +} diff --git a/sysdeps/l4/hurd/pt-kill.c b/sysdeps/l4/hurd/pt-kill.c new file mode 100644 index 0000000..c72e82f --- /dev/null +++ b/sysdeps/l4/hurd/pt-kill.c @@ -0,0 +1,3 @@ +/* The generic version is good enough for us, however, the generic + Hurd on Mach version supplies a specialized version */ +#include "../generic/pt-kill.c" diff --git a/sysdeps/l4/hurd/pt-setactivity-np.c b/sysdeps/l4/hurd/pt-setactivity-np.c new file mode 100644 index 0000000..f2f0723 --- /dev/null +++ b/sysdeps/l4/hurd/pt-setactivity-np.c @@ -0,0 +1,39 @@ +/* Set a thread's activity activity. Viengoos version. + Copyright (C) 2008 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 <pt-internal.h> + +#include <hurd/addr.h> +#include <hurd/thread.h> + +int +pthread_setactivity_np (addr_t activity) +{ + struct __pthread *self = _pthread_self (); + + struct hurd_thread_exregs_in in; + in.activity = activity; + + struct hurd_thread_exregs_out out; + int err = rm_thread_exregs (ADDR_VOID, self->object, + HURD_EXREGS_SET_ACTIVITY, + in, &out); + + return err; +} diff --git a/sysdeps/generic/bits/thread-barrier.h b/sysdeps/l4/hurd/pt-sigstate-destroy.c index 23d51ae..997a036 100644 --- a/sysdeps/generic/bits/thread-barrier.h +++ b/sysdeps/l4/hurd/pt-sigstate-destroy.c @@ -1,4 +1,4 @@ -/* Thread barrier attribute type. Generic version. +/* Destroy the signal state. Hurd on L4 version. Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,14 +17,12 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef _BITS_THREAD_BARRIER_H -#define _BITS_THREAD_BARRIER_H 1 +#include <pthread.h> -/* This structure describes the attributes of a POSIX thread barrier. - Note that not all of them are supported on all systems. */ -struct __pthread_attr -{ - enum __ -}; +#include <pt-internal.h> -#endif /* bits/thread-barrier.h */ +void +__pthread_sigstate_destroy (struct __pthread *thread) +{ + /* Nothing to do. */ +} diff --git a/sysdeps/l4/hurd/pt-sigstate-init.c b/sysdeps/l4/hurd/pt-sigstate-init.c new file mode 100644 index 0000000..4c40fdb --- /dev/null +++ b/sysdeps/l4/hurd/pt-sigstate-init.c @@ -0,0 +1,44 @@ +/* Initialize the signal state. Hurd on L4 version. + Copyright (C) 2003, 2008 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 <pthread.h> + +#include <pt-internal.h> +#include <sig-internal.h> + +error_t +__pthread_sigstate_init (struct __pthread *thread) +{ + struct signal_state *ss = &thread->ss; + + memset (ss, 0, sizeof (*ss)); + + ss->stack.ss_flags = SS_DISABLE; + + int signo; + for (signo = 1; signo < NSIG; ++signo) + { + sigemptyset (&ss->actions[signo - 1].sa_mask); + ss->actions[signo - 1].sa_flags = SA_RESTART; + ss->actions[signo - 1].sa_handler = SIG_DFL; + ss->lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; + } + + return 0; +} diff --git a/sysdeps/l4/hurd/pt-sigstate.c b/sysdeps/l4/hurd/pt-sigstate.c new file mode 100644 index 0000000..66dd08c --- /dev/null +++ b/sysdeps/l4/hurd/pt-sigstate.c @@ -0,0 +1,81 @@ +/* Set a thread's signal state. Hurd on L4 version. + Copyright (C) 2002, 2005, 2008 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 <pthread.h> +#include <assert.h> +#include <signal.h> + +#include <pt-internal.h> + +error_t +__pthread_sigstate (struct __pthread *thread, int how, + const sigset_t *set, sigset_t *oset, + int clear_pending) +{ + struct signal_state *ss = &thread->ss; + pthread_mutex_lock (&ss->lock); + + if (oset) + *oset = ss->blocked; + + if (set) + { + /* Mask out SIGKILL and SIGSTOP. */ + sigset_t s = *set; + sigdelset (&s, SIGKILL); + sigdelset (&s, SIGSTOP); + + switch (how) + { + case SIG_BLOCK: + ss->blocked |= s; + break; + case SIG_UNBLOCK: + ss->blocked &= ~s; + break; + case SIG_SETMASK: + ss->blocked = s; + break; + default: + errno = EINVAL; + pthread_mutex_unlock (&ss->lock); + return -1; + } + } + + if (clear_pending) + sigemptyset (&ss->pending); + + /* A "signal shall remain pending until it is unblocked" (2.4.1). + + "If there are any pending unblocked signals after the call to + sigprocmask(), at least one of those signals shall be delivered + before the call to sigprocmask() returns." + (pthread_sigmask). */ + sigset_t extant = ~ss->blocked & ss->pending; + if (! extant) + extant = ~ss->blocked & process_pending; + + pthread_mutex_unlock (&ss->lock); + + if (extant) + raise (l4_lsb64 (extant)); + + return 0; +} diff --git a/sysdeps/l4/hurd/pt-startup.c b/sysdeps/l4/hurd/pt-startup.c new file mode 100644 index 0000000..b6461de --- /dev/null +++ b/sysdeps/l4/hurd/pt-startup.c @@ -0,0 +1,30 @@ +/* Thread initialization. Hurd/L4 version. + Copyright (C) 2007 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 <l4.h> +#include <pt-internal.h> + +#include <hurd/exceptions.h> + +void +__pthread_startup (void) +{ + struct __pthread *pthread = _pthread_self (); + pthread->threadid = l4_myself (); +} diff --git a/sysdeps/l4/hurd/pt-sysdep.c b/sysdeps/l4/hurd/pt-sysdep.c index 265592c..c23364c 100644 --- a/sysdeps/l4/hurd/pt-sysdep.c +++ b/sysdeps/l4/hurd/pt-sysdep.c @@ -1,5 +1,5 @@ /* System dependent pthreads code. Hurd version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2008 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 @@ -23,36 +23,39 @@ #include <pt-internal.h> +int +sched_yield (void) +{ + l4_yield (); + return 0; +} + /* Forward. */ -static void *init_routine (void); +static void init_routine (void (*) (void *), void *) + __attribute__ ((noreturn)); /* OK, the name of this variable isn't really appropriate, but I don't want to change it yet. */ -void *(*_pthread_init_routine)(void) = &init_routine; +void (*_pthread_init_routine)(void (*) (void *), void *) = &init_routine; /* This function is called from the Hurd-specific startup code. It should return a new stack pointer for the main thread. The caller will switch to this new stack before doing anything serious. */ -static void * -init_routine (void) +static void +init_routine (void (*entry) (void *), void *arg) { - struct __pthread *thread; - int err; - /* Initialize the library. */ __pthread_initialize (); + struct __pthread *thread; + int err; + /* Create the pthread structure for the main thread (i.e. us). */ - err = __pthread_create_internal (&thread, 0, 0, 0); + err = __pthread_create_internal (&thread, 0, + (void *(*)(void *)) entry, arg); assert_perror (err); - __pthread_initialize (); - - /* Decrease the number of threads, to take into account that the - signal thread (which will be created by the startup code when we - return from here) shouldn't be seen as a user thread. */ -#warning Need to implement the signal thread. - // __pthread_total--; - - return (void *) thread->mcontext.sp; + /* Switch stacks. */ + l4_start_sp_ip (l4_myself (), thread->mcontext.sp, + thread->mcontext.pc); } diff --git a/sysdeps/l4/hurd/pt-sysdep.h b/sysdeps/l4/hurd/pt-sysdep.h index 8717533..08bcd14 100644 --- a/sysdeps/l4/hurd/pt-sysdep.h +++ b/sysdeps/l4/hurd/pt-sysdep.h @@ -1,5 +1,5 @@ -/* Internal defenitions for pthreads library. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. +/* Internal definitions for pthreads library. + Copyright (C) 2000, 2002, 2005, 2007, 2008 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 @@ -20,33 +20,42 @@ #ifndef _PT_SYSDEP_H #define _PT_SYSDEP_H 1 -#include <l4/l4.h> -#include <task_client.h> -#include <machine/vmparam.h> +#include <l4.h> +#include <hurd/storage.h> +#include <sys/mman.h> /* XXX */ #define _POSIX_THREAD_THREADS_MAX 64 -/* The default stack size. */ -#define PTHREAD_STACK_DEFAULT (PAGE_SIZE) +/* The default stack size: 2MB. */ +#define PTHREAD_STACK_DEFAULT (2 * 1024 * 1024) + +#include <hurd/exceptions.h> + +#define EXCEPTION_AREA_SIZE EXCEPTION_STACK_SIZE +#define EXCEPTION_AREA_SIZE_LOG2 EXCEPTION_STACK_SIZE_LOG2 +/* The exception page is the first object. */ +#define EXCEPTION_PAGE 0 #define PTHREAD_SYSDEP_MEMBERS \ - L4_ThreadId_t threadid; \ - L4_Word_t my_errno; + addr_t object; \ + l4_thread_id_t threadid; \ + addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE]; \ + void *exception_area_va; \ + l4_word_t my_errno; extern inline struct __pthread * __attribute__((__always_inline__)) _pthread_self (void) { - return (struct __pthread *) L4_MyUserDefinedHandle (); + return (struct __pthread *) l4_user_defined_handle (); } extern inline void -__pthread_stack_dealloc (void *stackaddr, size_t stacksize) __attribute__((__always_inline__)) +__pthread_stack_dealloc (void *stackaddr, size_t stacksize) { - /* XXX: can only implement this once we have a working memory manager. */ - return; + munmap (stackaddr, stacksize); } #endif /* pt-sysdep.h */ diff --git a/sysdeps/l4/hurd/pt-thread-alloc.c b/sysdeps/l4/hurd/pt-thread-alloc.c new file mode 100644 index 0000000..ada7b3b --- /dev/null +++ b/sysdeps/l4/hurd/pt-thread-alloc.c @@ -0,0 +1,95 @@ +/* Allocate kernel thread. Viengoos version. + Copyright (C) 2007, 2008 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 <assert.h> +#include <errno.h> +#include <string.h> + +#include <hurd/startup.h> +#include <hurd/storage.h> +#include <hurd/as.h> +#include <hurd/addr.h> + +#include <pt-internal.h> + +extern struct hurd_startup_data *__hurd_startup_data; + +extern addr_t meta_data_activity; + +int +__pthread_thread_alloc (struct __pthread *thread) +{ + /* The main thread is already running of course. */ + if (__pthread_num_threads == 1) + { + thread->object = __hurd_startup_data->thread; + thread->threadid = l4_myself (); + return 0; + } + else + { + addr_t exception_area = as_alloc (EXCEPTION_AREA_SIZE_LOG2, 1, true); + + thread->exception_area_va + = ADDR_TO_PTR (addr_extend (exception_area, + 0, EXCEPTION_AREA_SIZE_LOG2)); + + int i; + for (i = 0; i < EXCEPTION_AREA_SIZE / PAGESIZE; i ++) + { + addr_t slot = addr_chop (PTR_TO_ADDR (thread->exception_area_va + + i * PAGESIZE), + PAGESIZE_LOG2); + as_ensure (slot); + + struct storage storage = storage_alloc (ADDR_VOID, cap_page, + STORAGE_LONG_LIVED, + OBJECT_POLICY_DEFAULT, + slot); + if (ADDR_IS_VOID (storage.addr)) + { + int j; + for (j = 0; j < i; j ++) + storage_free (thread->exception_area[j], false); + as_free (exception_area, false); + return EAGAIN; + } + + thread->exception_area[i] = storage.addr; + } + + struct storage storage; + storage = storage_alloc (meta_data_activity, cap_thread, + /* Threads are rarely shortly lived. */ + STORAGE_MEDIUM_LIVED, OBJECT_POLICY_DEFAULT, + ADDR_VOID); + if (ADDR_IS_VOID (storage.addr)) + { + int j; + for (j = 0; j < EXCEPTION_AREA_SIZE / PAGESIZE; j ++) + storage_free (thread->exception_area[j], false); + as_free (exception_area, false); + return EAGAIN; + } + + thread->object = storage.addr; + } + + return 0; +} diff --git a/sysdeps/l4/hurd/pt-thread-halt.c b/sysdeps/l4/hurd/pt-thread-halt.c new file mode 100644 index 0000000..98fefaa --- /dev/null +++ b/sysdeps/l4/hurd/pt-thread-halt.c @@ -0,0 +1,104 @@ +/* Deallocate the kernel thread resources. Viengoos version. + Copyright (C) 2007, 2008 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 <assert.h> +#include <errno.h> + +#include <pt-internal.h> + +#include <hurd/exceptions.h> +#include <hurd/mutex.h> +#include <hurd/as.h> +#include <hurd/addr.h> + +/* If we try to deallocate our self, we will end up causing a + deadlock. Thus, when a thread tries to free itself, we add it + here. The next thread to free a thread will free it. */ +ss_mutex_t saved_object_lock; +static addr_t saved_object; + +void +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) +{ + /* We may deallocate THREAD. First save any data we need. */ + + addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE]; + memcpy (exception_area, thread->exception_area, + sizeof (thread->exception_area)); + memset (thread->exception_area, 0, sizeof (thread->exception_area)); + + void *va = thread->exception_area_va; + + addr_t object = thread->object; + l4_thread_id_t tid = thread->threadid; + + if (need_dealloc) + __pthread_dealloc (thread); + + /* The THREAD data structure is no longer valid. */ + thread = NULL; + + /* Deallocate any saved object. */ + ss_mutex_lock (&saved_object_lock); + if (! ADDR_IS_VOID (saved_object)) + { + storage_free (saved_object, false); + saved_object = ADDR_VOID; + } + ss_mutex_unlock (&saved_object_lock); + + /* Free the exception area. */ + + /* Clean up the exception page. */ + exception_page_cleanup + (ADDR_TO_PTR (addr_extend (exception_area[EXCEPTION_PAGE], + 0, PAGESIZE_LOG2))); + + /* Free the storage. */ + int i; + for (i = 0; i < EXCEPTION_AREA_SIZE / PAGESIZE; i ++) + { + assert (! ADDR_IS_VOID (exception_area[i])); + storage_free (exception_area[i], false); + } + + /* And the address space. */ + as_free (addr_chop (PTR_TO_ADDR (va), EXCEPTION_AREA_SIZE_LOG2), false); + + if (tid == l4_myself ()) + /* If we try to storage_free (storage.addr), we will freeze in the + middle. That's no good. We set SAVED_OBJECT to our thread + object and the next thread in will free us. */ + { + ss_mutex_lock (&saved_object_lock); + saved_object = object; + ss_mutex_unlock (&saved_object_lock); + } + else + storage_free (object, false); + + if (tid == l4_myself ()) + { + l4_send_timeout (l4_myself (), L4_NEVER); + panic ("Failed to stop thread %x.%x!", + l4_thread_no (l4_myself ()), l4_version (l4_myself ())); + } + else + thread_stop (object); +} diff --git a/sysdeps/l4/hurd/pt-thread-start.c b/sysdeps/l4/hurd/pt-thread-start.c new file mode 100644 index 0000000..9db399c --- /dev/null +++ b/sysdeps/l4/hurd/pt-thread-start.c @@ -0,0 +1,70 @@ +/* Start thread. L4 version. + Copyright (C) 2007 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 <assert.h> +#include <errno.h> +#include <string.h> +#include <hurd/thread.h> +#include <hurd/exceptions.h> + +#include <pt-internal.h> + +int +__pthread_thread_start (struct __pthread *thread) +{ + error_t err; + + if (__pthread_num_threads == 1) + /* The main thread is already running of course. */ + { + assert (__pthread_total == 1); + assert (l4_is_thread_equal (l4_myself (), thread->threadid)); + l4_set_user_defined_handle ((l4_word_t) thread); + } + else + { + struct hurd_thread_exregs_in in; + struct hurd_thread_exregs_out out; + + in.aspace = ADDR (0, 0); + in.aspace_cap_properties = CAP_PROPERTIES_VOID; + in.aspace_cap_properties_flags = CAP_COPY_COPY_SOURCE_GUARD; + + in.activity = ADDR_VOID; + + in.exception_page = addr_chop (PTR_TO_ADDR (thread->exception_area_va), + PAGESIZE_LOG2); + + in.sp = (l4_word_t) thread->mcontext.sp; + in.ip = (l4_word_t) thread->mcontext.pc; + + in.user_handle = (l4_word_t) thread; + err = rm_thread_exregs (ADDR_VOID, thread->object, + HURD_EXREGS_SET_ASPACE + | HURD_EXREGS_SET_ACTIVITY + | HURD_EXREGS_SET_EXCEPTION_PAGE + | HURD_EXREGS_SET_SP_IP + | HURD_EXREGS_SET_USER_HANDLE + | HURD_EXREGS_START + | HURD_EXREGS_ABORT_IPC, + in, &out); + assert (err == 0); + } + return 0; +} diff --git a/sysdeps/l4/hurd/pt-wakeup.c b/sysdeps/l4/hurd/pt-wakeup.c new file mode 100644 index 0000000..e568a6f --- /dev/null +++ b/sysdeps/l4/hurd/pt-wakeup.c @@ -0,0 +1,46 @@ +/* Wakeup a thread. Viengoos version. + Copyright (C) 2008 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 <pt-internal.h> + +#include <hurd/stddef.h> +#include <hurd/futex.h> +#include <stdint.h> + +/* Wakeup THREAD. */ +void +__pthread_wakeup (struct __pthread *thread) +{ + /* We need to loop here as the blocked thread may not yet be + blocked! Here's what happens when a thread blocks: it registers + itself as blocked, drops the relevant lock and then actually + blocks (via __pthread_block). This means that after dropping the + lock and before blocking, it may be interrupted and another + thread may try to wake it. */ + long ret; + do + { + ret = futex_wake (&thread->threadid, INT_MAX); + assertx (ret <= 1, "tid: %x, ret: %d", thread->threadid, ret); + + if (ret == 0) + l4_thread_switch (thread->threadid); + } + while (ret == 0); +} diff --git a/sysdeps/l4/hurd/sig-sysdep.h b/sysdeps/l4/hurd/sig-sysdep.h new file mode 100644 index 0000000..33e1385 --- /dev/null +++ b/sysdeps/l4/hurd/sig-sysdep.h @@ -0,0 +1,69 @@ +/* sig-sysdep.h - Hurd system specific header file. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <l4.h> +#include <string.h> + +struct utcb +{ + l4_word_t saved_sender; + l4_word_t saved_receiver; + l4_word_t saved_timeout; + l4_word_t saved_error_code; + l4_word_t saved_flags; + l4_word_t saved_br0; + l4_msg_t saved_message; +}; + +static inline void +utcb_state_save (struct utcb *buffer) +{ + l4_word_t *utcb = _L4_utcb (); + + buffer->saved_sender = utcb[_L4_UTCB_SENDER]; + buffer->saved_receiver = utcb[_L4_UTCB_RECEIVER]; + buffer->saved_timeout = utcb[_L4_UTCB_TIMEOUT]; + buffer->saved_error_code = utcb[_L4_UTCB_ERROR_CODE]; + buffer->saved_flags = utcb[_L4_UTCB_FLAGS]; + buffer->saved_br0 = utcb[_L4_UTCB_BR0]; + memcpy (&buffer->saved_message, + utcb, L4_NUM_MRS * sizeof (l4_word_t)); +} + +static inline void +utcb_state_restore (struct utcb *buffer) +{ + l4_word_t *utcb = _L4_utcb (); + + utcb[_L4_UTCB_SENDER] = buffer->saved_sender; + utcb[_L4_UTCB_RECEIVER] = buffer->saved_receiver; + utcb[_L4_UTCB_TIMEOUT] = buffer->saved_timeout; + utcb[_L4_UTCB_ERROR_CODE] = buffer->saved_error_code; + utcb[_L4_UTCB_FLAGS] = buffer->saved_flags; + utcb[_L4_UTCB_BR0] = buffer->saved_br0; + memcpy (utcb, &buffer->saved_message, + L4_NUM_MRS * sizeof (l4_word_t)); +} + +#define SIGNAL_DISPATCH_ENTRY \ + struct utcb buffer; utcb_state_save (&buffer); + +#define SIGNAL_DISPATCH_EXIT \ + utcb_state_restore (&buffer); diff --git a/sysdeps/l4/hurd/sigprocmask.c b/sysdeps/l4/hurd/sigprocmask.c new file mode 100644 index 0000000..a38b379 --- /dev/null +++ b/sysdeps/l4/hurd/sigprocmask.c @@ -0,0 +1,41 @@ +/* sigprocmask.c - Generic sigprocmask implementation. + Copyright (C) 2008 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pt-internal.h> +#include <sig-internal.h> + +int +sigprocmask (int how, const sigset_t *restrict set, sigset_t *restrict old) +{ + struct __pthread *thread = _pthread_self (); + if (! thread) + /* Library is initializing. */ + { + assert (__pthread_num_threads == 1); + + /* We should get the default mask from the startup data structure. */ + if (old) + *old = 0; + + return 0; + } + + return pthread_sigmask (how, set, old); +} diff --git a/sysdeps/l4/pt-block.c b/sysdeps/l4/pt-block.c index 050c694..69e1d35 100644 --- a/sysdeps/l4/pt-block.c +++ b/sysdeps/l4/pt-block.c @@ -17,13 +17,31 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <l4/l4.h> +#include <l4.h> #include <pt-internal.h> +#include <hurd/stddef.h> + /* Block THREAD. */ void __pthread_block (struct __pthread *thread) { - L4_Receive (L4_anylocalthread); + debug (5, "%x.%x/%x blocking", + l4_thread_no (thread->threadid), l4_version (thread->threadid), + thread->threadid); + + l4_accept (L4_UNTYPED_WORDS_ACCEPTOR); + l4_msg_tag_t tag = l4_receive (l4_anythread); + if (l4_ipc_failed (tag)) + { + debug (1, "%x.%x failed to block: %d, offset: %x", + l4_thread_no (l4_myself ()), l4_version (l4_myself ()), + (l4_error_code () >> 1) & 0x7, + l4_error_code () >> 4); + assert (! l4_ipc_failed (tag)); + } + else + debug (5, "%x.%x unblocked", + l4_thread_no (thread->threadid), l4_version (thread->threadid)); } diff --git a/sysdeps/l4/pt-docancel.c b/sysdeps/l4/pt-docancel.c index 9a3bb26..a3965d0 100644 --- a/sysdeps/l4/pt-docancel.c +++ b/sysdeps/l4/pt-docancel.c @@ -1,5 +1,5 @@ /* Cancel a thread. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2007 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 @@ -30,22 +30,13 @@ call_exit (void) int __pthread_do_cancel (struct __pthread *p) { - assert (p->cancel_pending = 1); + assert (p->cancel_pending == 1); assert (p->cancel_state == PTHREAD_CANCEL_ENABLE); - if (L4_SameThreads (L4_Myself (), p->threadid)) + if (l4_is_thread_equal (l4_myself (), p->threadid)) call_exit (); else - { - L4_Word_t dummy; - L4_ThreadId_t dummy_id; - - /* Change the ip of the target thread to make it exit. */ - L4_ExchangeRegisters (p->threadid, (1 << 4), 0, call_exit, - 0, 0, L4_nilthread, - &dummy, &dummy, &dummy, &dummy, &dummy, - &dummy_id); - } - + l4_start_sp_ip (p->threadid, (l4_word_t) p->mcontext.sp, + (l4_word_t) call_exit); return 0; } diff --git a/sysdeps/l4/pt-pool-np.c b/sysdeps/l4/pt-pool-np.c new file mode 100644 index 0000000..e83022b --- /dev/null +++ b/sysdeps/l4/pt-pool-np.c @@ -0,0 +1,54 @@ +/* Thread pool for L4 threads. + Copyright (C) 2004, 2007 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 <pt-internal.h> +#include <l4/thread.h> + +static pthread_mutex_t pool_lock = PTHREAD_MUTEX_INITIALIZER; + +_L4_thread_id_t pool_list = l4_nilthread; + +/* Add the thread TID to the pthread kernel thread pool. */ +int +pthread_pool_add_np (l4_thread_id_t tid) +{ + __pthread_mutex_lock (&pool_lock); + /* FIXME: Do error checking. */ + l4_set_user_defined_handle_of (tid, pool_list); + pool_list = tid; + __pthread_mutex_unlock (&pool_lock); + + return 0; +} + + +/* Get the first thread from the pool. */ +l4_thread_id_t +pthread_pool_get_np (void) +{ + _L4_thread_id_t tid; + + __pthread_mutex_lock (&pool_lock); + /* FIXME: Do error checking. */ + tid = pool_list; + if (tid != l4_nilthread) + pool_list = l4_user_defined_handle_of (tid); + __pthread_mutex_unlock (&pool_lock); + return tid; +} diff --git a/sysdeps/l4/pt-spin.c b/sysdeps/l4/pt-spin.c new file mode 100644 index 0000000..b6978b0 --- /dev/null +++ b/sysdeps/l4/pt-spin.c @@ -0,0 +1,63 @@ +/* Spin locks. L4 version. + Copyright (C) 2000, 2004 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 <l4.h> + +#include <pthread.h> +#include <sched.h> + +/* The default for single processor machines; don't spin, it's + pointless. */ +#ifndef __PTHREAD_SPIN_COUNT +# define __PTHREAD_SPIN_COUNT 1 +#endif + +/* The number of times to spin while trying to lock a spin lock object + before yielding the processor. */ +int __pthread_spin_count = __PTHREAD_SPIN_COUNT; + + +/* Lock the spin lock object LOCK. If the lock is held by another + thread spin until it becomes available. */ +int +_pthread_spin_lock (__pthread_spinlock_t *lock) +{ + l4_time_t timeout; + int i; + + /* Start with a small timeout of 2 microseconds, then back off + exponentially. */ + timeout = l4_time_period (2); + + while (1) + { + for (i = 0; i < __pthread_spin_count; i++) + { + if (__pthread_spin_trylock (lock) == 0) + return 0; + } + l4_sleep (timeout); + + timeout = l4_time_mul2 (timeout); + if (timeout == L4_NEVER) + timeout = L4_TIME_PERIOD_MAX; + } +} + +weak_alias (_pthread_spin_lock, pthread_spin_lock); diff --git a/sysdeps/l4/pt-stack-alloc.c b/sysdeps/l4/pt-stack-alloc.c index e28d531..b7ec12b 100644 --- a/sysdeps/l4/pt-stack-alloc.c +++ b/sysdeps/l4/pt-stack-alloc.c @@ -1,5 +1,5 @@ /* Allocate a new stack. L4 Hurd version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2007 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 @@ -17,41 +17,14 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <l4/l4.h> +#include <l4.h> #include <errno.h> #include <pt-internal.h> -#define __pthread_stacksize __pthread_default_attr.stacksize +#include <sys/mman.h> -#include <l4/sigma0.h> -#include <hurd/debug.h> - -static void * -allocate_page (void) -{ - L4_Fpage_t p; - /* The Kernel Interface page. */ - static L4_KernelInterfacePage_t *kip; - - if (! kip) - kip = L4_GetKernelInterface (); - -#define sigma0_tid() (L4_GlobalId (kip->ThreadInfo.X.UserBase, 1)) - p = L4_Sigma0_GetPage (sigma0_tid (), - L4_Fpage_Set_Attrs (L4_FpageLog2 (-1UL << 10, - PAGE_SHIFT), - L4_FullyAccessible)); - p.raw &= ~0x3ff; - - printf ("%s: Allocated page %x\n", - __FUNCTION__, p.raw); - - return (void *) p.raw; -} - - -/* Allocate a new stack of size STACKSIZE. If successfull, store the +/* Allocate a new stack of size STACKSIZE. If successful, store the address of the newly allocated stack in *STACKADDR and return 0. Otherwise return an error code (EINVAL for an invalid stack size, EAGAIN if the system lacked the necessary resources to allocate a @@ -59,12 +32,12 @@ allocate_page (void) int __pthread_stack_alloc (void **stackaddr, size_t stacksize) { - if (stacksize != __pthread_stacksize) - return EINVAL; - - *stackaddr = allocate_page (); - if (! *stackaddr) + void *buffer = mmap (0, stacksize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (buffer == MAP_FAILED) return EAGAIN; - + + *stackaddr = buffer; + return 0; } diff --git a/sysdeps/l4/pt-start.c b/sysdeps/l4/pt-start.c deleted file mode 100644 index fb4e27b..0000000 --- a/sysdeps/l4/pt-start.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Start thread. L4 Hurd version. - Copyright (C) 2002 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 <assert.h> -#include <errno.h> -#include <string.h> - -#include <pt-internal.h> - -#include "task_client.h" - -extern L4_ThreadId_t __system_pager; -extern L4_ThreadId_t __task_server; - -#ifndef WORKING_EXREGS -static void -send_startup_ipc (L4_ThreadId_t id, L4_Word_t ip, L4_Word_t sp) -{ - L4_Msg_t msg; - - printf ("%s: Sending startup message to %x, " - "(ip=%x, sp=%x)\n", - __FUNCTION__, * (L4_Word_t *) &id, ip, sp); - - L4_Clear (&msg); -#ifdef HAVE_PROPAGATION - L4_Set_VirtualSender (pager_tid); - L4_Set_Propagation (&msg.tag); -#endif - L4_Append_Word (&msg, ip); - L4_Append_Word (&msg, sp); -#ifndef HAVE_PROPAGATION - L4_Append_Word (&msg, *(L4_Word_t *) &id); - id = __system_pager; -#if 0 - DODEBUG (2, printf ("%s: Redirecting start request to pager (%x).\n", - __FUNCTION__, * (L4_Word_t *) &id)); -#endif -#endif - L4_LoadMsg (&msg); - L4_Send (id); -} -#endif - -/* Start THREAD. We allocate all system-specific resources, including - a kernel thread, set it up, and get it running. */ -int -__pthread_start (struct __pthread *thread) -{ - error_t err; - - if (__pthread_num_threads == 1) - /* The main thread is already running: do nothing. */ - { - assert (__pthread_total == 1); - thread->threadid = L4_Myself (); - } - else - { - CORBA_Environment env; - - env = idl4_default_environment; - err = thread_create (__task_server, - L4_Version (L4_Myself ()), - * (L4_Word_t *) &__system_pager, - (L4_Word_t *) &thread->threadid, &env); - if (err) - return EAGAIN; - - env = idl4_default_environment; - err = thread_resume (__task_server, - * (L4_Word_t *) &thread->threadid, - &env); - assert (! err); - -#ifndef WORKING_EXREGS - L4_AbortIpc_and_stop (thread->threadid); - L4_Start_SpIp (thread->threadid, (L4_Word_t) thread->mcontext.sp, - (L4_Word_t) thread->mcontext.pc); -#endif - send_startup_ipc (thread->threadid, (L4_Word_t) thread->mcontext.pc, - (L4_Word_t) thread->mcontext.sp); - - } - - return 0; -} diff --git a/sysdeps/l4/pt-thread-alloc.c b/sysdeps/l4/pt-thread-alloc.c index a9d5e21..ec69afb 100644 --- a/sysdeps/l4/pt-thread-alloc.c +++ b/sysdeps/l4/pt-thread-alloc.c @@ -1,5 +1,5 @@ -/* Start thread. L4 version. - Copyright (C) 2002 Free Software Foundation, Inc. +/* Allocate kernel thread. L4 version. + Copyright (C) 2003, 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 @@ -23,30 +23,21 @@ #include <pt-internal.h> -/* Start THREAD. Get the kernel thread scheduled and running. */ int -__pthread_thread_start (struct __pthread *thread) +__pthread_thread_alloc (struct __pthread *thread) { error_t err; /* The main thread is already running of course. */ if (__pthread_num_threads == 1) - { - assert (__pthread_total == 1); - thread->thread_id = L4_Myself (); - } + thread->threadid = l4_myself (); else { - CORBA_Environment env; - - env = idl4_default_environment; - err = thread_create (__task_server, - L4_Version (L4_Myself ()), - * (L4_Word_t *) &__system_pager, - (L4_Word_t *) &thread->threadid, &env); - if (err) - return EAGAIN; - } + thread->threadid = pthread_pool_get_np (); + if (thread->threadid != l4_nilthread) + return 0; + return EAGAIN; + } return 0; } diff --git a/sysdeps/l4/pt-thread-dealloc.c b/sysdeps/l4/pt-thread-dealloc.c new file mode 100644 index 0000000..c09e486 --- /dev/null +++ b/sysdeps/l4/pt-thread-dealloc.c @@ -0,0 +1,32 @@ +/* Deallocate the kernel thread resources. L4 version. + Copyright (C) 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 + 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 <assert.h> +#include <errno.h> +#include <l4.h> + +#include <pt-internal.h> + +/* Deallocate any kernel resources associated with THREAD except don't + halt the thread itself. On return, the thread will be marked as + dead and __pthread_halt will be called. */ +void +__pthread_thread_dealloc (struct __pthread *thread) +{ +} diff --git a/sysdeps/l4/pt-thread-halt.c b/sysdeps/l4/pt-thread-halt.c index 04d622f..aa2bf43 100644 --- a/sysdeps/l4/pt-thread-halt.c +++ b/sysdeps/l4/pt-thread-halt.c @@ -1,5 +1,5 @@ -/* Deallocate the kernel thread resources. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. +/* Deallocate the kernel thread resources. L4version. + Copyright (C) 2000, 2002, 2004 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 @@ -19,20 +19,27 @@ #include <assert.h> #include <errno.h> -#include <mach.h> #include <pt-internal.h> -extern L4_ThreadId_t __task_server; - /* Deallocate the kernel thread resources associated with THREAD. */ void -__pthread_thread_halt (struct __pthread *thread) +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) { - CORBA_Environment env = idl4_default_environment; - L4_Word_t *t = (L4_Word_t *) &thread->threadid; - - assert (*t); - assert (thread_terminate (__task_server, *t, &env)); - *t = 0; + l4_thread_id_t tid = thread->threadid; + + if (need_dealloc) + __pthread_dealloc (thread); + + /* There is potential race here: once if TID is the current thread, + then once we add TID to the pool, someone can reallocate it + before we call stop. However, to start the thread, the caller + atomically starts and sets the sp and ip, thus, if the stop has + not yet executed at that point, it won't. */ + + if (tid != l4_myself ()) + l4_stop (tid); + pthread_pool_add_np (tid); + if (tid == l4_myself ()) + l4_stop (tid); } diff --git a/sysdeps/l4/pt-thread-start.c b/sysdeps/l4/pt-thread-start.c index c428d29..144c58b 100644 --- a/sysdeps/l4/pt-thread-start.c +++ b/sysdeps/l4/pt-thread-start.c @@ -1,5 +1,5 @@ /* Start thread. L4 version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2007 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 @@ -23,70 +23,18 @@ #include <pt-internal.h> -#include "task_client.h" - -extern L4_ThreadId_t __system_pager; -extern L4_ThreadId_t __task_server; - -#ifndef WORKING_EXREGS -static void -send_startup_ipc (L4_ThreadId_t id, L4_Word_t ip, L4_Word_t sp) -{ - L4_Msg_t msg; - - printf ("%s: Sending startup message to %x, " - "(ip=%x, sp=%x)\n", - __FUNCTION__, * (L4_Word_t *) &id, ip, sp); - - L4_Clear (&msg); -#ifdef HAVE_PROPAGATION - L4_Set_VirtualSender (pager_tid); - L4_Set_Propagation (&msg.tag); -#endif - L4_Append_Word (&msg, ip); - L4_Append_Word (&msg, sp); -#ifndef HAVE_PROPAGATION - L4_Append_Word (&msg, *(L4_Word_t *) &id); - id = __system_pager; -#if 0 - DODEBUG (2, printf ("%s: Redirecting start request to pager (%x).\n", - __FUNCTION__, * (L4_Word_t *) &id)); -#endif -#endif - L4_LoadMsg (&msg); - L4_Send (id); -} -#endif - /* Start THREAD. Get the kernel thread scheduled and running. */ int __pthread_thread_start (struct __pthread *thread) { - error_t err; - - /* The main thread is already running of course. */ if (__pthread_num_threads == 1) + /* The main thread is already running of course. */ { assert (__pthread_total == 1); - assert (thread->thread_id == L4_Myself ()); + assert (l4_is_thread_equal (l4_myself (), thread->threadid)); } else - { - env = idl4_default_environment; - err = thread_resume (__task_server, - * (L4_Word_t *) &thread->threadid, - &env); - assert (! err); - -#ifndef WORKING_EXREGS - L4_AbortIpc_and_stop (thread->threadid); - L4_Start_SpIp (thread->threadid, (L4_Word_t) thread->mcontext.sp, - (L4_Word_t) thread->mcontext.pc); -#endif - send_startup_ipc (thread->threadid, (L4_Word_t) thread->mcontext.pc, - (L4_Word_t) thread->mcontext.sp); - - } - + l4_start_sp_ip (thread->threadid, (l4_word_t) thread->mcontext.sp, + (l4_word_t) thread->mcontext.pc); return 0; } diff --git a/sysdeps/l4/pt-timedblock.c b/sysdeps/l4/pt-timedblock.c new file mode 100644 index 0000000..ce7972b --- /dev/null +++ b/sysdeps/l4/pt-timedblock.c @@ -0,0 +1,35 @@ +/* Block a thread with a timeout. L4 version. + Copyright (C) 2000,02 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 <assert.h> +#include <errno.h> +#include <time.h> +#include <sys/time.h> + +#include <pt-internal.h> + +/* Block THREAD. */ +error_t +__pthread_timedblock (struct __pthread *thread, + const struct timespec *abstime) +{ +#warning Need gettimeofday to implement properly. + __pthread_block (thread); + return 0; +} diff --git a/sysdeps/l4/pt-wakeup.c b/sysdeps/l4/pt-wakeup.c index 7b00e4f..de37846 100644 --- a/sysdeps/l4/pt-wakeup.c +++ b/sysdeps/l4/pt-wakeup.c @@ -17,13 +17,38 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <l4/l4.h> +#include <l4.h> #include <pt-internal.h> +#include <hurd/stddef.h> + /* Wakeup THREAD. */ void __pthread_wakeup (struct __pthread *thread) { - L4_Send (thread->threadid); + debug (5, "%x.%x/%x waking %x.%x/%x", + l4_thread_no (l4_myself ()), l4_version (l4_myself ()), l4_myself (), + l4_thread_no (thread->threadid), l4_version (thread->threadid), + thread->threadid); + + /* Signal the waiter. */ + l4_msg_t msg; + l4_msg_clear (msg); + l4_msg_set_untyped_words (msg, 0); + l4_msg_load (msg); + + l4_msg_tag_t tag = l4_send (thread->threadid); + if (l4_ipc_failed (tag)) + { + int err = l4_error_code (); + debug (1, "%x.%x failed to wake %x.%x: %s (%d)", + l4_thread_no (l4_myself ()), l4_version (l4_myself ()), + l4_thread_no (thread->threadid), l4_version (thread->threadid), + l4_strerror (err), err); + } + else + debug (5, "%x.%x woke %x.%x", + l4_thread_no (l4_myself ()), l4_version (l4_myself ()), + l4_thread_no (thread->threadid), l4_version (thread->threadid)); } diff --git a/sysdeps/mach/bits/spin-lock-inline.h b/sysdeps/mach/bits/spin-lock-inline.h new file mode 100644 index 0000000..f9f7c29 --- /dev/null +++ b/sysdeps/mach/bits/spin-lock-inline.h @@ -0,0 +1,90 @@ +/* Definitions of user-visible names for spin locks. + Copyright (C) 1994, 1997, 2002, 2008, 2009 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _BITS_SPIN_LOCK_INLINE_H +#define _BITS_SPIN_LOCK_INLINE_H 1 + +#include <features.h> +#include <bits/spin-lock.h> +#include <machine-lock.h> /* This does all the work. */ + +__BEGIN_DECLS + +#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES + +# ifndef __EBUSY +# include <errno.h> +# define __EBUSY EBUSY +# endif + +# ifndef __PT_SPIN_INLINE +# define __PT_SPIN_INLINE __extern_inline +# endif + +__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_destroy (__pthread_spinlock_t *__lock) +{ + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, + int __pshared); + +__PT_SPIN_INLINE int +__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared) +{ + *__lock = __PTHREAD_SPIN_LOCK_INITIALIZER; + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_trylock (__pthread_spinlock_t *__lock) +{ + return __spin_try_lock (__lock) ? 0 : __EBUSY; +} + +__extern_inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); +extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); + +__extern_inline int +__pthread_spin_lock (__pthread_spinlock_t *__lock) +{ + if (__pthread_spin_trylock (__lock)) + return _pthread_spin_lock (__lock); + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_unlock (__pthread_spinlock_t *__lock) +{ + __spin_unlock (__lock); + return 0; +} + +#endif /* Use extern inlines or force inlines. */ + +__END_DECLS + +#endif /* bits/spin-lock.h */ diff --git a/sysdeps/mach/bits/spin-lock.h b/sysdeps/mach/bits/spin-lock.h index e137c24..537dac9 100644 --- a/sysdeps/mach/bits/spin-lock.h +++ b/sysdeps/mach/bits/spin-lock.h @@ -1,5 +1,5 @@ /* Definitions of user-visible names for spin locks. - Copyright (C) 1994, 1997, 2002 Free Software Foundation, Inc. + Copyright (C) 1994, 1997, 2002, 2008, 2009 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 @@ -29,69 +29,10 @@ __BEGIN_DECLS typedef __spin_lock_t __pthread_spinlock_t; /* Initializer for a spin lock object. */ -#ifndef __SPIN_LOCK_INITIALIZER -#error __SPIN_LOCK_INITIALIZER undefined: should be defined by <lock-intern.h>. +#ifndef __PTHREAD_SPIN_LOCK_INITIALIZER +#error __PTHREAD_SPIN_LOCK_INITIALIZER undefined: should be defined by <lock-intern.h>. #endif -#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES - -# ifndef __EBUSY -# include <errno.h> -# define __EBUSY EBUSY -# endif - -# ifndef __PT_SPIN_INLINE -# define __PT_SPIN_INLINE extern __inline -# endif - -__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock); - -__PT_SPIN_INLINE int -__pthread_spin_destroy (__pthread_spinlock_t *__lock) -{ - return 0; -} - -__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, - int __pshared); - -__PT_SPIN_INLINE int -__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared) -{ - *__lock = __SPIN_LOCK_INITIALIZER; - return 0; -} - -__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock); - -__PT_SPIN_INLINE int -__pthread_spin_trylock (__pthread_spinlock_t *__lock) -{ - return __spin_try_lock (__lock) ? 0 : __EBUSY; -} - -extern __inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); -extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); - -extern __inline int -__pthread_spin_lock (__pthread_spinlock_t *__lock) -{ - if (__pthread_spin_trylock (__lock)) - return _pthread_spin_lock (__lock); - return 0; -} - -__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock); - -__PT_SPIN_INLINE int -__pthread_spin_unlock (__pthread_spinlock_t *__lock) -{ - __spin_unlock (__lock); - return 0; -} - -#endif /* Use extern inlines or force inlines. */ - __END_DECLS #endif /* bits/spin-lock.h */ diff --git a/sysdeps/mach/hurd/i386/pt-machdep.c b/sysdeps/mach/hurd/ia32/pt-machdep.c index f3c8cf5..f3c8cf5 100644 --- a/sysdeps/mach/hurd/i386/pt-machdep.c +++ b/sysdeps/mach/hurd/ia32/pt-machdep.c diff --git a/sysdeps/mach/hurd/i386/pt-setup.c b/sysdeps/mach/hurd/ia32/pt-setup.c index 020f677..5420dc8 100644 --- a/sysdeps/mach/hurd/i386/pt-setup.c +++ b/sysdeps/mach/hurd/ia32/pt-setup.c @@ -1,5 +1,5 @@ /* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2007, 2008 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,13 +58,15 @@ stack_setup (struct __pthread *thread, top -= __hurd_threadvar_max; /* Save the self pointer. */ - top[_HURD_THREADVAR_THREAD] = (void *) thread; + top[_HURD_THREADVAR_THREAD] = (uintptr_t) thread; if (start_routine) { /* And then the call frame. */ - *--top = (uintptr_t) arg; /* Argument to START_ROUTINE. */ - *--top = (uintptr_t) start_routine; + top -= 2; + top = (uintptr_t *) ((uintptr_t) top & ~0xf); + top[1] = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + top[0] = (uintptr_t) start_routine; *--top = 0; /* Fake return address. */ } diff --git a/sysdeps/mach/hurd/pt-docancel.c b/sysdeps/mach/hurd/pt-docancel.c index 84f04c0..105c6fd 100644 --- a/sysdeps/mach/hurd/pt-docancel.c +++ b/sysdeps/mach/hurd/pt-docancel.c @@ -1,5 +1,5 @@ /* Cancel a thread. - Copyright (C) 2002, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2007, 2008 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 @@ -33,7 +33,7 @@ __pthread_do_cancel (struct __pthread *p) mach_port_t ktid; int me; - assert (p->cancel_pending = 1); + assert (p->cancel_pending == 1); assert (p->cancel_state == PTHREAD_CANCEL_ENABLE); ktid = __mach_thread_self (); diff --git a/sysdeps/mach/hurd/pt-sysdep.h b/sysdeps/mach/hurd/pt-sysdep.h index f652b68..13e235d 100644 --- a/sysdeps/mach/hurd/pt-sysdep.h +++ b/sysdeps/mach/hurd/pt-sysdep.h @@ -1,5 +1,5 @@ /* Internal defenitions for pthreads library. - Copyright (C) 2000, 2002, 2007 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2007, 2008 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 @@ -32,7 +32,8 @@ #define PTHREAD_SYSDEP_MEMBERS \ thread_t kernel_thread; \ - mach_msg_header_t wakeupmsg; + mach_msg_header_t wakeupmsg; \ + int have_kernel_resources; #define _HURD_THREADVAR_THREAD _HURD_THREADVAR_DYNAMIC_USER diff --git a/sysdeps/mach/pt-thread-alloc.c b/sysdeps/mach/pt-thread-alloc.c index 1acba98..3d7c046 100644 --- a/sysdeps/mach/pt-thread-alloc.c +++ b/sysdeps/mach/pt-thread-alloc.c @@ -1,5 +1,5 @@ /* Start thread. Mach version. - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 2008 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 @@ -63,6 +63,9 @@ create_wakeupmsg (struct __pthread *thread) int __pthread_thread_alloc (struct __pthread *thread) { + if (thread->have_kernel_resources) + return 0; + error_t err; err = create_wakeupmsg (thread); @@ -97,5 +100,7 @@ __pthread_thread_alloc (struct __pthread *thread) return EAGAIN; } + thread->have_kernel_resources = 1; + return 0; } diff --git a/sysdeps/mach/pt-thread-halt.c b/sysdeps/mach/pt-thread-halt.c index 9f86024..973cde1 100644 --- a/sysdeps/mach/pt-thread-halt.c +++ b/sysdeps/mach/pt-thread-halt.c @@ -30,14 +30,8 @@ being halted, thus the last action should be halting the thread itself. */ void -__pthread_thread_halt (struct __pthread *thread, int need_dealloc) +__pthread_thread_halt (struct __pthread *thread) { - error_t err; - thread_t tid = thread->kernel_thread; - - if (need_dealloc) - __pthread_dealloc (thread); - - err = __thread_terminate (tid); + error_t err = __thread_terminate (thread->kernel_thread); assert_perror (err); } diff --git a/sysdeps/mach/pt-timedblock.c b/sysdeps/mach/pt-timedblock.c index ddb8bae..6f54726 100644 --- a/sysdeps/mach/pt-timedblock.c +++ b/sysdeps/mach/pt-timedblock.c @@ -51,11 +51,11 @@ __pthread_timedblock (struct __pthread *thread, timeout = (abstime->tv_sec - now.tv_sec) * 1000; if (((abstime->tv_nsec + 999) / 1000) >= now.tv_usec) - timeout -= (((abstime->tv_nsec + 999) / 1000) - now.tv_usec + 999) / 1000; + timeout += (((abstime->tv_nsec + 999) / 1000) - now.tv_usec + 999) / 1000; else /* Need to do a carry. */ - timeout -= 1000 + ((abstime->tv_nsec + 999999) / 1000000) - - (now.tv_usec + 999) / 1000; + timeout -= (now.tv_usec + 999) / 1000 - + ((abstime->tv_nsec + 999999) / 1000000); err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof msg, thread->wakeupmsg.msgh_remote_port, diff --git a/sysdeps/posix/pt-spin.c b/sysdeps/posix/pt-spin.c index 486030d..cb809c6 100644 --- a/sysdeps/posix/pt-spin.c +++ b/sysdeps/posix/pt-spin.c @@ -1,5 +1,5 @@ /* Spin locks. - Copyright (C) 2000, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2004, 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 diff --git a/sysdeps/powerpc/bits/machine-lock.h b/sysdeps/powerpc/bits/machine-lock.h new file mode 100644 index 0000000..cba6b0a --- /dev/null +++ b/sysdeps/powerpc/bits/machine-lock.h @@ -0,0 +1,78 @@ +/* Machine-specific definition for spin locks. PowerPC version. + Copyright (C) 1994,97,2002 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _MACHINE_LOCK_H +#define _MACHINE_LOCK_H + +/* The type of a spin lock variable. */ + +typedef __volatile long int __spin_lock_t; + +/* Value to initialize `__spin_lock_t' variables to. */ + +#define __SPIN_LOCK_INITIALIZER 0L + + +#ifndef _EXTERN_INLINE +#define _EXTERN_INLINE extern __inline +#endif + +/* Unlock LOCK. */ + +_EXTERN_INLINE void +__spin_unlock (__spin_lock_t *__lock) +{ + long int __locked; + __asm__ __volatile__ ("\ +0: lwarx %0,0,%1\n\ + stwcx. %2,0,%1\n\ + bne- 0b\n\ +" : "=&r" (__locked) : "r" (__lock), "r" (0) : "cr0"); +} + +/* Try to lock LOCK; return nonzero if we locked it, zero if another has. */ + +_EXTERN_INLINE int +__spin_try_lock (register __spin_lock_t *__lock) +{ + long int __rtn; + __asm__ __volatile__ ("\ +0: lwarx %0,0,%1\n\ + stwcx. %2,0,%1\n\ + bne- 0b\n\ +" : "=&r" (__rtn) : "r" (__lock), "r" (1) : "cr0"); + return !__rtn; +} + +/* Return nonzero if LOCK is locked. */ + +_EXTERN_INLINE int +__spin_lock_locked (__spin_lock_t *__lock) +{ + long int __rtn; + __asm__ __volatile__ ("\ +0: lwarx %0,0,%1\n\ + stwcx. %0,0,%1\n\ + bne- 0b\n\ +" : "=&r" (__rtn) : "r" (__lock) : "cr0"); + return __rtn; +} + + +#endif /* machine-lock.h */ diff --git a/sysdeps/powerpc/bits/memory.h b/sysdeps/powerpc/bits/memory.h new file mode 100644 index 0000000..96624c3 --- /dev/null +++ b/sysdeps/powerpc/bits/memory.h @@ -0,0 +1,36 @@ +/* Memory barrier operations. PowerPC version. + Copyright (C) 2003 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. */ + +#ifndef _BITS_MEMORY_H +#define _BITS_MEMORY_H 1 + +/* Prevent read and write reordering across this function. */ +inline void +__memory_barrier (void) +{ + asm ("sync" ::: "memory"); +} + +/* Prevent read reordering across this function. */ +#define __memory_read_barrier __memory_barrier + +/* Prevent write reordering across this function. */ +#define __memory_write_barrier __memory_barrier + +#endif diff --git a/sysdeps/powerpc/bits/spin-lock.h b/sysdeps/powerpc/bits/spin-lock.h new file mode 100644 index 0000000..1dc2571 --- /dev/null +++ b/sysdeps/powerpc/bits/spin-lock.h @@ -0,0 +1,108 @@ +/* Machine-specific definitions for spin locks. PowerPC version. + Copyright (C) 2003 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. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_SPIN_LOCK_H +#define _BITS_SPIN_LOCK_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* The type of a spin lock object. */ +typedef __volatile int __pthread_spinlock_t; + +/* Initializer for a spin lock object. */ +# define __SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0) + +#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES + +# ifndef __EBUSY +# include <errno.h> +# define __EBUSY EBUSY +# endif + +# ifndef __PT_SPIN_INLINE +# define __PT_SPIN_INLINE extern __inline +# endif + +__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_destroy (__pthread_spinlock_t *__lock) +{ + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, + int __pshared); + +__PT_SPIN_INLINE int +__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared) +{ + *__lock = __SPIN_LOCK_INITIALIZER; + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_trylock (__pthread_spinlock_t *__lock) +{ + long int __rtn; + __asm__ __volatile__ ("\ +0: lwarx %0,0,%1\n\ + stwcx. %2,0,%1\n\ + bne- 0b\n\ +" : "=&r" (__rtn) : "r" (__lock), "r" (1) : "cr0"); + return __rtn ? __EBUSY : 0; +} + +extern inline int __pthread_spin_lock (__pthread_spinlock_t *__lock); +extern int _pthread_spin_lock (__pthread_spinlock_t *__lock); + +extern inline int +__pthread_spin_lock (__pthread_spinlock_t *__lock) +{ + if (__pthread_spin_trylock (__lock)) + return _pthread_spin_lock (__lock); + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_unlock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_unlock (__pthread_spinlock_t *__lock) +{ + long int __locked; + __asm__ __volatile__ ("\ +0: lwarx %0,0,%1\n\ + stwcx. %2,0,%1\n\ + bne- 0b\n\ +" : "=&r" (__locked) : "r" (__lock), "r" (0) : "cr0"); +} + +#endif /* Use extern inlines or force inlines. */ + +__END_DECLS + +#endif /* bits/spin-lock.h */ diff --git a/sysdeps/powerpc/machine-sp.h b/sysdeps/powerpc/machine-sp.h new file mode 100644 index 0000000..aa787c5 --- /dev/null +++ b/sysdeps/powerpc/machine-sp.h @@ -0,0 +1,31 @@ +/* Machine-specific function to return the stack pointer. i386 version. + Copyright (C) 1994,97,2001 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 Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#define __thread_stack_pointer() ({ \ + void *__sp__; \ + __asm__ ("mr %0, 1" : "=r" (__sp__)); \ + __sp__; \ +}) + +#endif /* machine-sp.h */ diff --git a/sysdeps/powerpc/pt-machdep.h b/sysdeps/powerpc/pt-machdep.h new file mode 100644 index 0000000..6d45636 --- /dev/null +++ b/sysdeps/powerpc/pt-machdep.h @@ -0,0 +1,29 @@ +/* Machine dependent pthreads internal defenitions. i386 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. */ + +#ifndef _PT_MACHDEP_H +#define _PT_MACHDEP_H 1 + +struct pthread_mcontext +{ + void *pc; + void *sp; +}; + +#endif /* pt-machdep.h */ |