diff options
43 files changed, 1090 insertions, 227 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..bef3f17a --- /dev/null +++ b/Makefile.am @@ -0,0 +1,132 @@ +# Makefile.am - Makefile template for libpthread. +# Copyright (C) 2003 Free Software Foundation, Inc. +# +# 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 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 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +if ARCH_IA32 + arch=ia32 +endif +if ARCH_POWERPC + arch=powerpc +endif + +# The source files is scattered over several directories. Add +# all these directories to the vpath. +SYSDEP_PATH = $(srcdir)/sysdeps/l4/hurd/${arch} \ + $(srcdir)/sysdeps/l4/${arch} \ + $(srcdir)/sysdeps/l4/hurd \ + $(srcdir)/sysdeps/l4 \ + $(srcdir)/sysdeps/hurd \ + $(srcdir)/sysdeps/${arch} \ + $(srcdir)/sysdeps/generic \ + $(srcdir)/sysdeps/posix \ + $(srcdir)/pthread \ + $(srcdir)/include +vpath %.c $(SYSDEP_PATH) + +AM_CPPFLAGS = -I$(top_builddir)/include -D_GNU_SOURCE=1 -I$(srcdir)/pthread \ + -I$(top_srcdir)/libc-parts $(addprefix -I, $(SYSDEP_PATH)) \ + -imacros $(srcdir)/include/libc-symbols.h + +# Sources. +SYSDEPS := lockfile.c + +noinst_LIBRARIES = libpthread.a +libpthread_a_SOURCES = pt-attr.c pt-attr-destroy.c pt-attr-getdetachstate.c \ + pt-attr-getguardsize.c pt-attr-getinheritsched.c \ + pt-attr-getschedparam.c pt-attr-getschedpolicy.c pt-attr-getscope.c \ + pt-attr-getstack.c pt-attr-getstackaddr.c pt-attr-getstacksize.c \ + pt-attr-init.c pt-attr-setdetachstate.c pt-attr-setguardsize.c \ + pt-attr-setinheritsched.c pt-attr-setschedparam.c \ + pt-attr-setschedpolicy.c pt-attr-setscope.c pt-attr-setstack.c \ + pt-attr-setstackaddr.c pt-attr-setstacksize.c pt-attr.c \ + pt-barrier-destroy.c pt-barrier-init.c pt-barrier-wait.c \ + pt-barrier.c pt-barrierattr-destroy.c pt-barrierattr-init.c \ + pt-barrierattr-getpshared.c pt-barrierattr-setpshared.c \ + pt-destroy-specific.c pt-init-specific.c \ + pt-key-create.c pt-key-delete.c \ + pt-getspecific.c pt-setspecific.c \ + pt-once.c \ + pt-alloc.c \ + pt-create.c \ + pt-create-np.c \ + pt-pool-np.c \ + pt-equal.c \ + pt-dealloc.c \ + pt-detach.c \ + pt-exit.c \ + pt-initialize.c \ + pt-join.c \ + pt-self.c \ + pt-sigmask.c \ + pt-spin-inlines.c \ + pt-cleanup.c \ + pt-setcancelstate.c \ + pt-setcanceltype.c \ + pt-testcancel.c \ + pt-cancel.c \ + pt-mutexattr.c \ + pt-mutexattr-destroy.c pt-mutexattr-init.c \ + pt-mutexattr-getprioceiling.c pt-mutexattr-getprotocol.c \ + pt-mutexattr-getpshared.c pt-mutexattr-gettype.c \ + pt-mutexattr-setprioceiling.c pt-mutexattr-setprotocol.c \ + pt-mutexattr-setpshared.c pt-mutexattr-settype.c \ + pt-mutex-init.c pt-mutex-destroy.c \ + pt-mutex-lock.c pt-mutex-trylock.c pt-mutex-timedlock.c \ + pt-mutex-unlock.c \ + pt-mutex-getprioceiling.c pt-mutex-setprioceiling.c \ + pt-rwlock-attr.c \ + pt-rwlockattr-init.c pt-rwlockattr-destroy.c \ + pt-rwlockattr-getpshared.c pt-rwlockattr-setpshared.c \ + pt-rwlock-init.c pt-rwlock-destroy.c \ + pt-rwlock-rdlock.c pt-rwlock-tryrdlock.c \ + pt-rwlock-trywrlock.c pt-rwlock-wrlock.c \ + pt-rwlock-timedrdlock.c pt-rwlock-timedwrlock.c \ + pt-rwlock-unlock.c \ + pt-cond.c \ + pt-condattr-init.c pt-condattr-destroy.c \ + pt-condattr-getclock.c pt-condattr-getpshared.c \ + pt-condattr-setclock.c pt-condattr-setpshared.c \ + pt-cond-destroy.c pt-cond-init.c \ + pt-cond-brdcast.c \ + pt-cond-signal.c \ + pt-cond-wait.c \ + pt-cond-timedwait.c \ + pt-stack-alloc.c \ + pt-thread-alloc.c \ + pt-thread-start.c \ + pt-thread-halt.c \ + pt-thread-init.c \ + pt-getconcurrency.c pt-setconcurrency.c \ + pt-block.c \ + pt-timedblock.c \ + pt-wakeup.c \ + pt-docancel.c \ + pt-sysdep.c \ + pt-setup.c \ + pt-machdep.c \ + pt-spin.c \ + pt-sigstate-init.c \ + pt-sigstate-destroy.c \ + pt-sigstate.c \ + pt-atfork.c \ + pt-kill.c \ + pt-getcpuclockid.c \ + pt-getschedparam.c pt-setschedparam.c pt-setschedprio.c \ + sem-close.c sem-init.c sem-timedwait.c sem-wait.c \ + sem-destroy.c sem-open.c sem-trywait.c sem-getvalue.c \ + sem-post.c sem-unlink.c
\ No newline at end of file diff --git a/headers.m4 b/headers.m4 new file mode 100644 index 00000000..3c907880 --- /dev/null +++ b/headers.m4 @@ -0,0 +1,36 @@ +# headers.m4 - Autoconf snippets to install links for header files. +# Copyright 2003 Free Software Foundation, Inc. +# Written by Marcus Brinkmann <marcus@gnu.org>. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +AC_CONFIG_LINKS([ + include/pthread.h:libpthread/include/pthread.h + include/pthread/pthread.h:libpthread/include/pthread/pthread.h + include/bits/memory.h:libpthread/sysdeps/${arch}/bits/memory.h + include/bits/spin-lock.h:libpthread/sysdeps/${arch}/bits/spin-lock.h + include/bits/pthreadtypes.h:libpthread/sysdeps/generic/bits/pthreadtypes.h + include/bits/barrier-attr.h:libpthread/sysdeps/generic/bits/barrier-attr.h + include/bits/barrier.h:libpthread/sysdeps/generic/bits/barrier.h + include/bits/cancelation.h:libpthread/sysdeps/generic/bits/cancelation.h + include/bits/condition-attr.h:libpthread/sysdeps/generic/bits/condition-attr.h + include/bits/condition.h:libpthread/sysdeps/generic/bits/condition.h + include/bits/mutex-attr.h:libpthread/sysdeps/generic/bits/mutex-attr.h + include/bits/mutex.h:libpthread/sysdeps/generic/bits/mutex.h + include/bits/once.h:libpthread/sysdeps/generic/bits/once.h + include/bits/pthread.h:libpthread/sysdeps/generic/bits/pthread.h + include/bits/rwlock-attr.h:libpthread/sysdeps/generic/bits/rwlock-attr.h + include/bits/rwlock.h:libpthread/sysdeps/generic/bits/rwlock.h + include/bits/thread-attr.h:libpthread/sysdeps/generic/bits/thread-attr.h + include/bits/thread-barrier.h:libpthread/sysdeps/generic/bits/thread-barrier.h + include/bits/thread-specific.h:libpthread/sysdeps/generic/bits/thread-specific.h + include/bits/pthread-np.h:libpthread/sysdeps/l4/bits/pthread-np.h + include/semaphore.h:libpthread/include/semaphore.h + include/bits/semaphore.h:libpthread/sysdeps/generic/bits/semaphore.h +]) diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c index 30dcede0..6cf9106b 100644 --- a/pthread/pt-alloc.c +++ b/pthread/pt-alloc.c @@ -1,5 +1,5 @@ /* Allocate a new thread structure. - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 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 @@ -25,7 +25,7 @@ #include <pt-internal.h> -#include <bits/atomic.h> +#include <atomic.h> /* This braindamage is necessary because the standard says that some of the threads functions "shall fail" if "No thread could be found @@ -46,7 +46,7 @@ pthread_rwlock_t __pthread_threads_lock; /* List of thread structures corresponding to free thread IDs. */ -__atomicptr_t __pthread_free_threads; +atomicptr_t __pthread_free_threads; static inline error_t initialize_pthread (struct __pthread *new, int recycling) @@ -97,8 +97,10 @@ __pthread_alloc (struct __pthread **pthread) /* Try to re-use a thread structure before creating a new one. */ while ((new = (struct __pthread *)__pthread_free_threads)) { - if (__atomicptr_compare_and_swap (&__pthread_free_threads, - new, new->next)) + if (atomic_compare_and_exchange_val_acq (&__pthread_free_threads, + (uintptr_t) new->next, + (uintptr_t) new) + == (uintptr_t) new) { /* Yes, we managed to get one. The thread number in the thread structure still refers to the correct slot. */ @@ -110,8 +112,10 @@ __pthread_alloc (struct __pthread **pthread) while (1) { new->next = (struct __pthread *)__pthread_free_threads; - if (__atomicptr_compare_and_swap (&__pthread_free_threads, - new->next, new)) + if (atomic_compare_and_exchange_val_acq + (&__pthread_free_threads, + (uintptr_t) new, (uintptr_t) new->next) + == (uintptr_t) new->next) break; } diff --git a/pthread/pt-create.c b/pthread/pt-create.c index bad5d83f..4f8d043f 100644 --- a/pthread/pt-create.c +++ b/pthread/pt-create.c @@ -1,5 +1,5 @@ /* Thread creation. - Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005, 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 @@ -22,7 +22,7 @@ #include <pthread.h> #include <signal.h> -#include <bits/atomic.h> +#include <atomic.h> #include <pt-internal.h> @@ -33,7 +33,7 @@ /* The total number of pthreads currently active. This is defined here since it would be really stupid to have a threads-using program that doesn't call `pthread_create'. */ -__atomic_t __pthread_total; +atomic_fast32_t __pthread_total; /* The entry-point for new threads. */ @@ -161,7 +161,7 @@ __pthread_create_internal (struct __pthread **thread, the number of threads from within the new thread isn't an option since this thread might return and call `pthread_exit' before the new thread runs. */ - __atomic_inc (&__pthread_total); + atomic_increment (&__pthread_total); /* Store a pointer to this thread in the thread ID lookup table. We could use __thread_setid, however, we only lock for reading as no @@ -188,7 +188,7 @@ __pthread_create_internal (struct __pthread **thread, failed_starting: __pthread_setid (pthread->thread, NULL); - __atomic_dec (&__pthread_total); + atomic_decrement (&__pthread_total); failed_sigstate: __pthread_sigstate_destroy (pthread); failed_setup: diff --git a/pthread/pt-dealloc.c b/pthread/pt-dealloc.c index 1fc7a7b3..879608b9 100644 --- a/pthread/pt-dealloc.c +++ b/pthread/pt-dealloc.c @@ -23,10 +23,10 @@ #include <pt-internal.h> -#include <bits/atomic.h> +#include <atomic.h> /* List of thread structures corresponding to free thread IDs. */ -extern __atomicptr_t __pthread_free_threads; +extern atomicptr_t __pthread_free_threads; /* Deallocate the thread structure for PTHREAD and the resources associated with it. */ @@ -54,9 +54,11 @@ __pthread_dealloc (struct __pthread *pthread) while (1) { pthread->next = (struct __pthread *)__pthread_free_threads; - if (__atomicptr_compare_and_swap (&__pthread_free_threads, - pthread->next, pthread)) - return; + if (atomic_compare_and_exchange_val_acq (&__pthread_free_threads, + (uintptr_t) pthread, + (uintptr_t) pthread->next) + == (uintptr_t) pthread->next) + break; } /* NOTREACHED */ diff --git a/pthread/pt-exit.c b/pthread/pt-exit.c index 7484ffd1..a8f85b1a 100644 --- a/pthread/pt-exit.c +++ b/pthread/pt-exit.c @@ -24,7 +24,7 @@ #include <pt-internal.h> -#include <bits/atomic.h> +#include <atomic.h> /* Terminate the current thread and make STATUS available to any @@ -57,7 +57,7 @@ pthread_exit (void *status) /* Decrease the number of threads. We use an atomic operation to make sure that only the last thread calls `exit'. */ - if (__atomic_dec_and_test (&__pthread_total)) + if (atomic_decrement_and_test (&__pthread_total)) /* We are the last thread. */ exit (0); diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h index efd4ffb9..0dd4e9a8 100644 --- a/pthread/pt-internal.h +++ b/pthread/pt-internal.h @@ -26,7 +26,7 @@ #include <signal.h> #include <assert.h> -#include <bits/atomic.h> +#include <atomic.h> #include <pt-key.h> @@ -125,7 +125,7 @@ __pthread_dequeue (struct __pthread *thread) element = element->next) /* The total number of threads currently active. */ -extern __atomic_t __pthread_total; +extern atomic_fast32_t __pthread_total; /* The total number of thread IDs currently in use, or on the list of available thread IDs. */ diff --git a/sysdeps/generic/bits/pthreadtypes.h b/sysdeps/generic/bits/pthreadtypes.h new file mode 100644 index 00000000..e5cbfd2a --- /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/i386/bits/atomic.h b/sysdeps/i386/bits/atomic.h deleted file mode 100644 index 0dfc1f60..00000000 --- a/sysdeps/i386/bits/atomic.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Atomic operations. 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 _BITS_ATOMIC_H -#define _BITS_ATOMIC_H 1 - -typedef __volatile int __atomic_t; - -static inline void -__atomic_inc (__atomic_t *__var) -{ - __asm__ __volatile ("lock; incl %0" : "=m" (*__var) : "m" (*__var)); -} - -static inline void -__atomic_dec (__atomic_t *__var) -{ - __asm__ __volatile ("lock; decl %0" : "=m" (*__var) : "m" (*__var)); -} - -static inline int -__atomic_dec_and_test (__atomic_t *__var) -{ - unsigned char __ret; - - __asm__ __volatile ("lock; decl %0; sete %1" - : "=m" (*__var), "=qm" (__ret) : "m" (*__var)); - return __ret != 0; -} - -/* We assume that an __atomicptr_t is only used for pointers to - word-aligned objects, and use the lowest bit for a simple lock. */ -typedef __volatile int * __atomicptr_t; - -/* Actually we don't implement that yet, and assume that we run on - something that has the i486 instruction set. */ -static inline int -__atomicptr_compare_and_swap (__atomicptr_t *__ptr, void *__oldval, - void * __newval) -{ - char __ret; - int __dummy; - - __asm__ __volatile ("lock; cmpxchgl %3, %1; sete %0" - : "=q" (__ret), "=m" (*__ptr), "=a" (__dummy) - : "r" (__newval), "m" (*__ptr), "a" (__oldval)); - return __ret; -} - -#endif diff --git a/sysdeps/i386/bits/memory.h b/sysdeps/ia32/bits/memory.h index 201305b9..201305b9 100644 --- a/sysdeps/i386/bits/memory.h +++ b/sysdeps/ia32/bits/memory.h diff --git a/sysdeps/i386/bits/spin-lock.h b/sysdeps/ia32/bits/spin-lock.h index e86bc13e..175656ef 100644 --- a/sysdeps/i386/bits/spin-lock.h +++ b/sysdeps/ia32/bits/spin-lock.h @@ -1,5 +1,5 @@ /* Machine-specific definitions for spin locks. i386 version. - Copyright (C) 2000, 2005 Free Software Foundation, Inc. + 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 @@ -32,7 +32,7 @@ __BEGIN_DECLS typedef __volatile int __pthread_spinlock_t; /* Initializer for a spin lock object. */ -# define __SPIN_LOCK_INITIALIZER (0) +# define __SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0) #if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES @@ -74,10 +74,10 @@ __pthread_spin_trylock (__pthread_spinlock_t *__lock) 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)) diff --git a/sysdeps/ia32/machine-sp.h b/sysdeps/ia32/machine-sp.h new file mode 100644 index 00000000..536f6902 --- /dev/null +++ b/sysdeps/ia32/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__ ("movl %%esp, %0" : "=r" (__sp__)); \ + __sp__; \ +}) + +#endif /* machine-sp.h */ diff --git a/sysdeps/i386/pt-machdep.h b/sysdeps/ia32/pt-machdep.h index 6d456367..6d456367 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 00000000..3a98cd3f --- /dev/null +++ b/sysdeps/l4/bits/pthread-np.h @@ -0,0 +1,44 @@ +/* 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> + +/* Create a thread with attributes given by ATTR, executing + START_ROUTINE with argument ARG. TID is the provided L4 + kernel thread. */ +extern int pthread_create_from_l4_tid_np (pthread_t *thread, + const pthread_attr_t *attr, + _L4_thread_id_t tid, + void *(*start_routine)(void *), + void *arg); + +/* 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/i386/pt-machdep.c b/sysdeps/l4/hurd/ia32/pt-machdep.c index dbf5cd7e..dbf5cd7e 100644 --- a/sysdeps/l4/hurd/i386/pt-machdep.c +++ b/sysdeps/l4/hurd/ia32/pt-machdep.c diff --git a/sysdeps/l4/hurd/i386/pt-setup.c b/sysdeps/l4/hurd/ia32/pt-setup.c index fe77d533..e244dc16 100644 --- a/sysdeps/l4/hurd/i386/pt-setup.c +++ b/sysdeps/l4/hurd/ia32/pt-setup.c @@ -17,7 +17,7 @@ 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> @@ -39,16 +39,16 @@ static void * stack_setup (struct __pthread *thread, 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); if (start_routine) { /* Set up call frame. */ - *--top = (L4_Word_t) arg; /* Argument to START_ROUTINE. */ - *--top = (L4_Word_t) start_routine; + *--top = (l4_word_t) arg; /* Argument to START_ROUTINE. */ + *--top = (l4_word_t) start_routine; *--top = 0; /* Fake return address. */ } @@ -63,10 +63,10 @@ __pthread_setup (struct __pthread *thread, thread->mcontext.pc = entry_point; thread->mcontext.sp = stack_setup (thread, 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/powerpc/pt-machdep.c b/sysdeps/l4/hurd/powerpc/pt-machdep.c new file mode 100644 index 00000000..754d203e --- /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/powerpc/pt-setup.c b/sysdeps/l4/hurd/powerpc/pt-setup.c new file mode 100644 index 00000000..d3cf4ec3 --- /dev/null +++ b/sysdeps/l4/hurd/powerpc/pt-setup.c @@ -0,0 +1,93 @@ +/* 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 + 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> + +/* 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); + +/* 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. + 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 (*entry_point)(void *(*)(void *), void *), + void *(*start_routine)(void *), void *arg) +{ + l4_word_t *top; + + /* Calculate top of the new stack. */ + top = (l4_word_t *) ((l4_word_t) thread->stackaddr + thread->stacksize); + + /* Initial stack frame. */ + top[-4] = 0; + top = top - 4; + + if (start_routine) + { + 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; +} + +int +__pthread_setup (struct __pthread *thread, + void (*entry_point)(void *(*)(void *), void *), + void *(*start_routine)(void *), void *arg) +{ + thread->mcontext.pc = first_entry_1; + thread->mcontext.sp = stack_setup (thread, entry_point, + start_routine, arg); + + if (l4_same_threads (thread->threadid, l4_myself ())) + l4_set_user_defined_handle ((l4_word_t) thread); + else + l4_set_user_defined_handle_of (thread->threadid, + (l4_word_t) thread); + return 0; +} diff --git a/sysdeps/l4/hurd/pt-kill.c b/sysdeps/l4/hurd/pt-kill.c new file mode 100644 index 00000000..1e64af49 --- /dev/null +++ b/sysdeps/l4/hurd/pt-kill.c @@ -0,0 +1,30 @@ +/* pthread_kill. 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 <pthread.h> +#include <assert.h> +#include <signal.h> + +#include <pt-internal.h> + +int +pthread_kill (pthread_t thread, int sig) +{ + return ESRCH; +} diff --git a/sysdeps/l4/hurd/pt-sigstate-destroy.c b/sysdeps/l4/hurd/pt-sigstate-destroy.c new file mode 100644 index 00000000..997a0369 --- /dev/null +++ b/sysdeps/l4/hurd/pt-sigstate-destroy.c @@ -0,0 +1,28 @@ +/* Destroy the signal state. Hurd on L4 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 <pthread.h> + +#include <pt-internal.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 00000000..25a3920c --- /dev/null +++ b/sysdeps/l4/hurd/pt-sigstate-init.c @@ -0,0 +1,28 @@ +/* Initialize the signal state. Hurd on L4 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. */ + +#include <pthread.h> + +#include <pt-internal.h> + +error_t +__pthread_sigstate_init (struct __pthread *thread) +{ + return 0; +} diff --git a/sysdeps/l4/hurd/pt-sigstate.c b/sysdeps/l4/hurd/pt-sigstate.c new file mode 100644 index 00000000..8ab80347 --- /dev/null +++ b/sysdeps/l4/hurd/pt-sigstate.c @@ -0,0 +1,33 @@ +/* Set a thread's signal state. Hurd on L4 version. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + 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) +{ + /* FIXME: Do the right thing here. */ + return 0; +} diff --git a/sysdeps/l4/hurd/pt-sysdep.h b/sysdeps/l4/hurd/pt-sysdep.h index 87175330..0b5abb74 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. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,30 +20,28 @@ #ifndef _PT_SYSDEP_H #define _PT_SYSDEP_H 1 -#include <l4/l4.h> -#include <task_client.h> -#include <machine/vmparam.h> +#include <l4.h> /* XXX */ #define _POSIX_THREAD_THREADS_MAX 64 /* The default stack size. */ -#define PTHREAD_STACK_DEFAULT (PAGE_SIZE) +#define PTHREAD_STACK_DEFAULT 4096 #define PTHREAD_SYSDEP_MEMBERS \ - L4_ThreadId_t threadid; \ - L4_Word_t my_errno; + l4_thread_id_t threadid; \ + 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; diff --git a/sysdeps/l4/pt-block.c b/sysdeps/l4/pt-block.c index 050c6947..933cc285 100644 --- a/sysdeps/l4/pt-block.c +++ b/sysdeps/l4/pt-block.c @@ -17,7 +17,7 @@ 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> diff --git a/sysdeps/l4/pt-create-np.c b/sysdeps/l4/pt-create-np.c new file mode 100644 index 00000000..68b8b004 --- /dev/null +++ b/sysdeps/l4/pt-create-np.c @@ -0,0 +1,46 @@ +/* Thread creation from provided L4 thread. + 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. */ + +#include <assert.h> +#include <errno.h> +#include <pthread.h> +#include <signal.h> + +#include <pt-internal.h> + +/* Create a thread with attributes given by ATTR, executing + START_ROUTINE with argument ARG. TID is the provided L4 + kernel thread. */ +int +pthread_create_from_l4_tid_np (pthread_t *thread, + const pthread_attr_t *attr, + _L4_thread_id_t tid, + void *(*start_routine)(void *), void *arg) +{ + int err; + struct __pthread *pthread; + +#warning Does not use TID. + err = __pthread_create_internal (&pthread, attr, + start_routine, arg); + if (! err) + *thread = pthread->thread; + + return err; +} diff --git a/sysdeps/l4/pt-docancel.c b/sysdeps/l4/pt-docancel.c index 9a3bb26c..e832e26e 100644 --- a/sysdeps/l4/pt-docancel.c +++ b/sysdeps/l4/pt-docancel.c @@ -30,6 +30,7 @@ call_exit (void) int __pthread_do_cancel (struct __pthread *p) { +#if 0 assert (p->cancel_pending = 1); assert (p->cancel_state == PTHREAD_CANCEL_ENABLE); @@ -46,6 +47,6 @@ __pthread_do_cancel (struct __pthread *p) &dummy, &dummy, &dummy, &dummy, &dummy, &dummy_id); } - +#endif return 0; } diff --git a/sysdeps/l4/pt-pool-np.c b/sysdeps/l4/pt-pool-np.c new file mode 100644 index 00000000..f59a3e2b --- /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, bool stop) +{ + __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 00000000..b6978b0c --- /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 e28d5310..2ede58fd 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,11 @@ 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-thread-alloc.c b/sysdeps/l4/pt-thread-alloc.c index a9d5e212..fc2f43b4 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,20 +23,30 @@ #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) { + /* XXX: The initialization code needs to make this consistent. + Right now, we have none and this whole library is a hack + anyways. */ +#warning __pthread_total is inconsistent. +#if 0 assert (__pthread_total == 1); - thread->thread_id = L4_Myself (); +#endif + thread->threadid = l4_myself (); } else { + thread->threadid = pthread_pool_get_np (); + if (thread->threadid != l4_nilthread) + return 0; + +#if 0 CORBA_Environment env; env = idl4_default_environment; @@ -45,8 +55,8 @@ __pthread_thread_start (struct __pthread *thread) * (L4_Word_t *) &__system_pager, (L4_Word_t *) &thread->threadid, &env); if (err) +#endif return EAGAIN; } - return 0; } diff --git a/sysdeps/l4/pt-thread-halt.c b/sysdeps/l4/pt-thread-halt.c index 04d622f4..aa2bf43d 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-init.c b/sysdeps/l4/pt-thread-init.c new file mode 100644 index 00000000..ac50d58d --- /dev/null +++ b/sysdeps/l4/pt-thread-init.c @@ -0,0 +1,34 @@ +/* Start thread. L4 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. */ + +#include <assert.h> +#include <errno.h> +#include <string.h> + +#include <pt-internal.h> + +/* Initialize provided kernel thread. */ +int +__pthread_init_provided_thread (struct __pthread *thread, + void *p) +{ + l4_thread_id_t *tid = (l4_thread_id_t *) p; + thread->threadid = *tid; + return 0; +} diff --git a/sysdeps/l4/pt-thread-start.c b/sysdeps/l4/pt-thread-start.c index c428d290..10996e1c 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 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) - { - assert (__pthread_total == 1); - assert (thread->thread_id == L4_Myself ()); - } + assert (__pthread_total == 1); 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_set_pager_of (thread->threadid, l4_pager ()); + 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 00000000..fda14401 --- /dev/null +++ b/sysdeps/l4/pt-timedblock.c @@ -0,0 +1,34 @@ +/* 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) +{ + __pthread_block (thread); + return 0; +} diff --git a/sysdeps/l4/pt-wakeup.c b/sysdeps/l4/pt-wakeup.c index 7b00e4f6..342a2204 100644 --- a/sysdeps/l4/pt-wakeup.c +++ b/sysdeps/l4/pt-wakeup.c @@ -17,7 +17,7 @@ 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> @@ -25,5 +25,5 @@ void __pthread_wakeup (struct __pthread *thread) { - L4_Send (thread->threadid); + l4_send (thread->threadid); } diff --git a/sysdeps/mach/hurd/i386/pt-machdep.c b/sysdeps/mach/hurd/ia32/pt-machdep.c index face46c5..face46c5 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 32ace6ad..32ace6ad 100644 --- a/sysdeps/mach/hurd/i386/pt-setup.c +++ b/sysdeps/mach/hurd/ia32/pt-setup.c diff --git a/sysdeps/posix/pt-spin.c b/sysdeps/posix/pt-spin.c index 486030de..26793b08 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, 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 00000000..cba6b0a6 --- /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 00000000..96624c3e --- /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 00000000..1dc25710 --- /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/i386/machine-sp.h b/sysdeps/powerpc/machine-sp.h index 945a36b8..aa787c59 100644 --- a/sysdeps/i386/machine-sp.h +++ b/sysdeps/powerpc/machine-sp.h @@ -23,7 +23,8 @@ /* Return the current stack pointer. */ #define __thread_stack_pointer() ({ \ - register void *__sp__ asm("esp"); \ + void *__sp__; \ + __asm__ ("mr %0, 1" : "=r" (__sp__)); \ __sp__; \ }) diff --git a/sysdeps/powerpc/pt-machdep.h b/sysdeps/powerpc/pt-machdep.h new file mode 100644 index 00000000..6d456367 --- /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 */ |