diff options
Diffstat (limited to 'libpthread/sysdeps/mach')
37 files changed, 1330 insertions, 0 deletions
diff --git a/libpthread/sysdeps/mach/CVS/Entries b/libpthread/sysdeps/mach/CVS/Entries new file mode 100644 index 00000000..910bd7e9 --- /dev/null +++ b/libpthread/sysdeps/mach/CVS/Entries @@ -0,0 +1,11 @@ +/pt-block.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-spin.c/1.2/Tue Feb 8 14:42:03 2005//Tzhengda-soc2008-virt-branch +/pt-stack-alloc.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-thread-alloc.c/1.3/Wed May 4 16:04:06 2005//Tzhengda-soc2008-virt-branch +/pt-thread-dealloc.c/1.1/Wed May 4 16:04:06 2005//Tzhengda-soc2008-virt-branch +/pt-thread-halt.c/1.2/Wed May 4 16:04:06 2005//Tzhengda-soc2008-virt-branch +/pt-thread-start.c/1.2/Mon Nov 18 22:20:58 2002//Tzhengda-soc2008-virt-branch +/pt-timedblock.c/1.2/Thu May 12 20:55:37 2005//Tzhengda-soc2008-virt-branch +/pt-wakeup.c/1.2/Mon Nov 18 22:20:58 2002//Tzhengda-soc2008-virt-branch +D/bits//// +D/hurd//// diff --git a/libpthread/sysdeps/mach/CVS/Repository b/libpthread/sysdeps/mach/CVS/Repository new file mode 100644 index 00000000..23602bb1 --- /dev/null +++ b/libpthread/sysdeps/mach/CVS/Repository @@ -0,0 +1 @@ +hurd/libpthread/sysdeps/mach diff --git a/libpthread/sysdeps/mach/CVS/Root b/libpthread/sysdeps/mach/CVS/Root new file mode 100644 index 00000000..a10aa66d --- /dev/null +++ b/libpthread/sysdeps/mach/CVS/Root @@ -0,0 +1 @@ +:ext:zhengda@cvs.savannah.gnu.org:/sources/hurd diff --git a/libpthread/sysdeps/mach/CVS/Tag b/libpthread/sysdeps/mach/CVS/Tag new file mode 100644 index 00000000..7e454c6d --- /dev/null +++ b/libpthread/sysdeps/mach/CVS/Tag @@ -0,0 +1 @@ +Tzhengda-soc2008-virt-branch diff --git a/libpthread/sysdeps/mach/bits/CVS/Entries b/libpthread/sysdeps/mach/bits/CVS/Entries new file mode 100644 index 00000000..1488d083 --- /dev/null +++ b/libpthread/sysdeps/mach/bits/CVS/Entries @@ -0,0 +1,2 @@ +/spin-lock.h/1.4/Tue Jul 1 11:43:18 2008//Tzhengda-soc2008-virt-branch +D diff --git a/libpthread/sysdeps/mach/bits/CVS/Repository b/libpthread/sysdeps/mach/bits/CVS/Repository new file mode 100644 index 00000000..e78fe18d --- /dev/null +++ b/libpthread/sysdeps/mach/bits/CVS/Repository @@ -0,0 +1 @@ +hurd/libpthread/sysdeps/mach/bits diff --git a/libpthread/sysdeps/mach/bits/CVS/Root b/libpthread/sysdeps/mach/bits/CVS/Root new file mode 100644 index 00000000..a10aa66d --- /dev/null +++ b/libpthread/sysdeps/mach/bits/CVS/Root @@ -0,0 +1 @@ +:ext:zhengda@cvs.savannah.gnu.org:/sources/hurd diff --git a/libpthread/sysdeps/mach/bits/CVS/Tag b/libpthread/sysdeps/mach/bits/CVS/Tag new file mode 100644 index 00000000..7e454c6d --- /dev/null +++ b/libpthread/sysdeps/mach/bits/CVS/Tag @@ -0,0 +1 @@ +Tzhengda-soc2008-virt-branch diff --git a/libpthread/sysdeps/mach/bits/spin-lock.h b/libpthread/sysdeps/mach/bits/spin-lock.h new file mode 100644 index 00000000..0cbf11ed --- /dev/null +++ b/libpthread/sysdeps/mach/bits/spin-lock.h @@ -0,0 +1,97 @@ +/* Definitions of user-visible names for spin locks. + Copyright (C) 1994, 1997, 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 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_H +#define _BITS_SPIN_LOCK_H 1 + +#include <features.h> +#include <machine-lock.h> /* This does all the work. */ + +__BEGIN_DECLS + +/* The type of a spin lock object. */ +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>. +#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/libpthread/sysdeps/mach/hurd/CVS/Entries b/libpthread/sysdeps/mach/hurd/CVS/Entries new file mode 100644 index 00000000..a13e7635 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/CVS/Entries @@ -0,0 +1,9 @@ +/pt-attr-setstackaddr.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-attr-setstacksize.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-docancel.c/1.3/Tue May 27 18:37:29 2008//Tzhengda-soc2008-virt-branch +/pt-sigstate-destroy.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-sigstate-init.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-sigstate.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-sysdep.c/1.2/Wed May 4 16:04:05 2005//Tzhengda-soc2008-virt-branch +/pt-sysdep.h/1.3/Tue Jan 18 10:08:52 2005//Tzhengda-soc2008-virt-branch +D/i386//// diff --git a/libpthread/sysdeps/mach/hurd/CVS/Repository b/libpthread/sysdeps/mach/hurd/CVS/Repository new file mode 100644 index 00000000..ad77c6f9 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/CVS/Repository @@ -0,0 +1 @@ +hurd/libpthread/sysdeps/mach/hurd diff --git a/libpthread/sysdeps/mach/hurd/CVS/Root b/libpthread/sysdeps/mach/hurd/CVS/Root new file mode 100644 index 00000000..a10aa66d --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/CVS/Root @@ -0,0 +1 @@ +:ext:zhengda@cvs.savannah.gnu.org:/sources/hurd diff --git a/libpthread/sysdeps/mach/hurd/CVS/Tag b/libpthread/sysdeps/mach/hurd/CVS/Tag new file mode 100644 index 00000000..7e454c6d --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/CVS/Tag @@ -0,0 +1 @@ +Tzhengda-soc2008-virt-branch diff --git a/libpthread/sysdeps/mach/hurd/i386/CVS/Entries b/libpthread/sysdeps/mach/hurd/i386/CVS/Entries new file mode 100644 index 00000000..d153b1d6 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/CVS/Entries @@ -0,0 +1,3 @@ +/pt-machdep.c/1.1/Thu Oct 10 23:05:05 2002//Tzhengda-soc2008-virt-branch +/pt-setup.c/1.6/Tue Jul 1 11:43:18 2008//Tzhengda-soc2008-virt-branch +D diff --git a/libpthread/sysdeps/mach/hurd/i386/CVS/Repository b/libpthread/sysdeps/mach/hurd/i386/CVS/Repository new file mode 100644 index 00000000..9a741168 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/CVS/Repository @@ -0,0 +1 @@ +hurd/libpthread/sysdeps/mach/hurd/i386 diff --git a/libpthread/sysdeps/mach/hurd/i386/CVS/Root b/libpthread/sysdeps/mach/hurd/i386/CVS/Root new file mode 100644 index 00000000..a10aa66d --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/CVS/Root @@ -0,0 +1 @@ +:ext:zhengda@cvs.savannah.gnu.org:/sources/hurd diff --git a/libpthread/sysdeps/mach/hurd/i386/CVS/Tag b/libpthread/sysdeps/mach/hurd/i386/CVS/Tag new file mode 100644 index 00000000..7e454c6d --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/CVS/Tag @@ -0,0 +1 @@ +Tzhengda-soc2008-virt-branch diff --git a/libpthread/sysdeps/mach/hurd/i386/pt-machdep.c b/libpthread/sysdeps/mach/hurd/i386/pt-machdep.c new file mode 100644 index 00000000..0f6e825e --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/pt-machdep.c @@ -0,0 +1,83 @@ +/* Machine dependent pthreads code. Hurd/i386 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 <errno.h> + +#include <mach.h> +#include <mach/i386/thread_status.h> +#include <mach/i386/mach_i386.h> +#include <mach/mig_errors.h> +#include <mach/thread_status.h> + +#define HURD_TLS_DESC_DECL(desc, tcb) \ + struct descriptor desc = \ + { /* low word: */ \ + 0xffff /* limit 0..15 */ \ + | (((unsigned int) (tcb)) << 16) /* base 0..15 */ \ + , /* high word: */ \ + ((((unsigned int) (tcb)) >> 16) & 0xff) /* base 16..23 */ \ + | ((0x12 | 0x60 | 0x80) << 8) /* access = ACC_DATA_W|ACC_PL_U|ACC_P */ \ + | (0xf << 16) /* limit 16..19 */ \ + | ((4 | 8) << 20) /* granularity = SZ_32|SZ_G */ \ + | (((unsigned int) (tcb)) & 0xff000000) /* base 24..31 */ \ + } + +int +__thread_set_pcsptp (thread_t thread, + int set_ip, void *ip, + int set_sp, void *sp, + int set_tp, void *tp) +{ + error_t err; + struct i386_thread_state state; + mach_msg_type_number_t state_count; + + state_count = i386_THREAD_STATE_COUNT; + + err = __thread_get_state (thread, i386_REGS_SEGS_STATE, + (thread_state_t) &state, &state_count); + if (err) + return err; + + if (set_sp) + state.uesp = (unsigned int) sp; + if (set_ip) + state.eip = (unsigned int) ip; + if (set_tp) { + HURD_TLS_DESC_DECL(desc, tp); + int sel; + + asm ("mov %%gs, %w0" : "=q" (sel) : "0" (0)); + if (__builtin_expect (sel, 0x48) & 4) /* LDT selector */ + err = __i386_set_ldt (thread, sel, &desc, 1); + else + err = __i386_set_gdt (thread, &sel, desc); + if (err) + return err; + state.gs = sel; + } + + err = __thread_set_state (thread, i386_REGS_SEGS_STATE, + (thread_state_t) &state, + i386_THREAD_STATE_COUNT); + if (err) + return err; + + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/i386/pt-setup.c b/libpthread/sysdeps/mach/hurd/i386/pt-setup.c new file mode 100644 index 00000000..dc275e94 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/pt-setup.c @@ -0,0 +1,108 @@ +/* Setup thread stack. Hurd/i386 version. + 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 + 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 <stdint.h> +#include <assert.h> +#include <mach.h> + +#include <pt-internal.h> + +/* The stack layout used on the i386 is: + + ----------------- + | ARG | + ----------------- + | START_ROUTINE | + ----------------- + | 0 | + ----------------- + | | + | Fast TSD | + | | + ----------------- + + We need to reserve __hurd_threadvar_max `unsigned long int's' of + (fast) thread-specific data (TSD) for the Hurd. */ + +/* 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. */ +static void * +stack_setup (struct __pthread *thread, + void *(*start_routine)(void *), void *arg) +{ + error_t err; + uintptr_t *bottom, *top; + + /* Calculate the top of the new stack. */ + bottom = thread->stackaddr; + top = (uintptr_t *) ((uintptr_t) bottom + thread->stacksize); + + /* Next, make room for the TSDs. */ + top -= __hurd_threadvar_max; + + /* Save the self pointer. */ + top[_HURD_THREADVAR_THREAD] = (void *) thread; + + if (start_routine) + { + /* And then the call frame. */ + top -= 2*sizeof(uintptr_t); + top = (uintptr_t) top & ~0xf; + top[1] = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + top[0] = (uintptr_t) start_routine; + *--top = 0; /* Fake return address. */ + } + + if (thread->guardsize) + { + err = __vm_protect (__mach_task_self (), (vm_address_t) bottom, + thread->guardsize, 0, 0); + assert_perror (err); + } + + return top; +} + +int +__pthread_setup (struct __pthread *thread, + void (*entry_point)(void *(*)(void *), void *), + void *(*start_routine)(void *), void *arg) +{ + error_t err; + mach_port_t ktid; + + thread->mcontext.pc = entry_point; + thread->mcontext.sp = stack_setup (thread, start_routine, arg); + + thread->tcb->self = thread->kernel_thread; + + ktid = __mach_thread_self (); + if (thread->kernel_thread != ktid) + { + err = __thread_set_pcsptp (thread->kernel_thread, + 1, thread->mcontext.pc, + 1, thread->mcontext.sp, + 1, thread->tcb); + assert_perror (err); + } + __mach_port_deallocate (__mach_task_self (), ktid); + + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/i386/pt-setup.c.orig b/libpthread/sysdeps/mach/hurd/i386/pt-setup.c.orig new file mode 100644 index 00000000..5abbcfcd --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/i386/pt-setup.c.orig @@ -0,0 +1,105 @@ +/* Setup thread stack. Hurd/i386 version. + 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 + 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 <stdint.h> +#include <assert.h> +#include <mach.h> + +#include <pt-internal.h> + +/* The stack layout used on the i386 is: + + ----------------- + | ARG | + ----------------- + | START_ROUTINE | + ----------------- + | 0 | + ----------------- + | | + | Fast TSD | + | | + ----------------- + + We need to reserve __hurd_threadvar_max `unsigned long int's' of + (fast) thread-specific data (TSD) for the Hurd. */ + +/* 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. */ +static void * +stack_setup (struct __pthread *thread, + void *(*start_routine)(void *), void *arg) +{ + error_t err; + uintptr_t *bottom, *top; + + /* Calculate the top of the new stack. */ + bottom = thread->stackaddr; + top = (uintptr_t *) ((uintptr_t) bottom + thread->stacksize); + + /* Next, make room for the TSDs. */ + top -= __hurd_threadvar_max; + + /* Save the self pointer. */ + top[_HURD_THREADVAR_THREAD] = (void *) thread; + + if (start_routine) + { + /* And then the call frame. */ + top -= 2*sizeof(uintptr_t); + top = (uintptr_t) top & ~0xf; + top[1] = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + top[0] = (uintptr_t) start_routine; + *--top = 0; /* Fake return address. */ + } + + if (thread->guardsize) + { + err = __vm_protect (__mach_task_self (), (vm_address_t) bottom, + thread->guardsize, 0, 0); + assert_perror (err); + } + + return top; +} + +int +__pthread_setup (struct __pthread *thread, + void (*entry_point)(void *(*)(void *), void *), + void *(*start_routine)(void *), void *arg) +{ + error_t err; + mach_port_t ktid; + + thread->mcontext.pc = entry_point; + thread->mcontext.sp = stack_setup (thread, start_routine, arg); + + ktid = __mach_thread_self (); + if (thread->kernel_thread != ktid) + { + err = __thread_set_pcsp (thread->kernel_thread, + 1, thread->mcontext.pc, + 1, thread->mcontext.sp); + assert_perror (err); + } + __mach_port_deallocate (__mach_task_self (), ktid); + + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-attr-setstackaddr.c b/libpthread/sysdeps/mach/hurd/pt-attr-setstackaddr.c new file mode 100644 index 00000000..1225ed5b --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-attr-setstackaddr.c @@ -0,0 +1,35 @@ +/* pthread_attr_setstackaddr. Hurd on Mach 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> + +/* We use fixed sized stacks which require proper alignment. */ +#define __pthread_stacksize __pthread_default_attr.stacksize + +int +pthread_attr_setstackaddr (pthread_attr_t *attr, + void *stackaddr) +{ + if ((long) stackaddr & (__pthread_stacksize - 1)) + return EINVAL; + + attr->stackaddr = stackaddr; + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-attr-setstacksize.c b/libpthread/sysdeps/mach/hurd/pt-attr-setstacksize.c new file mode 100644 index 00000000..6471c0a3 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-attr-setstacksize.c @@ -0,0 +1,35 @@ +/* pthread_attr_setstacksize. Hurd on Mach 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> + +/* We use fixed sized stacks which require proper alignment. */ +#define __pthread_stacksize __pthread_default_attr.stacksize + +int +pthread_attr_setstacksize (pthread_attr_t *attr, + size_t stacksize) +{ + if (stacksize != __pthread_stacksize) + return EINVAL; + + attr->stacksize = stacksize; + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-docancel.c b/libpthread/sysdeps/mach/hurd/pt-docancel.c new file mode 100644 index 00000000..b3d31a56 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-docancel.c @@ -0,0 +1,64 @@ +/* Cancel a thread. + 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 + 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> + +static void +call_exit (void) +{ + pthread_exit (0); +} + +int +__pthread_do_cancel (struct __pthread *p) +{ + mach_port_t ktid; + int me; + + assert (p->cancel_pending == 1); + assert (p->cancel_state == PTHREAD_CANCEL_ENABLE); + + ktid = __mach_thread_self (); + me = p->kernel_thread == ktid; + __mach_port_deallocate (__mach_task_self (), ktid); + + if (me) + call_exit (); + else + { + error_t err; + + err = __thread_suspend (p->kernel_thread); + assert_perror (err); + + err = __thread_abort (p->kernel_thread); + assert_perror (err); + + err = __thread_set_pcsptp (p->kernel_thread, + 1, (void *) call_exit, 0, 0, 0, 0); + assert_perror (err); + + err = __thread_resume (p->kernel_thread); + assert_perror (err); + } + + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-sigstate-destroy.c b/libpthread/sysdeps/mach/hurd/pt-sigstate-destroy.c new file mode 100644 index 00000000..8e56c5cf --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-sigstate-destroy.c @@ -0,0 +1,28 @@ +/* Destroy the signal state. Hurd on Mach 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/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c b/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c new file mode 100644 index 00000000..da5a9455 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-sigstate-init.c @@ -0,0 +1,37 @@ +/* Initialize the signal state. Hurd on Mach 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 <hurd/threadvar.h> + +#include <pt-internal.h> + +error_t +__pthread_sigstate_init (struct __pthread *thread) +{ + void **location = + (void *) __hurd_threadvar_location_from_sp (_HURD_THREADVAR_SIGSTATE, + thread->stackaddr); + + /* The real initialization happens internally in glibc the first + time that _hurd_thead_sigstate is called. */ + *location = 0; + + return 0; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-sigstate.c b/libpthread/sysdeps/mach/hurd/pt-sigstate.c new file mode 100644 index 00000000..68c79c5b --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-sigstate.c @@ -0,0 +1,69 @@ +/* Set a thread's signal state. Hurd on Mach 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 <hurd/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) +{ + error_t err = 0; + struct hurd_sigstate *ss; + + ss = _hurd_thread_sigstate (thread->kernel_thread); + assert (ss); + + __pthread_spin_lock (&ss->lock); + + if (oset) + *oset = ss->blocked; + + if (set) + switch (how) + { + case SIG_BLOCK: + ss->blocked |= *set; + break; + + case SIG_SETMASK: + ss->blocked = *set; + break; + + case SIG_UNBLOCK: + ss->blocked &= ~*set; + break; + + default: + err = EINVAL; + break; + } + + if (! err && clear_pending) + __sigemptyset (&ss->pending); + + __pthread_spin_unlock (&ss->lock); + + return err; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-sysdep.c b/libpthread/sysdeps/mach/hurd/pt-sysdep.c new file mode 100644 index 00000000..5e070067 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-sysdep.c @@ -0,0 +1,72 @@ +/* System dependent pthreads code. Hurd version. + 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 + 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 <stddef.h> +#include <stdint.h> + +#include <mach.h> +#include <mach/mig_support.h> + +#include <hurd/threadvar.h> + +#include <pt-internal.h> + +/* Forward. */ +static void *init_routine (void); + +/* OK, the name of this variable isn't really appropriate, but I don't + want to change it yet. */ +void *(*_cthread_init_routine)(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) +{ + struct __pthread *thread; + int err; + + /* Initialize the library. */ + __pthread_initialize (); + + /* Create the pthread structure for the main thread (i.e. us). */ + err = __pthread_create_internal (&thread, 0, 0, 0); + assert_perror (err); + + ((void **) (__hurd_threadvar_stack_offset))[_HURD_THREADVAR_THREAD] + = thread; + + /* Decrease the number of threads, to take into account that the + signal thread (which will be created by the glibc startup code + when we return from here) shouldn't be seen as a user thread. */ + __pthread_total--; + + /* Make MiG code thread aware. */ + __mig_init (thread->stackaddr); + + /* Make sure we can find the per-thread variables. */ + __hurd_threadvar_stack_mask = ~(__pthread_default_attr.stacksize - 1); + __hurd_threadvar_stack_offset + = (__pthread_default_attr.stacksize + - __hurd_threadvar_max * sizeof (uintptr_t)); + + return thread->mcontext.sp; +} diff --git a/libpthread/sysdeps/mach/hurd/pt-sysdep.h b/libpthread/sysdeps/mach/hurd/pt-sysdep.h new file mode 100644 index 00000000..f17d14e1 --- /dev/null +++ b/libpthread/sysdeps/mach/hurd/pt-sysdep.h @@ -0,0 +1,71 @@ +/* Internal defenitions for pthreads library. + Copyright (C) 2000, 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. */ + +#ifndef _PT_SYSDEP_H +#define _PT_SYSDEP_H 1 + +#include <mach.h> + +#include <hurd/threadvar.h> + +/* XXX */ +#define _POSIX_THREAD_THREADS_MAX 64 + +/* The default stack size. */ +#define PTHREAD_STACK_DEFAULT (2 * 1024 * 1024) + +#define PTHREAD_SYSDEP_MEMBERS \ + thread_t kernel_thread; \ + mach_msg_header_t wakeupmsg; + +#define _HURD_THREADVAR_THREAD _HURD_THREADVAR_DYNAMIC_USER + +#define _pthread_self() \ + ({ \ + struct __pthread *thread; \ + \ + assert (__pthread_threads); \ + thread = *(struct __pthread **) \ + __hurd_threadvar_location (_HURD_THREADVAR_THREAD); \ + \ + assert (thread); \ + assert (({ mach_port_t ktid = __mach_thread_self (); \ + int ok = thread->kernel_thread == ktid; \ + __mach_port_deallocate (__mach_task_self (), ktid);\ + ok; })); \ + thread; \ + }) + +extern inline void +__attribute__((__always_inline__)) +__pthread_stack_dealloc (void *stackaddr, size_t stacksize) +{ + __vm_deallocate (__mach_task_self (), (vm_offset_t) stackaddr, stacksize); +} + +/* Change thread THREAD's program counter to PC if SET_PC is true, + its stack pointer to SP if SET_IP is true, and its thread pointer + to TP if SET_TP is true. */ +extern int __thread_set_pcsptp (thread_t thread, + int set_pc, void *pc, + int set_sp, void *sp, + int set_tp, void *tp); + + +#endif /* pt-sysdep.h */ diff --git a/libpthread/sysdeps/mach/pt-block.c b/libpthread/sysdeps/mach/pt-block.c new file mode 100644 index 00000000..a947b27c --- /dev/null +++ b/libpthread/sysdeps/mach/pt-block.c @@ -0,0 +1,39 @@ +/* Block a thread. Mach version. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <assert.h> +#include <errno.h> + +#include <mach.h> +#include <mach/message.h> + +#include <pt-internal.h> + +/* Block THREAD. */ +void +__pthread_block (struct __pthread *thread) +{ + mach_msg_header_t msg; + error_t err; + + err = __mach_msg (&msg, MACH_RCV_MSG, 0, sizeof msg, + thread->wakeupmsg.msgh_remote_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + assert_perror (err); +} diff --git a/libpthread/sysdeps/mach/pt-spin.c b/libpthread/sysdeps/mach/pt-spin.c new file mode 100644 index 00000000..d9a2a32a --- /dev/null +++ b/libpthread/sysdeps/mach/pt-spin.c @@ -0,0 +1,36 @@ +/* Spin locks. Mach version. + Copyright (C) 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 + 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 <machine-lock.h> + +/* In glibc. */ +extern void __spin_lock_solid (__pthread_spinlock_t *lock); + +/* 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) +{ + __spin_lock_solid (lock); + return 0; +} + +weak_alias (_pthread_spin_lock, pthread_spin_lock); +weak_alias (_pthread_spin_lock, __pthread_spin_lock); diff --git a/libpthread/sysdeps/mach/pt-stack-alloc.c b/libpthread/sysdeps/mach/pt-stack-alloc.c new file mode 100644 index 00000000..0956fc7d --- /dev/null +++ b/libpthread/sysdeps/mach/pt-stack-alloc.c @@ -0,0 +1,74 @@ +/* Allocate a new stack. Mach 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 <errno.h> + +#include <mach.h> +#include <mach/machine/vm_param.h> + +#include <pt-internal.h> + +#define __pthread_stacksize __pthread_default_attr.stacksize + +/* The next address to use for stack allocation. */ +static vm_address_t next_stack_base = VM_MIN_ADDRESS; + + +/* 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 + new stack). */ +int +__pthread_stack_alloc (void **stackaddr, size_t stacksize) +{ + vm_offset_t base; + int i = 0; + + if (stacksize != __pthread_stacksize) + return EINVAL; + + get_stack: + i ++; + for (base = next_stack_base; + base < VM_MAX_ADDRESS + && __vm_allocate (__mach_task_self (), &base, + __pthread_stacksize, FALSE) != KERN_SUCCESS; + base += __pthread_stacksize) + ; + + if (base >= VM_MAX_ADDRESS) + { + if (i == 1) + { + next_stack_base = VM_MIN_ADDRESS; + goto get_stack; + } + else + return EAGAIN; + } + + if (base >= VM_MAX_ADDRESS) + return EAGAIN; + + next_stack_base = base + __pthread_stacksize; + + (*stackaddr) = (void *) base; + return 0; +} diff --git a/libpthread/sysdeps/mach/pt-thread-alloc.c b/libpthread/sysdeps/mach/pt-thread-alloc.c new file mode 100644 index 00000000..1acba98a --- /dev/null +++ b/libpthread/sysdeps/mach/pt-thread-alloc.c @@ -0,0 +1,101 @@ +/* Start thread. Mach version. + 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 + 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 <mach.h> + +#include <pt-internal.h> + +/* Prepare a wakeup message. */ +static error_t +create_wakeupmsg (struct __pthread *thread) +{ + kern_return_t err; + + /* Build wakeup message. */ + thread->wakeupmsg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); + thread->wakeupmsg.msgh_size = 0; + + err = __mach_port_allocate (__mach_task_self (), MACH_PORT_RIGHT_RECEIVE, + &thread->wakeupmsg.msgh_remote_port); + if (err) + return EAGAIN; + + thread->wakeupmsg.msgh_local_port = MACH_PORT_NULL; + thread->wakeupmsg.msgh_seqno = 0; + thread->wakeupmsg.msgh_id = 0; + + err = __mach_port_insert_right (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port, + thread->wakeupmsg.msgh_remote_port, + MACH_MSG_TYPE_MAKE_SEND); + if (err) + { + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); + return EAGAIN; + } + + return 0; +} + +/* Allocate any resouces for THREAD. The new kernel thread should not + be eligible to be scheduled. */ +int +__pthread_thread_alloc (struct __pthread *thread) +{ + error_t err; + + err = create_wakeupmsg (thread); + if (err) + return err; + + /* If there are no pthreads in the system then the pthread library + is bootstrapping and the main thread must create initialize + itself. The thread itself is already running, it just has not + pthread context. We want to reuse what it already has (including + the kernel thread), however, we must determine which thread is + the main thread. + + We cannot test if __pthread_total is one as we later decrement + before creating the signal thread. Currently, we check if + __pthread_num_threads--the number of allocated thread + structures--is one. __pthread_alloc has already been called in + __pthread_create_internal for us. This predicate could be improved, + however, it is sufficient for now. */ + if (__pthread_num_threads == 1) + { + assert (__pthread_total == 0); + thread->kernel_thread = __mach_thread_self (); + /* We implicitly hold a reference drop the one that we just + acquired. */ + __mach_port_deallocate (__mach_task_self (), thread->kernel_thread); + } + else + { + err = __thread_create (__mach_task_self (), &thread->kernel_thread); + if (err) + return EAGAIN; + } + + return 0; +} diff --git a/libpthread/sysdeps/mach/pt-thread-dealloc.c b/libpthread/sysdeps/mach/pt-thread-dealloc.c new file mode 100644 index 00000000..55d8c4d5 --- /dev/null +++ b/libpthread/sysdeps/mach/pt-thread-dealloc.c @@ -0,0 +1,41 @@ +/* Deallocate the kernel thread resources. Mach 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 <mach.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) +{ + /* Why no assert? Easy. When Mach kills a task, it starts by + invalidating the task port and then terminating the threads one + by one. But while it is terminating them, they are still + eligible to be scheduled. Imagine we have two threads, one calls + exit, one calls pthread_exit. The second one may run this after + the mask port can been destroyed thus gratuitously triggering the + assert. */ + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); +} diff --git a/libpthread/sysdeps/mach/pt-thread-halt.c b/libpthread/sysdeps/mach/pt-thread-halt.c new file mode 100644 index 00000000..9f860247 --- /dev/null +++ b/libpthread/sysdeps/mach/pt-thread-halt.c @@ -0,0 +1,43 @@ +/* Deallocate the kernel thread resources. Mach version. + 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 + 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 <mach.h> + +#include <pt-internal.h> + +/* Stop the kernel thread associated with THREAD. If NEED_DEALLOC is + true, the function must call __pthread_dealloc on THREAD. + + NB: The thread executing this function may be the thread which is + being halted, thus the last action should be halting the thread + itself. */ +void +__pthread_thread_halt (struct __pthread *thread, int need_dealloc) +{ + error_t err; + thread_t tid = thread->kernel_thread; + + if (need_dealloc) + __pthread_dealloc (thread); + + err = __thread_terminate (tid); + assert_perror (err); +} diff --git a/libpthread/sysdeps/mach/pt-thread-start.c b/libpthread/sysdeps/mach/pt-thread-start.c new file mode 100644 index 00000000..11b017ff --- /dev/null +++ b/libpthread/sysdeps/mach/pt-thread-start.c @@ -0,0 +1,49 @@ +/* Start thread. Mach 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 <mach.h> + +#include <pt-internal.h> + +/* Start THREAD. Get the kernel thread scheduled and running. */ +int +__pthread_thread_start (struct __pthread *thread) +{ + error_t err; + + if (__pthread_num_threads == 1) + { + /* The main thread is already running: do nothing. */ + assert (__pthread_total == 1); + assert (({ mach_port_t ktid = __mach_thread_self (); + int ok = thread->kernel_thread == ktid; + __mach_port_deallocate (__mach_task_self (), + thread->kernel_thread); + ok; })); + } + else + { + err = __thread_resume (thread->kernel_thread); + assert_perror (err); + } + + return 0; +} diff --git a/libpthread/sysdeps/mach/pt-timedblock.c b/libpthread/sysdeps/mach/pt-timedblock.c new file mode 100644 index 00000000..ddb8baec --- /dev/null +++ b/libpthread/sysdeps/mach/pt-timedblock.c @@ -0,0 +1,68 @@ +/* Block a thread with a timeout. Mach version. + 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 + 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 <mach.h> +#include <mach/message.h> + +#include <pt-internal.h> + +/* Block THREAD. */ +error_t +__pthread_timedblock (struct __pthread *thread, + const struct timespec *abstime) +{ + error_t err; + mach_msg_header_t msg; + mach_msg_timeout_t timeout; + struct timeval now; + + /* We have an absolute time and now we have to convert it to a + relative time. Arg. */ + + err = gettimeofday(&now, NULL); + assert (! err); + + if (now.tv_sec > abstime->tv_sec + || (now.tv_sec == abstime->tv_sec + && now.tv_usec > ((abstime->tv_nsec + 999) / 1000))) + return ETIMEDOUT; + + 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; + else + /* Need to do a carry. */ + timeout -= 1000 + ((abstime->tv_nsec + 999999) / 1000000) + - (now.tv_usec + 999) / 1000; + + err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, + sizeof msg, thread->wakeupmsg.msgh_remote_port, + timeout, MACH_PORT_NULL); + if (err == EMACH_RCV_TIMED_OUT) + return ETIMEDOUT; + + assert_perror (err); + return 0; +} diff --git a/libpthread/sysdeps/mach/pt-wakeup.c b/libpthread/sysdeps/mach/pt-wakeup.c new file mode 100644 index 00000000..4920d102 --- /dev/null +++ b/libpthread/sysdeps/mach/pt-wakeup.c @@ -0,0 +1,38 @@ +/* Wakeup a thread. Mach version. + Copyright (C) 2000, 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 <mach.h> +#include <mach/message.h> + +#include <pt-internal.h> + +/* Wakeup THREAD. */ +void +__pthread_wakeup (struct __pthread *thread) +{ + error_t err; + + err = __mach_msg (&thread->wakeupmsg, MACH_SEND_MSG, + sizeof (thread->wakeupmsg), 0, MACH_PORT_NULL, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + assert_perror (err); +} |