diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-04-02 01:43:22 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-04-02 01:44:14 +0200 |
commit | 33574c17eefcf326c1cd30eb9f915ad26d3d9ef2 (patch) | |
tree | 2c1b143f2b7a0ceba9fba000b70dd2889d56e60f /sysdeps | |
parent | 03e2aa50fd512449025bba8c244d16338d8526a4 (diff) | |
download | glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.gz glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.tar.xz glibc-33574c17eefcf326c1cd30eb9f915ad26d3d9ef2.zip |
hurd: Add hurd thread library
Contributed by Agustina Arzille <avarzille@riseup.net> Amos Jeffries <squid3@treenet.co.nz> David Michael <fedora.dm0@gmail.com> Marco Gerards <marco@gnu.org> Marcus Brinkmann <marcus@gnu.org> Neal H. Walfield <neal@gnu.org> Pino Toscano <toscano.pino@tiscali.it> Richard Braun <rbraun@sceen.net> Roland McGrath <roland@gnu.org> Samuel Thibault <samuel.thibault@ens-lyon.org> Thomas DiModica <ricinwich@yahoo.com> Thomas Schwinge <tschwinge@gnu.org> * htl: New directory. * sysdeps/htl: New directory. * sysdeps/hurd/htl: New directory. * sysdeps/i386/htl: New directory. * sysdeps/mach/htl: New directory. * sysdeps/mach/hurd/htl: New directory. * sysdeps/mach/hurd/i386/htl: New directory. * nscd/Depend, resolv/Depend, rt/Depend: Add htl dependency. * sysdeps/mach/hurd/i386/Implies: Add mach/hurd/i386/htl imply. * sysdeps/mach/hurd/i386/libpthread.abilist: New file.
Diffstat (limited to 'sysdeps')
196 files changed, 9774 insertions, 0 deletions
diff --git a/sysdeps/htl/Implies b/sysdeps/htl/Implies new file mode 100644 index 0000000000..f1b3e8939c --- /dev/null +++ b/sysdeps/htl/Implies @@ -0,0 +1 @@ +pthread diff --git a/sysdeps/htl/Makeconfig b/sysdeps/htl/Makeconfig new file mode 100644 index 0000000000..3af4c1de35 --- /dev/null +++ b/sysdeps/htl/Makeconfig @@ -0,0 +1,11 @@ +# Makeconfig fragment for Hurd libpthread add-on. +# This gets included at the end of the main glibc Makeconfig. + +have-thread-library = yes + +shared-thread-library = $(common-objpfx)htl/libpthread_nonshared.a \ + $(common-objpfx)htl/libpthread.so +static-thread-library = $(common-objpfx)htl/libpthread.a +bounded-thread-library = $(static-thread-library) + +rpath-dirs += htl diff --git a/sysdeps/htl/Makefile b/sysdeps/htl/Makefile new file mode 100644 index 0000000000..12bb54ebf4 --- /dev/null +++ b/sysdeps/htl/Makefile @@ -0,0 +1,7 @@ +ifeq ($(subdir),rt) +librt-sysdep_routines += timer_routines +endif + +ifeq ($(subdir),posix) +CFLAGS-confstr.c += -DLIBPTHREAD_VERSION='"HTL $(version)"' +endif diff --git a/sysdeps/htl/Subdirs b/sysdeps/htl/Subdirs new file mode 100644 index 0000000000..5215f33d98 --- /dev/null +++ b/sysdeps/htl/Subdirs @@ -0,0 +1 @@ +htl diff --git a/sysdeps/htl/Versions b/sysdeps/htl/Versions new file mode 100644 index 0000000000..3a3b1e8b3d --- /dev/null +++ b/sysdeps/htl/Versions @@ -0,0 +1,15 @@ +libc { + GLIBC_2.2 { + # XXX + __vm_deallocate; __mach_port_insert_right; __mach_reply_port; + __mig_init; __vm_allocate; __mach_port_allocate; + + # functions used in inline functions or macros + __pthread_spin_destroy; __pthread_spin_init; __pthread_spin_lock; + _pthread_spin_lock; __pthread_spin_trylock; __pthread_spin_unlock; + + # p* + pthread_spin_destroy; pthread_spin_init; pthread_spin_lock; + pthread_spin_trylock; pthread_spin_unlock; + } +} diff --git a/sysdeps/htl/bits/cancelation.h b/sysdeps/htl/bits/cancelation.h new file mode 100644 index 0000000000..56cf1af154 --- /dev/null +++ b/sysdeps/htl/bits/cancelation.h @@ -0,0 +1,50 @@ +/* Cancelation. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_CANCELATION_H +#define _BITS_CANCELATION_H 1 + +struct __pthread_cancelation_handler +{ + void (*__handler) (void *); + void *__arg; + struct __pthread_cancelation_handler *__next; +}; + +/* Returns the thread local location of the cleanup handler stack. */ +struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void); + +#define __pthread_cleanup_push(rt, rtarg) \ + { \ + struct __pthread_cancelation_handler **__handlers \ + = __pthread_get_cleanup_stack (); \ + struct __pthread_cancelation_handler __handler = \ + { \ + (rt), \ + (rtarg), \ + *__handlers \ + }; \ + *__handlers = &__handler; + +#define __pthread_cleanup_pop(execute) \ + if (execute) \ + __handler.__handler (__handler.__arg); \ + *__handlers = __handler.__next; \ + } + +#endif /* _BITS_CANCELATION_H */ diff --git a/sysdeps/htl/bits/pthread-np.h b/sysdeps/htl/bits/pthread-np.h new file mode 100644 index 0000000000..b9587efba8 --- /dev/null +++ b/sysdeps/htl/bits/pthread-np.h @@ -0,0 +1,26 @@ +/* Non-portable functions. Generic version. + Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_PTHREAD_NP_H +#define _BITS_PTHREAD_NP_H 1 + +#endif /* bits/pthread-np.h */ diff --git a/sysdeps/htl/bits/pthread.h b/sysdeps/htl/bits/pthread.h new file mode 100644 index 0000000000..593ab06ba8 --- /dev/null +++ b/sysdeps/htl/bits/pthread.h @@ -0,0 +1,36 @@ +/* Pthread data structures. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_PTHREAD_H +#define _BITS_PTHREAD_H 1 + +typedef int __pthread_t; + +/* Return true if __T1 and __T2 both name the same thread. Otherwise, + false. */ +extern int __pthread_equal (__pthread_t __t1, __pthread_t __t2); + +#ifdef __USE_EXTERN_INLINES +__extern_inline int +__pthread_equal (__pthread_t __t1, __pthread_t __t2) +{ + return __t1 == __t2; +} +#endif + +#endif /* bits/pthread.h */ diff --git a/sysdeps/htl/bits/pthreadtypes.h b/sysdeps/htl/bits/pthreadtypes.h new file mode 100644 index 0000000000..95ccf513ff --- /dev/null +++ b/sysdeps/htl/bits/pthreadtypes.h @@ -0,0 +1,131 @@ +/* Declaration of common pthread types for all architectures. Hurd version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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 <bits/thread-shared-types.h> + +#include <features.h> + +#include <bits/types.h> + +__BEGIN_DECLS +#include <bits/pthread.h> +typedef __pthread_t pthread_t; + +/* Possible values for the process shared attribute. */ +enum __pthread_process_shared +{ + __PTHREAD_PROCESS_PRIVATE = 0, + __PTHREAD_PROCESS_SHARED +}; + +/* Possible values for the inheritsched attribute. */ +enum __pthread_inheritsched +{ + __PTHREAD_EXPLICIT_SCHED = 0, + __PTHREAD_INHERIT_SCHED +}; + +/* Possible values for the `contentionscope' attribute. */ +enum __pthread_contentionscope +{ + __PTHREAD_SCOPE_SYSTEM = 0, + __PTHREAD_SCOPE_PROCESS +}; + +/* Possible values for the `detachstate' attribute. */ +enum __pthread_detachstate +{ + __PTHREAD_CREATE_JOINABLE = 0, + __PTHREAD_CREATE_DETACHED +}; + +#include <bits/types/struct___pthread_attr.h> +typedef struct __pthread_attr pthread_attr_t; + +enum __pthread_mutex_protocol +{ + __PTHREAD_PRIO_NONE = 0, + __PTHREAD_PRIO_INHERIT, + __PTHREAD_PRIO_PROTECT +}; + +enum __pthread_mutex_type +{ + __PTHREAD_MUTEX_TIMED, + __PTHREAD_MUTEX_ERRORCHECK, + __PTHREAD_MUTEX_RECURSIVE +}; + +enum __pthread_mutex_robustness +{ + __PTHREAD_MUTEX_STALLED, + __PTHREAD_MUTEX_ROBUST = 0x100 +}; + +#include <bits/types/struct___pthread_mutexattr.h> +typedef struct __pthread_mutexattr pthread_mutexattr_t; + +#include <bits/types/struct___pthread_mutex.h> +typedef struct __pthread_mutex pthread_mutex_t; + +#include <bits/types/struct___pthread_condattr.h> +typedef struct __pthread_condattr pthread_condattr_t; + +#include <bits/types/struct___pthread_cond.h> +typedef struct __pthread_cond pthread_cond_t; + +#ifdef __USE_XOPEN2K +# include <bits/types/__pthread_spinlock_t.h> +typedef __pthread_spinlock_t pthread_spinlock_t; +#endif /* XPG6. */ + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K + +# include <bits/types/struct___pthread_rwlockattr.h> +typedef struct __pthread_rwlockattr pthread_rwlockattr_t; + +# include <bits/types/struct___pthread_rwlock.h> +typedef struct __pthread_rwlock pthread_rwlock_t; + +#endif /* __USE_UNIX98 || __USE_XOPEN2K */ + +#ifdef __USE_XOPEN2K + +# include <bits/types/struct___pthread_barrierattr.h> +typedef struct __pthread_barrierattr pthread_barrierattr_t; + +# include <bits/types/struct___pthread_barrier.h> +typedef struct __pthread_barrier pthread_barrier_t; + +#endif /* __USE_XOPEN2K */ + +#include <bits/types/__pthread_key.h> +typedef __pthread_key pthread_key_t; + +#include <bits/types/struct___pthread_once.h> +typedef struct __pthread_once pthread_once_t; + +__END_DECLS +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/htl/bits/semaphore.h b/sysdeps/htl/bits/semaphore.h new file mode 100644 index 0000000000..b1789be55f --- /dev/null +++ b/sysdeps/htl/bits/semaphore.h @@ -0,0 +1,47 @@ +/* Semaphore type. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_SEMAPHORE_H +#define _BITS_SEMAPHORE_H 1 + +#ifndef _SEMAPHORE_H +# error Never include <bits/semaphore.h> directly. +#endif + +#include <bits/types/__pthread_spinlock_t.h> +#include <bits/pthread.h> + +/* User visible part of a semaphore. */ +struct __semaphore +{ + __pthread_spinlock_t __lock; + struct __pthread *__queue; + int __pshared; + int __value; + void *__data; +}; + +typedef struct __semaphore sem_t; + +#define SEM_FAILED ((void *) 0) + +/* Initializer for a semaphore. */ +#define __SEMAPHORE_INITIALIZER(pshared, value) \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, (pshared), (value), NULL } + +#endif /* bits/semaphore.h */ diff --git a/sysdeps/htl/bits/thread-shared-types.h b/sysdeps/htl/bits/thread-shared-types.h new file mode 100644 index 0000000000..054cbf201f --- /dev/null +++ b/sysdeps/htl/bits/thread-shared-types.h @@ -0,0 +1,24 @@ +/* Common threading primitives definitions for both POSIX and C11. + Copyright (C) 2017-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _THREAD_SHARED_TYPES_H +#define _THREAD_SHARED_TYPES_H 1 + +#include <bits/pthreadtypes-arch.h> + +#endif /* _THREAD_SHARED_TYPES_H */ diff --git a/sysdeps/htl/bits/types/__pthread_key.h b/sysdeps/htl/bits/types/__pthread_key.h new file mode 100644 index 0000000000..c558f478b0 --- /dev/null +++ b/sysdeps/htl/bits/types/__pthread_key.h @@ -0,0 +1,24 @@ +/* Thread specific data. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES___PTHREAD_KEY_H +#define _BITS_TYPES___PTHREAD_KEY_H 1 + +typedef int __pthread_key; + +#endif /* bits/types/__pthread_key.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_attr.h b/sysdeps/htl/bits/types/struct___pthread_attr.h new file mode 100644 index 0000000000..44f9543a84 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_attr.h @@ -0,0 +1,45 @@ +/* Thread attribute type. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_ATTR +#define _BITS_TYPES_STRUCT___PTHREAD_ATTR 1 + +#include <sched.h> + +#define __need_size_t +#include <stddef.h> + +enum __pthread_detachstate; +enum __pthread_inheritsched; +enum __pthread_contentionscope; + +/* This structure describes the attributes of a POSIX thread. Note + that not all of them are supported on all systems. */ +struct __pthread_attr +{ + struct sched_param __schedparam; + void *__stackaddr; + size_t __stacksize; + size_t __guardsize; + enum __pthread_detachstate __detachstate; + enum __pthread_inheritsched __inheritsched; + enum __pthread_contentionscope __contentionscope; + int __schedpolicy; +}; + +#endif /* bits/types/struct___pthread_attr.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_barrier.h b/sysdeps/htl/bits/types/struct___pthread_barrier.h new file mode 100644 index 0000000000..27a6b84212 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_barrier.h @@ -0,0 +1,38 @@ +/* Thread barrier attribute type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_BARRIER_H +#define _BITS_TYPES_STRUCT___PTHREAD_BARRIER_H 1 + +#include <bits/types/__pthread_spinlock_t.h> + +/* This structure describes the attributes of a POSIX barrier. */ +struct __pthread_barrier +{ + __pthread_spinlock_t __lock; + struct __pthread *__queue; /* List of waiters. */ + unsigned __pending; /* Number of that still need to wait on + barrier. */ + unsigned __count; /* Number of threads that must wait before + barrier is passed. */ + struct __pthread_barrierattr *__attr; + void *__data; +}; + + +#endif /* bits/types/struct___pthread_barrier.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_barrierattr.h b/sysdeps/htl/bits/types/struct___pthread_barrierattr.h new file mode 100644 index 0000000000..5ac2c34d88 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_barrierattr.h @@ -0,0 +1,31 @@ +/* Thread barrier attribute type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_BARRIERATTR_H +#define _BITS_TYPES_STRUCT___PTHREAD_BARRIERATTR_H 1 + +enum __pthread_process_shared; + +/* This structure describes the attributes of a POSIX thread barrier. + Note that not all of them are supported on all systems. */ +struct __pthread_barrierattr +{ + enum __pthread_process_shared __pshared; +}; + +#endif /* bits/types/struct___pthread_barrierattr.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_cond.h b/sysdeps/htl/bits/types/struct___pthread_cond.h new file mode 100644 index 0000000000..d84cde0887 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_cond.h @@ -0,0 +1,38 @@ +/* Condition type. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_COND_H +#define _BITS_TYPES_STRUCT___PTHREAD_COND_H 1 + +#include <bits/types/__pthread_spinlock_t.h> + +/* User visible part of a condition variable. */ +struct __pthread_cond +{ + __pthread_spinlock_t __lock; + struct __pthread *__queue; + struct __pthread_condattr *__attr; + struct __pthread_condimpl *__impl; + void *__data; +}; + +/* Initializer for a condition variable. */ +#define __PTHREAD_COND_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL } + +#endif /* bits/types/struct___pthread_cond.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_condattr.h b/sysdeps/htl/bits/types/struct___pthread_condattr.h new file mode 100644 index 0000000000..4d5450168c --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_condattr.h @@ -0,0 +1,33 @@ +/* Condition attribute type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_CONDATTR +#define _BITS_TYPES_STRUCT___PTHREAD_CONDATTR 1 + +#include <bits/types.h> + +enum __pthread_process_shared; + +/* User visible part of a condition attribute variable. */ +struct __pthread_condattr +{ + enum __pthread_process_shared __pshared; + __clockid_t __clock; +}; + +#endif /* bits/types/struct___pthread_condattr.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_mutex.h b/sysdeps/htl/bits/types/struct___pthread_mutex.h new file mode 100644 index 0000000000..0a89ded73c --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_mutex.h @@ -0,0 +1,62 @@ +/* Mutex type. Generic version. + + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H +#define _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H 1 + +#include <bits/types/__pthread_spinlock_t.h> +#include <bits/types/struct___pthread_mutexattr.h> + +/* User visible part of a mutex. */ +struct __pthread_mutex +{ + __pthread_spinlock_t __held; + __pthread_spinlock_t __lock; + /* In cthreads, mutex_init does not initialized thre third + pointer, as such, we cannot rely on its value for anything. */ + char *__cthreadscompat1; + struct __pthread *__queue; + struct __pthread_mutexattr *__attr; + void *__data; + /* Up to this point, we are completely compatible with cthreads + and what libc expects. */ + void *__owner; + unsigned __locks; + /* If NULL then the default attributes apply. */ +}; + +/* Initializer for a mutex. N.B. this also happens to be compatible + with the cthread mutex initializer. */ +#define __PTHREAD_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } + +#define __PTHREAD_ERRORCHECK_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_ERRORCHECK + 1)) + +#define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ + __PTHREAD_ERRORCHECK_MUTEXATTR, 0, 0, 0 } + +#define __PTHREAD_RECURSIVE_MUTEXATTR ((struct __pthread_mutexattr *) ((unsigned long) __PTHREAD_MUTEX_RECURSIVE + 1)) + +#define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, \ + __PTHREAD_RECURSIVE_MUTEXATTR, 0, 0, 0 } + +#endif /* bits/types/struct___pthread_mutex.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_mutexattr.h b/sysdeps/htl/bits/types/struct___pthread_mutexattr.h new file mode 100644 index 0000000000..c77458ac21 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_mutexattr.h @@ -0,0 +1,40 @@ +/* Mutex attribute type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEXATTR_H +#define _BITS_TYPES_STRUCT___PTHREAD_MUTEXATTR_H 1 + +enum __pthread_mutex_protocol; +enum __pthread_process_shared; +enum __pthread_mutex_type; + +/* This structure describes the attributes of a POSIX mutex + attribute. */ +struct __pthread_mutexattr +{ + int __prioceiling; + enum __pthread_mutex_protocol __protocol; + enum __pthread_process_shared __pshared; + enum __pthread_mutex_type __mutex_type; +}; + +/* Attributes for a recursive mutex. */ +extern const struct __pthread_mutexattr __pthread_errorcheck_mutexattr; +extern const struct __pthread_mutexattr __pthread_recursive_mutexattr; + +#endif /* bits/types/struct___pthread_mutexattr.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_once.h b/sysdeps/htl/bits/types/struct___pthread_once.h new file mode 100644 index 0000000000..5b99658938 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_once.h @@ -0,0 +1,33 @@ +/* Dynamic package initialization data structures. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_ONCE_H +#define _BITS_TYPES_STRUCT___PTHREAD_ONCE_H 1 + +#include <bits/types/__pthread_spinlock_t.h> + +struct __pthread_once +{ + int __run; + __pthread_spinlock_t __lock; +}; + +#define __PTHREAD_ONCE_INIT \ + (struct __pthread_once) { 0, __PTHREAD_SPIN_LOCK_INITIALIZER } + +#endif /* bits/types/struct___pthread_once.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_rwlock.h b/sysdeps/htl/bits/types/struct___pthread_rwlock.h new file mode 100644 index 0000000000..cf47671240 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_rwlock.h @@ -0,0 +1,45 @@ +/* rwlock type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_RWLOCK_H +#define _BITS_TYPES_STRUCT___PTHREAD_RWLOCK_H + +#include <bits/types/__pthread_spinlock_t.h> + +/* User visible part of a rwlock. If __held is not held and readers + is 0, then the lock is unlocked. If __held is held and readers is + 0, then the lock is held by a writer. If __held is held and + readers is greater than 0, then the lock is held by READERS + readers. */ +struct __pthread_rwlock +{ + __pthread_spinlock_t __held; + __pthread_spinlock_t __lock; + int __readers; + struct __pthread *__readerqueue; + struct __pthread *__writerqueue; + struct __pthread_rwlockattr *__attr; + void *__data; +}; + +/* Initializer for a rwlock. */ +#define __PTHREAD_RWLOCK_INITIALIZER \ + { __PTHREAD_SPIN_LOCK_INITIALIZER, __PTHREAD_SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } + + +#endif /* bits/types/struct___pthread_rwlock.h */ diff --git a/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h b/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h new file mode 100644 index 0000000000..7df532ee04 --- /dev/null +++ b/sysdeps/htl/bits/types/struct___pthread_rwlockattr.h @@ -0,0 +1,31 @@ +/* Thread rwlock attribute type. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_RWLOCKATTR_H +#define _BITS_TYPES_STRUCT___PTHREAD_RWLOCKATTR_H 1 + +enum __pthread_process_shared; + +/* This structure describes the attributes of a POSIX thread rwlock. + Note that not all of them are supported on all systems. */ +struct __pthread_rwlockattr +{ + enum __pthread_process_shared __pshared; +}; + +#endif /* bits/types/struct___pthread_rwlockattr.h */ diff --git a/sysdeps/htl/flockfile.c b/sysdeps/htl/flockfile.c new file mode 100644 index 0000000000..f9df093767 --- /dev/null +++ b/sysdeps/htl/flockfile.c @@ -0,0 +1,31 @@ +/* Lock I/O stream. Hurd version. + Copyright (C) 2002-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <libc-lock.h> + + +void +__flockfile (FILE *stream) +{ +#ifdef SHARED + __libc_ptf_call (_IO_flockfile, (stream), 0); +#endif +} +weak_alias (__flockfile, _IO_flockfile) +weak_alias (__flockfile, flockfile) diff --git a/sysdeps/htl/fork.h b/sysdeps/htl/fork.h new file mode 100644 index 0000000000..f944a741ee --- /dev/null +++ b/sysdeps/htl/fork.h @@ -0,0 +1,29 @@ +/* Register fork handlers. Generic version. + Copyright (C) 2002-2018 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, see + <http://www.gnu.org/licenses/>. */ + +/* Function to call to unregister fork handlers. */ +extern void __unregister_atfork (void *dso_handle) attribute_hidden; +#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle) + + +/* C library side function to register new fork handlers. */ +extern int __register_atfork (void (*__prepare) (void), + void (*__parent) (void), + void (*__child) (void), + void *dso_handle); +libc_hidden_proto (__register_atfork) diff --git a/sysdeps/htl/ftrylockfile.c b/sysdeps/htl/ftrylockfile.c new file mode 100644 index 0000000000..7de42c7b3d --- /dev/null +++ b/sysdeps/htl/ftrylockfile.c @@ -0,0 +1,35 @@ +/* Try locking I/O stream. Hurd version + Copyright (C) 2002-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdio-lock.h> + + +int +__ftrylockfile (FILE *stream) +{ +#ifdef SHARED + return __libc_ptf_call (_IO_ftrylockfile, (stream), 0); +#else + return 0; +#endif +} +weak_alias (__ftrylockfile, _IO_ftrylockfile) +weak_alias (__ftrylockfile, ftrylockfile) diff --git a/sysdeps/htl/funlockfile.c b/sysdeps/htl/funlockfile.c new file mode 100644 index 0000000000..bc7da12c34 --- /dev/null +++ b/sysdeps/htl/funlockfile.c @@ -0,0 +1,32 @@ +/* Unlock I/O stream. Hurd version. + Copyright (C) 2002-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdio.h> +#include <stdio-lock.h> + + +void +__funlockfile (FILE *stream) +{ +#ifdef SHARED + __libc_ptf_call (_IO_funlockfile, (stream), 0); +#endif +} +weak_alias (__funlockfile, _IO_funlockfile) +weak_alias (__funlockfile, funlockfile) diff --git a/sysdeps/htl/libc-lockP.h b/sysdeps/htl/libc-lockP.h new file mode 100644 index 0000000000..944c0e5931 --- /dev/null +++ b/sysdeps/htl/libc-lockP.h @@ -0,0 +1,180 @@ +/* Private libc-internal interface for mutex locks. + Copyright (C) 2015-2018 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; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_LIBC_LOCKP_H +#define _BITS_LIBC_LOCKP_H 1 + +#include <pthread.h> +#include <pthread-functions.h> + +/* Type for key to thread-specific data. */ +typedef pthread_key_t __libc_key_t; + +/* If we check for a weakly referenced symbol and then perform a + normal jump to it te code generated for some platforms in case of + PIC is unnecessarily slow. What would happen is that the function + is first referenced as data and then it is called indirectly + through the PLT. We can make this a direct jump. */ +#ifdef __PIC__ +# define __libc_maybe_call(FUNC, ARGS, ELSE) \ + (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \ + _fn != NULL ? (*_fn) ARGS : ELSE; })) +#else +# define __libc_maybe_call(FUNC, ARGS, ELSE) \ + (FUNC != NULL ? FUNC ARGS : ELSE) +#endif + +/* Call thread functions through the function pointer table. */ +#if defined SHARED && IS_IN (libc) +# define PTFAVAIL(NAME) __libc_pthread_functions_init +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ + (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE) +# define __libc_ptf_call_always(FUNC, ARGS) \ + PTHFCT_CALL (ptr_##FUNC, ARGS) +#elif IS_IN (libpthread) +# define PTFAVAIL(NAME) 1 +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ + FUNC ARGS +# define __libc_ptf_call_always(FUNC, ARGS) \ + FUNC ARGS +#else +# define PTFAVAIL(NAME) (NAME != NULL) +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ + __libc_maybe_call (FUNC, ARGS, ELSE) +# define __libc_ptf_call_always(FUNC, ARGS) \ + FUNC ARGS +#endif + +/* Create thread-specific key. */ +#define __libc_key_create(KEY, DESTRUCTOR) \ + __libc_ptf_call (__pthread_key_create, (KEY, DESTRUCTOR), 1) + +/* Get thread-specific data. */ +#define __libc_getspecific(KEY) \ + __libc_ptf_call (__pthread_getspecific, (KEY), NULL) + +/* Set thread-specific data. */ +#define __libc_setspecific(KEY, VALUE) \ + __libc_ptf_call (__pthread_setspecific, (KEY, VALUE), 0) + + +/* Functions that are used by this file and are internal to the GNU C + library. */ + +extern int __pthread_mutex_init (pthread_mutex_t *__mutex, + const pthread_mutexattr_t *__mutex_attr); + +extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); + +extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex); + +extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr); + +extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr); + +extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr, + int __kind); + +extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock, + const pthread_rwlockattr_t *__attr); + +extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); + +extern int __pthread_key_create (pthread_key_t *__key, + void (*__destr_function) (void *)); + +extern int __pthread_setspecific (pthread_key_t __key, + const void *__pointer); + +extern void *__pthread_getspecific (pthread_key_t __key); + +extern int __pthread_once (pthread_once_t *__once_control, + void (*__init_routine) (void)); + +extern int __pthread_atfork (void (*__prepare) (void), + void (*__parent) (void), + void (*__child) (void)); + + + +/* Make the pthread functions weak so that we can elide them from + single-threaded processes. */ +#if !defined(__NO_WEAK_PTHREAD_ALIASES) && !IS_IN (libpthread) +# ifdef weak_extern +weak_extern (__pthread_mutex_init) +weak_extern (__pthread_mutex_destroy) +weak_extern (__pthread_mutex_lock) +weak_extern (__pthread_mutex_trylock) +weak_extern (__pthread_mutex_unlock) +weak_extern (__pthread_mutexattr_init) +weak_extern (__pthread_mutexattr_destroy) +weak_extern (__pthread_mutexattr_settype) +weak_extern (__pthread_rwlock_init) +weak_extern (__pthread_rwlock_destroy) +weak_extern (__pthread_rwlock_rdlock) +weak_extern (__pthread_rwlock_tryrdlock) +weak_extern (__pthread_rwlock_wrlock) +weak_extern (__pthread_rwlock_trywrlock) +weak_extern (__pthread_rwlock_unlock) +weak_extern (__pthread_key_create) +weak_extern (__pthread_setspecific) +weak_extern (__pthread_getspecific) +weak_extern (__pthread_once) +weak_extern (__pthread_initialize) +weak_extern (__pthread_atfork) +weak_extern (__pthread_setcancelstate) +# else +# pragma weak __pthread_mutex_init +# pragma weak __pthread_mutex_destroy +# pragma weak __pthread_mutex_lock +# pragma weak __pthread_mutex_trylock +# pragma weak __pthread_mutex_unlock +# pragma weak __pthread_mutexattr_init +# pragma weak __pthread_mutexattr_destroy +# pragma weak __pthread_mutexattr_settype +# pragma weak __pthread_rwlock_destroy +# pragma weak __pthread_rwlock_rdlock +# pragma weak __pthread_rwlock_tryrdlock +# pragma weak __pthread_rwlock_wrlock +# pragma weak __pthread_rwlock_trywrlock +# pragma weak __pthread_rwlock_unlock +# pragma weak __pthread_key_create +# pragma weak __pthread_setspecific +# pragma weak __pthread_getspecific +# pragma weak __pthread_once +# pragma weak __pthread_initialize +# pragma weak __pthread_atfork +# pragma weak __pthread_setcancelstate +# endif +#endif + +#endif /* bits/libc-lockP.h */ diff --git a/sysdeps/htl/old_pt-atfork.c b/sysdeps/htl/old_pt-atfork.c new file mode 100644 index 0000000000..dfb7e983fe --- /dev/null +++ b/sysdeps/htl/old_pt-atfork.c @@ -0,0 +1,26 @@ +/* Register fork handlers. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <shlib-compat.h> + +#if SHLIB_COMPAT(libpthread, GLIBC_2_12, GLIBC_2_23) +# define pthread_atfork __dyn_pthread_atfork +# include "pt-atfork.c" +# undef pthread_atfork +compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_12); +#endif diff --git a/sysdeps/htl/pt-atfork.c b/sysdeps/htl/pt-atfork.c new file mode 100644 index 0000000000..036427dbbc --- /dev/null +++ b/sysdeps/htl/pt-atfork.c @@ -0,0 +1,33 @@ +/* Register fork handlers. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> +#include <fork.h> + +/* This is defined by newer gcc version unique for each module. */ +extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden"))); + +int +pthread_atfork (void (*prepare) (void), + void (*parent) (void), + void (*child) (void)) +{ + return __register_atfork (prepare, parent, child, + &__dso_handle == NULL ? NULL : __dso_handle); +} diff --git a/sysdeps/htl/pt-attr-destroy.c b/sysdeps/htl/pt-attr-destroy.c new file mode 100644 index 0000000000..a538201eb5 --- /dev/null +++ b/sysdeps/htl/pt-attr-destroy.c @@ -0,0 +1,27 @@ +/* pthread_attr_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_destroy (pthread_attr_t *attr) +{ + return 0; +} +strong_alias (__pthread_attr_destroy, pthread_attr_destroy); diff --git a/sysdeps/htl/pt-attr-getdetachstate.c b/sysdeps/htl/pt-attr-getdetachstate.c new file mode 100644 index 0000000000..5520305292 --- /dev/null +++ b/sysdeps/htl/pt-attr-getdetachstate.c @@ -0,0 +1,29 @@ +/* pthread_attr_getdetachstate. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_getdetachstate (const pthread_attr_t *attr, int *detachstate) +{ + *detachstate = attr->__detachstate; + return 0; +} + +strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate); diff --git a/sysdeps/htl/pt-attr-getguardsize.c b/sysdeps/htl/pt-attr-getguardsize.c new file mode 100644 index 0000000000..38c4f78c18 --- /dev/null +++ b/sysdeps/htl/pt-attr-getguardsize.c @@ -0,0 +1,27 @@ +/* pthread_attr_getguardsize. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_getguardsize (const pthread_attr_t *attr, size_t * guardsize) +{ + *guardsize = attr->__guardsize; + return 0; +} diff --git a/sysdeps/htl/pt-attr-getinheritsched.c b/sysdeps/htl/pt-attr-getinheritsched.c new file mode 100644 index 0000000000..1187dfa641 --- /dev/null +++ b/sysdeps/htl/pt-attr-getinheritsched.c @@ -0,0 +1,29 @@ +/* pthread_attr_getinheritsched. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_getinheritsched (const pthread_attr_t *attr, int *inheritsched) +{ + *inheritsched = attr->__inheritsched; + return 0; +} + +strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched); diff --git a/sysdeps/htl/pt-attr-getschedparam.c b/sysdeps/htl/pt-attr-getschedparam.c new file mode 100644 index 0000000000..cd86d61aca --- /dev/null +++ b/sysdeps/htl/pt-attr-getschedparam.c @@ -0,0 +1,33 @@ +/* pthread_attr_getschedparam. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <sched.h> +#include <string.h> + +#include <pt-internal.h> + +int +__pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param) +{ + memcpy (param, &attr->__schedparam, sizeof *param); + return 0; +} + +strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam); diff --git a/sysdeps/htl/pt-attr-getschedpolicy.c b/sysdeps/htl/pt-attr-getschedpolicy.c new file mode 100644 index 0000000000..49e1fedb0c --- /dev/null +++ b/sysdeps/htl/pt-attr-getschedpolicy.c @@ -0,0 +1,29 @@ +/* pthread_attr_getschedpolicy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy) +{ + *policy = attr->__schedpolicy; + return 0; +} + +strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy); diff --git a/sysdeps/htl/pt-attr-getscope.c b/sysdeps/htl/pt-attr-getscope.c new file mode 100644 index 0000000000..a48ec6d827 --- /dev/null +++ b/sysdeps/htl/pt-attr-getscope.c @@ -0,0 +1,29 @@ +/* pthread_attr_getscope. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_getscope (const pthread_attr_t *attr, int *contentionscope) +{ + *contentionscope = attr->__contentionscope; + return 0; +} + +strong_alias (__pthread_attr_getscope, pthread_attr_getscope); diff --git a/sysdeps/htl/pt-attr-getstack.c b/sysdeps/htl/pt-attr-getstack.c new file mode 100644 index 0000000000..4367c2f747 --- /dev/null +++ b/sysdeps/htl/pt-attr-getstack.c @@ -0,0 +1,30 @@ +/* pthread_attr_getstack. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_getstack (const pthread_attr_t *attr, + void **stackaddr, size_t * stacksize) +{ + pthread_attr_getstackaddr (attr, stackaddr); + pthread_attr_getstacksize (attr, stacksize); + return 0; +} +weak_alias (__pthread_attr_getstack, pthread_attr_getstack) diff --git a/sysdeps/htl/pt-attr-getstackaddr.c b/sysdeps/htl/pt-attr-getstackaddr.c new file mode 100644 index 0000000000..a043d788a7 --- /dev/null +++ b/sysdeps/htl/pt-attr-getstackaddr.c @@ -0,0 +1,27 @@ +/* pthread_attr_getstackaddr. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_getstackaddr (const pthread_attr_t *attr, void **stackaddr) +{ + *stackaddr = attr->__stackaddr; + return 0; +} diff --git a/sysdeps/htl/pt-attr-getstacksize.c b/sysdeps/htl/pt-attr-getstacksize.c new file mode 100644 index 0000000000..59c9c645db --- /dev/null +++ b/sysdeps/htl/pt-attr-getstacksize.c @@ -0,0 +1,27 @@ +/* pthread_attr_getstacksize. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_getstacksize (const pthread_attr_t *attr, size_t * stacksize) +{ + *stacksize = attr->__stacksize; + return 0; +} diff --git a/sysdeps/htl/pt-attr-init.c b/sysdeps/htl/pt-attr-init.c new file mode 100644 index 0000000000..e6ccc82a64 --- /dev/null +++ b/sysdeps/htl/pt-attr-init.c @@ -0,0 +1,28 @@ +/* pthread_attr_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_init (pthread_attr_t *attr) +{ + *attr = __pthread_default_attr; + return 0; +} +strong_alias (__pthread_attr_init, pthread_attr_init); diff --git a/sysdeps/htl/pt-attr-setdetachstate.c b/sysdeps/htl/pt-attr-setdetachstate.c new file mode 100644 index 0000000000..4907f4b56a --- /dev/null +++ b/sysdeps/htl/pt-attr-setdetachstate.c @@ -0,0 +1,38 @@ +/* pthread_attr_setdetachstate. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate) +{ + switch (detachstate) + { + case PTHREAD_CREATE_DETACHED: + case PTHREAD_CREATE_JOINABLE: + attr->__detachstate = detachstate; + break; + default: + return EINVAL; + } + + return 0; +} + +strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate); diff --git a/sysdeps/htl/pt-attr-setguardsize.c b/sysdeps/htl/pt-attr-setguardsize.c new file mode 100644 index 0000000000..97f9d3b06e --- /dev/null +++ b/sysdeps/htl/pt-attr-setguardsize.c @@ -0,0 +1,27 @@ +/* pthread_attr_setguardsize. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize) +{ + attr->__guardsize = guardsize; + return 0; +} diff --git a/sysdeps/htl/pt-attr-setinheritsched.c b/sysdeps/htl/pt-attr-setinheritsched.c new file mode 100644 index 0000000000..abbb9cb8a9 --- /dev/null +++ b/sysdeps/htl/pt-attr-setinheritsched.c @@ -0,0 +1,38 @@ +/* pthread_attr_setinheritsched. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_setinheritsched (pthread_attr_t *attr, int inheritsched) +{ + switch (inheritsched) + { + case PTHREAD_INHERIT_SCHED: + case PTHREAD_EXPLICIT_SCHED: + attr->__inheritsched = inheritsched; + break; + default: + return EINVAL; + } + + return 0; +} + +strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched); diff --git a/sysdeps/htl/pt-attr-setschedparam.c b/sysdeps/htl/pt-attr-setschedparam.c new file mode 100644 index 0000000000..c382f55499 --- /dev/null +++ b/sysdeps/htl/pt-attr-setschedparam.c @@ -0,0 +1,38 @@ +/* pthread_attr_getschedparam. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <sched.h> +#include <string.h> + +#include <pt-internal.h> + +int +__pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param) +{ + if (memcmp (param, &__pthread_default_attr.__schedparam, sizeof *param) == 0) + { + memcpy (&attr->__schedparam, param, sizeof *param); + return 0; + } + + return ENOTSUP; +} + +strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam); diff --git a/sysdeps/htl/pt-attr-setschedpolicy.c b/sysdeps/htl/pt-attr-setschedpolicy.c new file mode 100644 index 0000000000..411fc0be3c --- /dev/null +++ b/sysdeps/htl/pt-attr-setschedpolicy.c @@ -0,0 +1,42 @@ +/* pthread_attr_getschedpolicy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy) +{ + switch (policy) + { + case SCHED_OTHER: + attr->__schedpolicy = policy; + break; + + case SCHED_FIFO: + case SCHED_RR: + return ENOTSUP; + + default: + return EINVAL; + } + + return 0; +} + +strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy); diff --git a/sysdeps/htl/pt-attr-setscope.c b/sysdeps/htl/pt-attr-setscope.c new file mode 100644 index 0000000000..4e20d24de1 --- /dev/null +++ b/sysdeps/htl/pt-attr-setscope.c @@ -0,0 +1,41 @@ +/* pthread_attr_setscope. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_attr_setscope (pthread_attr_t *attr, int contentionscope) +{ + if (contentionscope == __pthread_default_attr.__contentionscope) + { + attr->__contentionscope = contentionscope; + return 0; + } + + switch (contentionscope) + { + case PTHREAD_SCOPE_PROCESS: + case PTHREAD_SCOPE_SYSTEM: + return ENOTSUP; + default: + return EINVAL; + } +} + +strong_alias (__pthread_attr_setscope, pthread_attr_setscope); diff --git a/sysdeps/htl/pt-attr-setstack.c b/sysdeps/htl/pt-attr-setstack.c new file mode 100644 index 0000000000..e538283459 --- /dev/null +++ b/sysdeps/htl/pt-attr-setstack.c @@ -0,0 +1,48 @@ +/* pthread_attr_setstack. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +int +pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize) +{ + int err; + size_t s; + + /* pthread_attr_setstack should always succeed, thus we set the size + first as it is more discriminating. */ + pthread_attr_getstacksize (attr, &s); + + err = pthread_attr_setstacksize (attr, stacksize); + if (err) + return err; + + err = pthread_attr_setstackaddr (attr, stackaddr); + if (err) + { + int e = pthread_attr_setstacksize (attr, s); + assert_perror (e); + + return err; + } + + return 0; +} diff --git a/sysdeps/htl/pt-attr-setstackaddr.c b/sysdeps/htl/pt-attr-setstackaddr.c new file mode 100644 index 0000000000..e3ca583375 --- /dev/null +++ b/sysdeps/htl/pt-attr-setstackaddr.c @@ -0,0 +1,27 @@ +/* pthread_attr_setstackaddr. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr) +{ + attr->__stackaddr = stackaddr; + return 0; +} diff --git a/sysdeps/htl/pt-attr-setstacksize.c b/sysdeps/htl/pt-attr-setstacksize.c new file mode 100644 index 0000000000..547bf675ca --- /dev/null +++ b/sysdeps/htl/pt-attr-setstacksize.c @@ -0,0 +1,28 @@ +/* pthread_attr_setstacksize. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) +{ + attr->__stacksize = stacksize; + + return 0; +} diff --git a/sysdeps/htl/pt-attr.c b/sysdeps/htl/pt-attr.c new file mode 100644 index 0000000000..f1877fdaa2 --- /dev/null +++ b/sysdeps/htl/pt-attr.c @@ -0,0 +1,39 @@ +/* Default attributes. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <sched.h> +#include <stddef.h> +#include <limits.h> + +#include <pt-internal.h> + +const struct __pthread_attr __pthread_default_attr = { + __schedparam: { sched_priority: 0 }, + __stacksize: 0, + __stackaddr: NULL, +#ifdef PAGESIZE + __guardsize: PAGESIZE, +#else + __guardsize: 1, +#endif /* PAGESIZE */ + __detachstate: PTHREAD_CREATE_JOINABLE, + __inheritsched: PTHREAD_EXPLICIT_SCHED, + __contentionscope: PTHREAD_SCOPE_SYSTEM, + __schedpolicy: SCHED_OTHER +}; diff --git a/sysdeps/htl/pt-barrier-destroy.c b/sysdeps/htl/pt-barrier-destroy.c new file mode 100644 index 0000000000..7d4f03ea37 --- /dev/null +++ b/sysdeps/htl/pt-barrier-destroy.c @@ -0,0 +1,26 @@ +/* pthread_barrier_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_barrier_destroy (pthread_barrier_t *barrier) +{ + return 0; +} diff --git a/sysdeps/htl/pt-barrier-init.c b/sysdeps/htl/pt-barrier-init.c new file mode 100644 index 0000000000..8f652d7d27 --- /dev/null +++ b/sysdeps/htl/pt-barrier-init.c @@ -0,0 +1,51 @@ +/* pthread_barrier_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <string.h> +#include <assert.h> + +#include <pt-internal.h> + +int +pthread_barrier_init (pthread_barrier_t *barrier, + const pthread_barrierattr_t *attr, unsigned count) +{ + if (count == 0) + return EINVAL; + + memset (barrier, 0, sizeof *barrier); + + barrier->__lock = PTHREAD_SPINLOCK_INITIALIZER; + barrier->__pending = count; + barrier->__count = count; + + if (attr == NULL + || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + barrier->__attr = malloc (sizeof *attr); + if (barrier->__attr == NULL) + return ENOMEM; + + *barrier->__attr = *attr; + return 0; +} diff --git a/sysdeps/htl/pt-barrier-wait.c b/sysdeps/htl/pt-barrier-wait.c new file mode 100644 index 0000000000..faac1f9d5a --- /dev/null +++ b/sysdeps/htl/pt-barrier-wait.c @@ -0,0 +1,68 @@ +/* pthread_barrier_wait. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +int +pthread_barrier_wait (pthread_barrier_t *barrier) +{ + __pthread_spin_lock (&barrier->__lock); + if (--barrier->__pending == 0) + { + barrier->__pending = barrier->__count; + + if (barrier->__count > 1) + { + struct __pthread *wakeup; + unsigned n = 0; + + __pthread_queue_iterate (barrier->__queue, wakeup) + n++; + + { + struct __pthread *wakeups[n]; + unsigned i = 0; + + __pthread_dequeuing_iterate (barrier->__queue, wakeup) + wakeups[i++] = wakeup; + + barrier->__queue = NULL; + __pthread_spin_unlock (&barrier->__lock); + + for (i = 0; i < n; i++) + __pthread_wakeup (wakeups[i]); + } + } + + return PTHREAD_BARRIER_SERIAL_THREAD; + } + else + { + struct __pthread *self = _pthread_self (); + + /* Add ourselves to the list of waiters. */ + __pthread_enqueue (&barrier->__queue, self); + __pthread_spin_unlock (&barrier->__lock); + + __pthread_block (self); + return 0; + } +} diff --git a/sysdeps/htl/pt-barrier.c b/sysdeps/htl/pt-barrier.c new file mode 100644 index 0000000000..0990ce9798 --- /dev/null +++ b/sysdeps/htl/pt-barrier.c @@ -0,0 +1,24 @@ +/* Default barrier attributes. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +const struct __pthread_barrierattr __pthread_default_barrierattr = { + __pshared: PTHREAD_PROCESS_PRIVATE +}; diff --git a/sysdeps/htl/pt-barrierattr-destroy.c b/sysdeps/htl/pt-barrierattr-destroy.c new file mode 100644 index 0000000000..c99227b7a3 --- /dev/null +++ b/sysdeps/htl/pt-barrierattr-destroy.c @@ -0,0 +1,26 @@ +/* pthread_barrierattr_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_barrierattr_destroy (pthread_barrierattr_t *attr) +{ + return 0; +} diff --git a/sysdeps/htl/pt-barrierattr-getpshared.c b/sysdeps/htl/pt-barrierattr-getpshared.c new file mode 100644 index 0000000000..3015f1c107 --- /dev/null +++ b/sysdeps/htl/pt-barrierattr-getpshared.c @@ -0,0 +1,28 @@ +/* pthread_barrierattr_getpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_barrierattr_getpshared (const pthread_barrierattr_t *attr, + int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} diff --git a/sysdeps/htl/pt-barrierattr-init.c b/sysdeps/htl/pt-barrierattr-init.c new file mode 100644 index 0000000000..b5236287cf --- /dev/null +++ b/sysdeps/htl/pt-barrierattr-init.c @@ -0,0 +1,27 @@ +/* pthread_barrierattr_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_barrierattr_init (pthread_barrierattr_t *attr) +{ + *attr = __pthread_default_barrierattr; + return 0; +} diff --git a/sysdeps/htl/pt-barrierattr-setpshared.c b/sysdeps/htl/pt-barrierattr-setpshared.c new file mode 100644 index 0000000000..52a5040b73 --- /dev/null +++ b/sysdeps/htl/pt-barrierattr-setpshared.c @@ -0,0 +1,37 @@ +/* pthread_barrierattr_setpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_barrierattr_setpshared (pthread_barrierattr_t *attr, int pshared) +{ + switch (pshared) + { + case PTHREAD_PROCESS_PRIVATE: + attr->__pshared = pshared; + return 0; + + case PTHREAD_PROCESS_SHARED: + return ENOTSUP; + + default: + return EINVAL; + } +} diff --git a/sysdeps/htl/pt-cond-brdcast.c b/sysdeps/htl/pt-cond-brdcast.c new file mode 100644 index 0000000000..fc1d65352a --- /dev/null +++ b/sysdeps/htl/pt-cond-brdcast.c @@ -0,0 +1,44 @@ +/* Broadcast a condition. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +/* Unblock all threads that are blocked on condition variable COND. */ +int +__pthread_cond_broadcast (pthread_cond_t *cond) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&cond->__lock); + while ((wakeup = cond->__queue)) + { + __pthread_dequeue (wakeup); + __pthread_spin_unlock (&cond->__lock); + /* Wake it up without spin held, so it may have a chance to really + preempt us */ + __pthread_wakeup (wakeup); + __pthread_spin_lock (&cond->__lock); + } + __pthread_spin_unlock (&cond->__lock); + + return 0; +} + +strong_alias (__pthread_cond_broadcast, pthread_cond_broadcast); diff --git a/sysdeps/htl/pt-cond-destroy.c b/sysdeps/htl/pt-cond-destroy.c new file mode 100644 index 0000000000..81c4ccfd20 --- /dev/null +++ b/sysdeps/htl/pt-cond-destroy.c @@ -0,0 +1,28 @@ +/* pthread_cond_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_cond_destroy (pthread_cond_t *cond) +{ + return 0; +} + +strong_alias (__pthread_cond_destroy, pthread_cond_destroy); diff --git a/sysdeps/htl/pt-cond-init.c b/sysdeps/htl/pt-cond-init.c new file mode 100644 index 0000000000..4c128ac86c --- /dev/null +++ b/sysdeps/htl/pt-cond-init.c @@ -0,0 +1,45 @@ +/* pthread_cond_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> +#include <string.h> + +#include <pt-internal.h> + +int +__pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t * attr) +{ + *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER; + + if (attr == NULL + || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + cond->__attr = malloc (sizeof *attr); + if (cond->__attr == NULL) + return ENOMEM; + + *cond->__attr = *attr; + return 0; +} + +strong_alias (__pthread_cond_init, pthread_cond_init); diff --git a/sysdeps/htl/pt-cond-signal.c b/sysdeps/htl/pt-cond-signal.c new file mode 100644 index 0000000000..a1c0c2adcf --- /dev/null +++ b/sysdeps/htl/pt-cond-signal.c @@ -0,0 +1,42 @@ +/* Signal a condition. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +/* Unblock at least one of the threads that are blocked on condition + variable COND. */ +int +__pthread_cond_signal (pthread_cond_t *cond) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&cond->__lock); + wakeup = cond->__queue; + if (wakeup != NULL) + __pthread_dequeue (wakeup); + __pthread_spin_unlock (&cond->__lock); + + if (wakeup != NULL) + __pthread_wakeup (wakeup); + + return 0; +} + +strong_alias (__pthread_cond_signal, pthread_cond_signal); diff --git a/sysdeps/htl/pt-cond-timedwait.c b/sysdeps/htl/pt-cond-timedwait.c new file mode 100644 index 0000000000..525e63dd42 --- /dev/null +++ b/sysdeps/htl/pt-cond-timedwait.c @@ -0,0 +1,177 @@ +/* Wait on a condition. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime); + +int +__pthread_cond_timedwait (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + return __pthread_cond_timedwait_internal (cond, mutex, abstime); +} + +strong_alias (__pthread_cond_timedwait, pthread_cond_timedwait); + +struct cancel_ctx +{ + struct __pthread *wakeup; + pthread_cond_t *cond; +}; + +static void +cancel_hook (void *arg) +{ + struct cancel_ctx *ctx = arg; + struct __pthread *wakeup = ctx->wakeup; + pthread_cond_t *cond = ctx->cond; + int unblock; + + __pthread_spin_lock (&cond->__lock); + /* The thread only needs to be awaken if it's blocking or about to block. + If it was already unblocked, it's not queued any more. */ + unblock = wakeup->prevp != NULL; + if (unblock) + __pthread_dequeue (wakeup); + __pthread_spin_unlock (&cond->__lock); + + if (unblock) + __pthread_wakeup (wakeup); +} + +/* Block on condition variable COND until ABSTIME. As a GNU + extension, if ABSTIME is NULL, then wait forever. MUTEX should be + held by the calling thread. On return, MUTEX will be held by the + calling thread. */ +int +__pthread_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + error_t err; + int cancelled, oldtype, drain; + clockid_t clock_id = __pthread_default_condattr.__clock; + + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + + struct __pthread *self = _pthread_self (); + struct cancel_ctx ctx; + ctx.wakeup = self; + ctx.cond = cond; + + /* Test for a pending cancellation request, switch to deferred mode for + safer resource handling, and prepare the hook to call in case we're + cancelled while blocking. Once CANCEL_LOCK is released, the cancellation + hook can be called by another thread at any time. Whatever happens, + this function must exit with MUTEX locked. + + This function contains inline implementations of pthread_testcancel and + pthread_setcanceltype to reduce locking overhead. */ + __pthread_mutex_lock (&self->cancel_lock); + cancelled = (self->cancel_state == PTHREAD_CANCEL_ENABLE) + && self->cancel_pending; + + if (!cancelled) + { + self->cancel_hook = cancel_hook; + self->cancel_hook_arg = &ctx; + oldtype = self->cancel_type; + + if (oldtype != PTHREAD_CANCEL_DEFERRED) + self->cancel_type = PTHREAD_CANCEL_DEFERRED; + + /* Add ourselves to the list of waiters. This is done while setting + the cancellation hook to simplify the cancellation procedure, i.e. + if the thread is queued, it can be cancelled, otherwise it is + already unblocked, progressing on the return path. */ + __pthread_spin_lock (&cond->__lock); + __pthread_enqueue (&cond->__queue, self); + if (cond->__attr != NULL) + clock_id = cond->__attr->__clock; + __pthread_spin_unlock (&cond->__lock); + } + __pthread_mutex_unlock (&self->cancel_lock); + + if (cancelled) + pthread_exit (PTHREAD_CANCELED); + + /* Release MUTEX before blocking. */ + __pthread_mutex_unlock (mutex); + + /* Block the thread. */ + if (abstime != NULL) + err = __pthread_timedblock (self, abstime, clock_id); + else + { + err = 0; + __pthread_block (self); + } + + __pthread_spin_lock (&cond->__lock); + if (self->prevp == NULL) + { + /* Another thread removed us from the list of waiters, which means a + wakeup message has been sent. It was either consumed while we were + blocking, or queued after we timed out and before we acquired the + condition lock, in which case the message queue must be drained. */ + if (!err) + drain = 0; + else + { + assert (err == ETIMEDOUT); + drain = 1; + } + } + else + { + /* We're still in the list of waiters. Noone attempted to wake us up, + i.e. we timed out. */ + assert (err == ETIMEDOUT); + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&cond->__lock); + + if (drain) + __pthread_block (self); + + /* We're almost done. Remove the unblock hook, restore the previous + cancellation type, and check for a pending cancellation request. */ + __pthread_mutex_lock (&self->cancel_lock); + self->cancel_hook = NULL; + self->cancel_hook_arg = NULL; + self->cancel_type = oldtype; + cancelled = (self->cancel_state == PTHREAD_CANCEL_ENABLE) + && self->cancel_pending; + __pthread_mutex_unlock (&self->cancel_lock); + + /* Reacquire MUTEX before returning/cancelling. */ + __pthread_mutex_lock (mutex); + + if (cancelled) + pthread_exit (PTHREAD_CANCELED); + + return err; +} diff --git a/sysdeps/htl/pt-cond-wait.c b/sysdeps/htl/pt-cond-wait.c new file mode 100644 index 0000000000..8ea7c8e980 --- /dev/null +++ b/sysdeps/htl/pt-cond-wait.c @@ -0,0 +1,38 @@ +/* Wait on a condition. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +/* Implemented in pt-cond-timedwait.c. */ +extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime); + + +/* Block on condition variable COND. MUTEX should be held by the + calling thread. On return, MUTEX will be held by the calling + thread. */ +int +__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + return __pthread_cond_timedwait_internal (cond, mutex, 0); +} + +strong_alias (__pthread_cond_wait, pthread_cond_wait); diff --git a/sysdeps/htl/pt-cond.c b/sysdeps/htl/pt-cond.c new file mode 100644 index 0000000000..2dc6c51f29 --- /dev/null +++ b/sysdeps/htl/pt-cond.c @@ -0,0 +1,27 @@ +/* Default condition attributes. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <time.h> + +#include <pt-internal.h> + +const struct __pthread_condattr __pthread_default_condattr = { + __pshared: PTHREAD_PROCESS_PRIVATE, + __clock: CLOCK_REALTIME +}; diff --git a/sysdeps/htl/pt-condattr-destroy.c b/sysdeps/htl/pt-condattr-destroy.c new file mode 100644 index 0000000000..7399858d45 --- /dev/null +++ b/sysdeps/htl/pt-condattr-destroy.c @@ -0,0 +1,28 @@ +/* pthread_condattr_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_condattr_destroy (pthread_condattr_t *cond) +{ + return 0; +} + +strong_alias (__pthread_condattr_destroy, pthread_condattr_destroy); diff --git a/sysdeps/htl/pt-condattr-getclock.c b/sysdeps/htl/pt-condattr-getclock.c new file mode 100644 index 0000000000..6c603e1b0b --- /dev/null +++ b/sysdeps/htl/pt-condattr-getclock.c @@ -0,0 +1,29 @@ +/* pthread_condattr_getclock. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <time.h> + +#include <pt-internal.h> + +int +pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t * clock) +{ + *clock = attr->__clock; + return 0; +} diff --git a/sysdeps/htl/pt-condattr-getpshared.c b/sysdeps/htl/pt-condattr-getpshared.c new file mode 100644 index 0000000000..4f51f7ed43 --- /dev/null +++ b/sysdeps/htl/pt-condattr-getpshared.c @@ -0,0 +1,27 @@ +/* pthread_condattr_getpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} diff --git a/sysdeps/htl/pt-condattr-init.c b/sysdeps/htl/pt-condattr-init.c new file mode 100644 index 0000000000..ec392e13d7 --- /dev/null +++ b/sysdeps/htl/pt-condattr-init.c @@ -0,0 +1,29 @@ +/* pthread_condattr_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_condattr_init (pthread_condattr_t *attr) +{ + *attr = __pthread_default_condattr; + return 0; +} + +strong_alias (__pthread_condattr_init, pthread_condattr_init); diff --git a/sysdeps/htl/pt-condattr-setclock.c b/sysdeps/htl/pt-condattr-setclock.c new file mode 100644 index 0000000000..fa3e14a0d3 --- /dev/null +++ b/sysdeps/htl/pt-condattr-setclock.c @@ -0,0 +1,51 @@ +/* pthread_condattr_setclock. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock) +{ + /* Only a few clocks are allowed. CLOCK_REALTIME is always allowed. + CLOCK_MONOTONIC only if the kernel has the necessary support. */ + if (clock == CLOCK_MONOTONIC) + { + /* Check whether the clock is available. */ + static int avail; + + if (avail == 0) + { + struct timespec ts; + int res; + + res = clock_gettime (CLOCK_MONOTONIC, &ts); + avail = res < 0 ? -1 : 1; + } + + if (avail < 0) + /* Not available. */ + return EINVAL; + } + else if (clock != CLOCK_REALTIME) + return EINVAL; + + attr->__clock = clock; + + return 0; +} diff --git a/sysdeps/htl/pt-condattr-setpshared.c b/sysdeps/htl/pt-condattr-setpshared.c new file mode 100644 index 0000000000..9283a681fe --- /dev/null +++ b/sysdeps/htl/pt-condattr-setpshared.c @@ -0,0 +1,37 @@ +/* pthread_condattr_setpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared) +{ + switch (pshared) + { + case PTHREAD_PROCESS_PRIVATE: + attr->__pshared = pshared; + return 0; + + case PTHREAD_PROCESS_SHARED: + return ENOTSUP; + + default: + return EINVAL; + } +} diff --git a/sysdeps/htl/pt-destroy-specific.c b/sysdeps/htl/pt-destroy-specific.c new file mode 100644 index 0000000000..523a62007d --- /dev/null +++ b/sysdeps/htl/pt-destroy-specific.c @@ -0,0 +1,77 @@ +/* __pthread_destory_specific. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdlib.h> + +#include <pt-internal.h> + +void +__pthread_destroy_specific (struct __pthread *thread) +{ + int i; + int seen_one; + + /* Check if there is any thread specific data. */ + if (thread->thread_specifics == NULL) + return; + + __pthread_key_lock_ready (); + + /* Iterate and call the destructors on any thread specific data. */ + for (;;) + { + seen_one = 0; + + __pthread_mutex_lock (&__pthread_key_lock); + + for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size; + i++) + { + void *value; + + if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID) + continue; + + value = thread->thread_specifics[i]; + if (value != NULL) + { + thread->thread_specifics[i] = 0; + + if (__pthread_key_destructors[i]) + { + seen_one = 1; + __pthread_key_destructors[i] (value); + } + } + } + + __pthread_mutex_unlock (&__pthread_key_lock); + + if (!seen_one) + break; + + /* This may take a very long time. Let those blocking on + pthread_key_create or pthread_key_delete make progress. */ + sched_yield (); + } + + free (thread->thread_specifics); + thread->thread_specifics = 0; + thread->thread_specifics_size = 0; +} diff --git a/sysdeps/htl/pt-equal.c b/sysdeps/htl/pt-equal.c new file mode 100644 index 0000000000..11ded7adf5 --- /dev/null +++ b/sysdeps/htl/pt-equal.c @@ -0,0 +1,30 @@ +/* Default attributes. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +/* Return true if __T1 and __T2 both name the same thread. Otherwise, + false. */ +int +__pthread_equal (pthread_t __t1, pthread_t __t2) +{ + return __t1 == __t2; +} + +strong_alias (__pthread_equal, pthread_equal); diff --git a/sysdeps/htl/pt-getconcurrency.c b/sysdeps/htl/pt-getconcurrency.c new file mode 100644 index 0000000000..4b959019a1 --- /dev/null +++ b/sysdeps/htl/pt-getconcurrency.c @@ -0,0 +1,26 @@ +/* Get the current level of desired concurrency. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_getconcurrency (void) +{ + return __pthread_concurrency; +} diff --git a/sysdeps/htl/pt-getcpuclockid.c b/sysdeps/htl/pt-getcpuclockid.c new file mode 100644 index 0000000000..e4c7e87a3e --- /dev/null +++ b/sysdeps/htl/pt-getcpuclockid.c @@ -0,0 +1,35 @@ +/* Return a thread's cpu clockid. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <time.h> + +#include <pt-internal.h> + +int +pthread_getcpuclockid (pthread_t thread, clockid_t *clock) +{ +#ifdef CLOCK_THREAD_CPUTIME_ID + *clock = CLOCK_THREAD_CPUTIME_ID; + return 0; +#else + return ENOSYS; +#endif +} + +stub_warning (pthread_getcpuclockid) diff --git a/sysdeps/htl/pt-getschedparam.c b/sysdeps/htl/pt-getschedparam.c new file mode 100644 index 0000000000..2d8328719e --- /dev/null +++ b/sysdeps/htl/pt-getschedparam.c @@ -0,0 +1,31 @@ +/* Get the scheduling parameters for a thread. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_getschedparam (pthread_t thread, int *policy, + struct sched_param *param) +{ + *policy = SCHED_OTHER; + param->sched_priority = 0; + return 0; +} + +strong_alias (__pthread_getschedparam, pthread_getschedparam); diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c new file mode 100644 index 0000000000..70e1f6c01d --- /dev/null +++ b/sysdeps/htl/pt-getspecific.c @@ -0,0 +1,38 @@ +/* pthread_getspecific. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +void * +__pthread_getspecific (pthread_key_t key) +{ + struct __pthread *self; + + if (key < 0 || key >= __pthread_key_count + || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID) + return NULL; + + self = _pthread_self (); + if (key >= self->thread_specifics_size) + return 0; + + return self->thread_specifics[key]; +} +strong_alias (__pthread_getspecific, pthread_getspecific); diff --git a/sysdeps/htl/pt-init-specific.c b/sysdeps/htl/pt-init-specific.c new file mode 100644 index 0000000000..841ba27c42 --- /dev/null +++ b/sysdeps/htl/pt-init-specific.c @@ -0,0 +1,30 @@ +/* __pthread_init_specific. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdlib.h> + +#include <pt-internal.h> + +error_t +__pthread_init_specific (struct __pthread *thread) +{ + thread->thread_specifics = 0; + thread->thread_specifics_size = 0; + return 0; +} diff --git a/sysdeps/htl/pt-key-create.c b/sysdeps/htl/pt-key-create.c new file mode 100644 index 0000000000..194acc3cea --- /dev/null +++ b/sysdeps/htl/pt-key-create.c @@ -0,0 +1,108 @@ +/* pthread_key_create. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> + +#include <pt-internal.h> + +pthread_mutex_t __pthread_key_lock; + +void (**__pthread_key_destructors) (void *arg); +int __pthread_key_size; +int __pthread_key_count; +int __pthread_key_invalid_count; + +int +__pthread_key_create (pthread_key_t *key, void (*destructor) (void *)) +{ + /* Where to look for the next key slot. */ + static int index; + + __pthread_key_lock_ready (); + + __pthread_mutex_lock (&__pthread_key_lock); + +do_search: + /* Use the search hint and try to find a free slot. */ + for (; index < __pthread_key_count + && __pthread_key_destructors[index] != PTHREAD_KEY_INVALID; index++) + ; + + /* See if we actually found a free element. */ + if (index < __pthread_key_count) + { + assert (__pthread_key_destructors[index] == PTHREAD_KEY_INVALID); + assert (__pthread_key_invalid_count > 0); + + __pthread_key_invalid_count--; + __pthread_key_destructors[index] = destructor; + *key = index++; + + __pthread_mutex_unlock (&__pthread_key_lock); + return 0; + } + + assert (index == __pthread_key_count); + + /* No space at the end. */ + if (__pthread_key_size == __pthread_key_count) + { + /* See if it is worth looking for a free element. */ + if (__pthread_key_invalid_count > 4 + && __pthread_key_invalid_count > __pthread_key_size / 8) + { + index = 0; + goto do_search; + } + + + /* Resize the array. */ + { + void *t; + int newsize; + + if (__pthread_key_size == 0) + newsize = 8; + else + newsize = __pthread_key_size * 2; + + t = realloc (__pthread_key_destructors, + newsize * sizeof (*__pthread_key_destructors)); + if (t == NULL) + { + __pthread_mutex_unlock (&__pthread_key_lock); + return ENOMEM; + } + + __pthread_key_size = newsize; + __pthread_key_destructors = t; + } + } + + __pthread_key_destructors[index] = destructor; + *key = index; + + index++; + __pthread_key_count++; + + __pthread_mutex_unlock (&__pthread_key_lock); + return 0; +} +strong_alias (__pthread_key_create, pthread_key_create) diff --git a/sysdeps/htl/pt-key-delete.c b/sysdeps/htl/pt-key-delete.c new file mode 100644 index 0000000000..e9b5665c31 --- /dev/null +++ b/sysdeps/htl/pt-key-delete.c @@ -0,0 +1,63 @@ +/* pthread_key_delete. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +int +pthread_key_delete (pthread_key_t key) +{ + error_t err = 0; + + __pthread_key_lock_ready (); + + __pthread_mutex_lock (&__pthread_key_lock); + + if (key < 0 || key >= __pthread_key_count + || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID) + err = EINVAL; + else + { + int i; + + __pthread_key_destructors[key] = PTHREAD_KEY_INVALID; + __pthread_key_invalid_count++; + + __pthread_rwlock_rdlock (&__pthread_threads_lock); + for (i = 0; i < __pthread_num_threads; ++i) + { + struct __pthread *t; + + t = __pthread_threads[i]; + + if (t == NULL) + continue; + + /* Just remove the key, no need to care whether it was + already there. */ + if (key < t->thread_specifics_size) + t->thread_specifics[key] = 0; + } + __pthread_rwlock_unlock (&__pthread_threads_lock); + } + + __pthread_mutex_unlock (&__pthread_key_lock); + + return err; +} diff --git a/sysdeps/htl/pt-key.h b/sysdeps/htl/pt-key.h new file mode 100644 index 0000000000..d1d4b765a5 --- /dev/null +++ b/sysdeps/htl/pt-key.h @@ -0,0 +1,76 @@ +/* pthread_key internal declatations for the Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <libc-lockP.h> + +#define PTHREAD_KEY_MEMBERS \ + void **thread_specifics; /* This is only resized by the thread, and always growing */ \ + unsigned thread_specifics_size; /* Number of entries in thread_specifics */ + +#define PTHREAD_KEY_INVALID (void *) (-1) + + +/* __PTHREAD_KEY_DESTRUCTORS is an array of destructors with + __PTHREAD_KEY_SIZE elements. If an element with index less than + __PTHREAD_KEY_COUNT is invalid, it shall contain the value + PTHREAD_KEY_INVALID which shall be distinct from NULL. + + Normally, we just add new keys to the end of the array and realloc + it as necessary. The pthread_key_create routine may decide to + rescan the array if __PTHREAD_KEY_FREE is large. */ +extern void (**__pthread_key_destructors) (void *arg); +extern int __pthread_key_size; +extern int __pthread_key_count; +/* Number of invalid elements in the array. Does not include elements + for which memory has been allocated but which have not yet been + used (i.e. those elements with indexes greater than + __PTHREAD_KEY_COUNT). */ +extern int __pthread_key_invalid_count; + +/* Protects the above variables. This must be a recursive lock: the + destructors may call pthread_key_delete. */ +extern pthread_mutex_t __pthread_key_lock; + +#include <assert.h> + +static inline void +__pthread_key_lock_ready (void) +{ + static pthread_once_t o = PTHREAD_ONCE_INIT; + + void do_init (void) + { + int err; + pthread_mutexattr_t attr; + + err = __pthread_mutexattr_init (&attr); + assert_perror (err); + + err = __pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); + assert_perror (err); + + err = _pthread_mutex_init (&__pthread_key_lock, &attr); + assert_perror (err); + + err = __pthread_mutexattr_destroy (&attr); + assert_perror (err); + } + + __pthread_once (&o, do_init); +} diff --git a/sysdeps/htl/pt-kill.c b/sysdeps/htl/pt-kill.c new file mode 100644 index 0000000000..7f7a39eb57 --- /dev/null +++ b/sysdeps/htl/pt-kill.c @@ -0,0 +1,33 @@ +/* pthread-kill.c - Generic pthread-kill implementation. + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pthreadP.h> +#include "sig-internal.h" + +int +__pthread_kill (pthread_t tid, int signo) +{ + siginfo_t si; + memset (&si, 0, sizeof (si)); + si.si_signo = signo; + + return pthread_kill_siginfo_np (tid, si); +} +strong_alias (__pthread_kill, pthread_kill) diff --git a/sysdeps/htl/pt-mutex-destroy.c b/sysdeps/htl/pt-mutex-destroy.c new file mode 100644 index 0000000000..17b30838d0 --- /dev/null +++ b/sysdeps/htl/pt-mutex-destroy.c @@ -0,0 +1,38 @@ +/* Destroy a mutex. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> + +#include <pt-internal.h> + +int +_pthread_mutex_destroy (pthread_mutex_t *mutex) +{ + if (mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR) + /* Static attributes. */ + ; + else + free (mutex->__attr); + + return 0; +} + +strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy); diff --git a/sysdeps/htl/pt-mutex-getprioceiling.c b/sysdeps/htl/pt-mutex-getprioceiling.c new file mode 100644 index 0000000000..66833b857f --- /dev/null +++ b/sysdeps/htl/pt-mutex-getprioceiling.c @@ -0,0 +1,28 @@ +/* Get a mutex' priority ceiling. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling) +{ + return ENOSYS; +} + +stub_warning (pthread_mutex_getprioceiling) diff --git a/sysdeps/htl/pt-mutex-init.c b/sysdeps/htl/pt-mutex-init.c new file mode 100644 index 0000000000..ee3ca9aec4 --- /dev/null +++ b/sysdeps/htl/pt-mutex-init.c @@ -0,0 +1,48 @@ +/* Initialize a mutex. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#include <pt-internal.h> + +int +_pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER; + + if (attr == NULL + || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0)) + /* The default attributes. */ + return 0; + + if (mutex->__attr == NULL + || mutex->__attr == __PTHREAD_ERRORCHECK_MUTEXATTR + || mutex->__attr == __PTHREAD_RECURSIVE_MUTEXATTR) + mutex->__attr = malloc (sizeof *attr); + + if (mutex->__attr == NULL) + return ENOMEM; + + *mutex->__attr = *attr; + return 0; +} + +strong_alias (_pthread_mutex_init, pthread_mutex_init); diff --git a/sysdeps/htl/pt-mutex-lock.c b/sysdeps/htl/pt-mutex-lock.c new file mode 100644 index 0000000000..6a82627c0f --- /dev/null +++ b/sysdeps/htl/pt-mutex-lock.c @@ -0,0 +1,36 @@ +/* Lock a mutex. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Implemented in pt-mutex-timedlock.c. */ +extern int __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, + const struct timespec *abstime); + +/* Lock MUTEX, block if we can't get it. */ +int +__pthread_mutex_lock (struct __pthread_mutex *mutex) +{ + return __pthread_mutex_timedlock_internal (mutex, 0); +} + +strong_alias (__pthread_mutex_lock, _pthread_mutex_lock); +strong_alias (__pthread_mutex_lock, pthread_mutex_lock); diff --git a/sysdeps/htl/pt-mutex-setprioceiling.c b/sysdeps/htl/pt-mutex-setprioceiling.c new file mode 100644 index 0000000000..ea02188bf5 --- /dev/null +++ b/sysdeps/htl/pt-mutex-setprioceiling.c @@ -0,0 +1,28 @@ +/* Set a mutex' priority ceiling. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prio, int *oldprio) +{ + return ENOSYS; +} + +stub_warning (pthread_mutex_setprioceiling) diff --git a/sysdeps/htl/pt-mutex-timedlock.c b/sysdeps/htl/pt-mutex-timedlock.c new file mode 100644 index 0000000000..2a64c53e9e --- /dev/null +++ b/sysdeps/htl/pt-mutex-timedlock.c @@ -0,0 +1,195 @@ +/* Lock a mutex with a timeout. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +#define LOSE do { * (int *) 0 = 0; } while (1) + +/* Try to lock MUTEX, block until *ABSTIME if it is already held. As + a GNU extension, if TIMESPEC is NULL then wait forever. */ +int +__pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, + const struct timespec *abstime) +{ + error_t err; + int drain; + struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->__attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + __pthread_spin_lock (&mutex->__lock); + if (__pthread_spin_trylock (&mutex->__held) == 0) + /* Successfully acquired the lock. */ + { +#ifdef ALWAYS_TRACK_MUTEX_OWNER +# ifndef NDEBUG + self = _pthread_self (); + if (self != NULL) + /* The main thread may take a lock before the library is fully + initialized, in particular, before the main thread has a + TCB. */ + { + assert (mutex->__owner == NULL); + mutex->__owner = _pthread_self (); + } +# endif +#endif + + if (attr != NULL) + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_NORMAL: + break; + + case PTHREAD_MUTEX_RECURSIVE: + mutex->__locks = 1; + case PTHREAD_MUTEX_ERRORCHECK: + mutex->__owner = _pthread_self (); + break; + + default: + LOSE; + } + + __pthread_spin_unlock (&mutex->__lock); + return 0; + } + + /* The lock is busy. */ + + self = _pthread_self (); + assert (self); + + if (attr == NULL || attr->__mutex_type == PTHREAD_MUTEX_NORMAL) + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) + assert (mutex->__owner != self); +#endif + } + else + { + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_ERRORCHECK: + if (mutex->__owner == self) + { + __pthread_spin_unlock (&mutex->__lock); + return EDEADLK; + } + break; + + case PTHREAD_MUTEX_RECURSIVE: + if (mutex->__owner == self) + { + mutex->__locks++; + __pthread_spin_unlock (&mutex->__lock); + return 0; + } + break; + + default: + LOSE; + } + } + +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + assert (mutex->__owner); + + if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + + /* Add ourselves to the queue. */ + __pthread_enqueue (&mutex->__queue, self); + __pthread_spin_unlock (&mutex->__lock); + + /* Block the thread. */ + if (abstime != NULL) + err = __pthread_timedblock (self, abstime, CLOCK_REALTIME); + else + { + err = 0; + __pthread_block (self); + } + + __pthread_spin_lock (&mutex->__lock); + if (self->prevp == NULL) + /* Another thread removed us from the queue, which means a wakeup message + has been sent. It was either consumed while we were blocking, or + queued after we timed out and before we acquired the mutex lock, in + which case the message queue must be drained. */ + drain = err ? 1 : 0; + else + { + /* We're still in the queue. Noone attempted to wake us up, i.e. we + timed out. */ + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&mutex->__lock); + + if (drain) + __pthread_block (self); + + if (err) + { + assert (err == ETIMEDOUT); + return err; + } + +#if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL) +#endif + { + assert (mutex->__owner == self); + } + + if (attr != NULL) + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_NORMAL: + break; + + case PTHREAD_MUTEX_RECURSIVE: + assert (mutex->__locks == 0); + mutex->__locks = 1; + case PTHREAD_MUTEX_ERRORCHECK: + mutex->__owner = self; + break; + + default: + LOSE; + } + + return 0; +} + +int +pthread_mutex_timedlock (struct __pthread_mutex *mutex, + const struct timespec *abstime) +{ + return __pthread_mutex_timedlock_internal (mutex, abstime); +} diff --git a/sysdeps/htl/pt-mutex-transfer-np.c b/sysdeps/htl/pt-mutex-transfer-np.c new file mode 100644 index 0000000000..e208ac1b58 --- /dev/null +++ b/sysdeps/htl/pt-mutex-transfer-np.c @@ -0,0 +1,66 @@ +/* Transfer ownership of a mutex. Generic version. + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__pthread_mutex_transfer_np (struct __pthread_mutex *mutex, pthread_t tid) +{ + assert (mutex->__owner == _pthread_self ()); + + struct __pthread *thread = __pthread_getid (tid); + const struct __pthread_mutexattr *attr = mutex->__attr; + + if (thread == NULL) + return ESRCH; + + if (thread == _pthread_self ()) + return 0; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + if (attr != NULL && attr->__mutex_type == PTHREAD_MUTEX_ERRORCHECK) + { + + if (mutex->__owner != _pthread_self ()) + return EPERM; + + mutex->__owner = thread; + } + +#ifndef NDEBUG +# if !defined(ALWAYS_TRACK_MUTEX_OWNER) + if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL) +# endif + { + mutex->__owner = thread; + } +#endif + + return 0; +} + +strong_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np) diff --git a/sysdeps/htl/pt-mutex-trylock.c b/sysdeps/htl/pt-mutex-trylock.c new file mode 100644 index 0000000000..b19611b229 --- /dev/null +++ b/sysdeps/htl/pt-mutex-trylock.c @@ -0,0 +1,111 @@ +/* Try to Lock a mutex. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +#define LOSE do { * (int *) 0 = 0; } while (1) + +/* Lock MUTEX, return EBUSY if we can't get it. */ +int +__pthread_mutex_trylock (struct __pthread_mutex *mutex) +{ + int err; + struct __pthread *self; + const struct __pthread_mutexattr *attr = mutex->__attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + __pthread_spin_lock (&mutex->__lock); + if (__pthread_spin_trylock (&mutex->__held) == 0) + /* Acquired the lock. */ + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) +# ifndef NDEBUG + self = _pthread_self (); + if (self != NULL) + /* The main thread may take a lock before the library is fully + initialized, in particular, before the main thread has a + TCB. */ + { + assert (mutex->__owner == NULL); + mutex->__owner = _pthread_self (); + } +# endif +#endif + + if (attr != NULL) + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_NORMAL: + break; + + case PTHREAD_MUTEX_RECURSIVE: + mutex->__locks = 1; + case PTHREAD_MUTEX_ERRORCHECK: + mutex->__owner = _pthread_self (); + break; + + default: + LOSE; + } + + __pthread_spin_unlock (&mutex->__lock); + return 0; + } + + err = EBUSY; + + if (attr != NULL) + { + self = _pthread_self (); + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_NORMAL: + break; + + case PTHREAD_MUTEX_ERRORCHECK: + /* We could check if MUTEX->OWNER is SELF, however, POSIX + does not permit pthread_mutex_trylock to return EDEADLK + instead of EBUSY, only pthread_mutex_lock. */ + break; + + case PTHREAD_MUTEX_RECURSIVE: + if (mutex->__owner == self) + { + mutex->__locks++; + err = 0; + } + break; + + default: + LOSE; + } + } + + __pthread_spin_unlock (&mutex->__lock); + + return err; +} + +strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock); +strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock); diff --git a/sysdeps/htl/pt-mutex-unlock.c b/sysdeps/htl/pt-mutex-unlock.c new file mode 100644 index 0000000000..e46a913965 --- /dev/null +++ b/sysdeps/htl/pt-mutex-unlock.c @@ -0,0 +1,107 @@ +/* Unlock a mutex. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +#define LOSE do { * (int *) 0 = 0; } while (1) + +/* Unlock MUTEX, rescheduling a waiting thread. */ +int +__pthread_mutex_unlock (pthread_mutex_t *mutex) +{ + struct __pthread *wakeup; + const struct __pthread_mutexattr *attr = mutex->__attr; + + if (attr == __PTHREAD_ERRORCHECK_MUTEXATTR) + attr = &__pthread_errorcheck_mutexattr; + if (attr == __PTHREAD_RECURSIVE_MUTEXATTR) + attr = &__pthread_recursive_mutexattr; + + __pthread_spin_lock (&mutex->__lock); + + if (attr == NULL || attr->__mutex_type == PTHREAD_MUTEX_NORMAL) + { +#if defined(ALWAYS_TRACK_MUTEX_OWNER) +# ifndef NDEBUG + if (_pthread_self ()) + { + assert (mutex->__owner); + assert (mutex->__owner == _pthread_self ()); + mutex->__owner = NULL; + } +# endif +#endif + } + else + switch (attr->__mutex_type) + { + case PTHREAD_MUTEX_ERRORCHECK: + case PTHREAD_MUTEX_RECURSIVE: + if (mutex->__owner != _pthread_self ()) + { + __pthread_spin_unlock (&mutex->__lock); + return EPERM; + } + + if (attr->__mutex_type == PTHREAD_MUTEX_RECURSIVE) + if (--mutex->__locks > 0) + { + __pthread_spin_unlock (&mutex->__lock); + return 0; + } + + mutex->__owner = 0; + break; + + default: + LOSE; + } + + + if (mutex->__queue == NULL) + { + __pthread_spin_unlock (&mutex->__held); + __pthread_spin_unlock (&mutex->__lock); + return 0; + } + + wakeup = mutex->__queue; + __pthread_dequeue (wakeup); + +#ifndef NDEBUG +# if !defined (ALWAYS_TRACK_MUTEX_OWNER) + if (attr != NULL && attr->__mutex_type != PTHREAD_MUTEX_NORMAL) +# endif + { + mutex->__owner = wakeup; + } +#endif + + /* We do not unlock MUTEX->held: we are transferring the ownership + to the thread that we are waking up. */ + + __pthread_spin_unlock (&mutex->__lock); + __pthread_wakeup (wakeup); + + return 0; +} + +strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock); +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock); diff --git a/sysdeps/htl/pt-mutexattr-destroy.c b/sysdeps/htl/pt-mutexattr-destroy.c new file mode 100644 index 0000000000..a43cf7d028 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-destroy.c @@ -0,0 +1,27 @@ +/* pthread_mutexattr_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_mutexattr_destroy (pthread_mutexattr_t *attr) +{ + return 0; +} +weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy) diff --git a/sysdeps/htl/pt-mutexattr-getprioceiling.c b/sysdeps/htl/pt-mutexattr-getprioceiling.c new file mode 100644 index 0000000000..9e13910afd --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-getprioceiling.c @@ -0,0 +1,29 @@ +/* pthread_mutexattr_getprioceiling. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *attr, + int *prioceiling) +{ + return ENOSYS; +} + +stub_warning (pthread_mutexattr_getprioceiling) diff --git a/sysdeps/htl/pt-mutexattr-getprotocol.c b/sysdeps/htl/pt-mutexattr-getprotocol.c new file mode 100644 index 0000000000..cef51d2073 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-getprotocol.c @@ -0,0 +1,27 @@ +/* pthread_mutexattr_getprotocol. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attr, int *protocol) +{ + *protocol = attr->__protocol; + return 0; +} diff --git a/sysdeps/htl/pt-mutexattr-getpshared.c b/sysdeps/htl/pt-mutexattr-getpshared.c new file mode 100644 index 0000000000..3afcb50918 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-getpshared.c @@ -0,0 +1,27 @@ +/* pthread_mutexattr_getpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_getpshared (const pthread_mutexattr_t *attr, int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} diff --git a/sysdeps/htl/pt-mutexattr-gettype.c b/sysdeps/htl/pt-mutexattr-gettype.c new file mode 100644 index 0000000000..aa5639c44e --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-gettype.c @@ -0,0 +1,27 @@ +/* pthread_mutexattr_gettype. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_gettype (const pthread_mutexattr_t *attr, int *type) +{ + *type = attr->__mutex_type; + return 0; +} diff --git a/sysdeps/htl/pt-mutexattr-init.c b/sysdeps/htl/pt-mutexattr-init.c new file mode 100644 index 0000000000..bb90ce7221 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-init.c @@ -0,0 +1,28 @@ +/* pthread_mutexattr_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_mutexattr_init (pthread_mutexattr_t *attr) +{ + *attr = __pthread_default_mutexattr; + return 0; +} +weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init) diff --git a/sysdeps/htl/pt-mutexattr-setprioceiling.c b/sysdeps/htl/pt-mutexattr-setprioceiling.c new file mode 100644 index 0000000000..8a0f86f3fb --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-setprioceiling.c @@ -0,0 +1,28 @@ +/* pthread_mutexattr_setprioceiling. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attr, int prioceiling) +{ + return ENOSYS; +} + +stub_warning (pthread_mutexattr_setprioceiling) diff --git a/sysdeps/htl/pt-mutexattr-setprotocol.c b/sysdeps/htl/pt-mutexattr-setprotocol.c new file mode 100644 index 0000000000..ffd21c26d7 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-setprotocol.c @@ -0,0 +1,40 @@ +/* pthread_mutexattr_setprotocol. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_setprotocol (pthread_mutexattr_t *attr, int protocol) +{ + if (protocol == __pthread_default_mutexattr.__protocol) + { + attr->__protocol = protocol; + return 0; + } + + switch (protocol) + { + case PTHREAD_PRIO_NONE: + case PTHREAD_PRIO_INHERIT: + case PTHREAD_PRIO_PROTECT: + return ENOTSUP; + default: + return EINVAL; + } +} diff --git a/sysdeps/htl/pt-mutexattr-setpshared.c b/sysdeps/htl/pt-mutexattr-setpshared.c new file mode 100644 index 0000000000..759def04f0 --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-setpshared.c @@ -0,0 +1,37 @@ +/* pthread_mutexattr_setpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared) +{ + switch (pshared) + { + case PTHREAD_PROCESS_PRIVATE: + attr->__pshared = pshared; + return 0; + + case PTHREAD_PROCESS_SHARED: + return ENOTSUP; + + default: + return EINVAL; + } +} diff --git a/sysdeps/htl/pt-mutexattr-settype.c b/sysdeps/htl/pt-mutexattr-settype.c new file mode 100644 index 0000000000..9dc5ba01cd --- /dev/null +++ b/sysdeps/htl/pt-mutexattr-settype.c @@ -0,0 +1,37 @@ +/* pthread_mutexattr_settype. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type) +{ + switch (type) + { + case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_ERRORCHECK: + case PTHREAD_MUTEX_RECURSIVE: + attr->__mutex_type = type; + return 0; + + default: + return EINVAL; + } +} +weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype) diff --git a/sysdeps/htl/pt-mutexattr.c b/sysdeps/htl/pt-mutexattr.c new file mode 100644 index 0000000000..ba55ebd7ad --- /dev/null +++ b/sysdeps/htl/pt-mutexattr.c @@ -0,0 +1,41 @@ +/* Default mutex attributes. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +const struct __pthread_mutexattr __pthread_default_mutexattr = { + __prioceiling: 0, + __protocol: PTHREAD_PRIO_NONE, + __pshared: PTHREAD_PROCESS_PRIVATE, + __mutex_type: PTHREAD_MUTEX_DEFAULT +}; + +const struct __pthread_mutexattr __pthread_errorcheck_mutexattr = { + __prioceiling: 0, + __protocol: PTHREAD_PRIO_NONE, + __pshared: PTHREAD_PROCESS_PRIVATE, + __mutex_type: PTHREAD_MUTEX_ERRORCHECK +}; + +const struct __pthread_mutexattr __pthread_recursive_mutexattr = { + __prioceiling: 0, + __protocol: PTHREAD_PRIO_NONE, + __pshared: PTHREAD_PROCESS_PRIVATE, + __mutex_type: PTHREAD_MUTEX_RECURSIVE +}; diff --git a/sysdeps/htl/pt-once.c b/sysdeps/htl/pt-once.c new file mode 100644 index 0000000000..a3a139adc8 --- /dev/null +++ b/sysdeps/htl/pt-once.c @@ -0,0 +1,44 @@ +/* pthread_once. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <atomic.h> + +#include <pt-internal.h> + +int +__pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) +{ + atomic_full_barrier (); + if (once_control->__run == 0) + { + __pthread_spin_lock (&once_control->__lock); + + if (once_control->__run == 0) + { + init_routine (); + atomic_full_barrier (); + once_control->__run = 1; + } + + __pthread_spin_unlock (&once_control->__lock); + } + + return 0; +} +strong_alias (__pthread_once, pthread_once); diff --git a/sysdeps/htl/pt-rwlock-attr.c b/sysdeps/htl/pt-rwlock-attr.c new file mode 100644 index 0000000000..a4814fc72c --- /dev/null +++ b/sysdeps/htl/pt-rwlock-attr.c @@ -0,0 +1,24 @@ +/* Default rwlock attributes. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +const struct __pthread_rwlockattr __pthread_default_rwlockattr = { + __pshared: PTHREAD_PROCESS_PRIVATE +}; diff --git a/sysdeps/htl/pt-rwlock-destroy.c b/sysdeps/htl/pt-rwlock-destroy.c new file mode 100644 index 0000000000..8261a184c6 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-destroy.c @@ -0,0 +1,28 @@ +/* Destroy a rwlock. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +_pthread_rwlock_destroy (pthread_rwlock_t *rwlock) +{ + return 0; +} + +strong_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy); diff --git a/sysdeps/htl/pt-rwlock-init.c b/sysdeps/htl/pt-rwlock-init.c new file mode 100644 index 0000000000..0ef84320f9 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-init.c @@ -0,0 +1,44 @@ +/* Initialize a rwlock. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <string.h> +#include <pt-internal.h> + +int +_pthread_rwlock_init (pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) +{ + *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER; + + if (attr == NULL + || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + rwlock->__attr = malloc (sizeof *attr); + if (rwlock->__attr == NULL) + return ENOMEM; + + *rwlock->__attr = *attr; + return 0; +} + +strong_alias (_pthread_rwlock_init, pthread_rwlock_init); diff --git a/sysdeps/htl/pt-rwlock-rdlock.c b/sysdeps/htl/pt-rwlock-rdlock.c new file mode 100644 index 0000000000..4592e1ae2c --- /dev/null +++ b/sysdeps/htl/pt-rwlock-rdlock.c @@ -0,0 +1,34 @@ +/* Acquire a rwlock for reading. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +/* Implemented in pt-rwlock-timedrdlock.c. */ +extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock + *rwlock, + const struct timespec + *abstime); + +/* Acquire RWLOCK for reading, block if we can't get it. */ +int +__pthread_rwlock_rdlock (struct __pthread_rwlock *rwlock) +{ + return __pthread_rwlock_timedrdlock_internal (rwlock, 0); +} +weak_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock); diff --git a/sysdeps/htl/pt-rwlock-timedrdlock.c b/sysdeps/htl/pt-rwlock-timedrdlock.c new file mode 100644 index 0000000000..60dd97f28a --- /dev/null +++ b/sysdeps/htl/pt-rwlock-timedrdlock.c @@ -0,0 +1,120 @@ +/* Acquire a rwlock for reading. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if + it is already held. As a GNU extension, if TIMESPEC is NULL then + wait forever. */ +int +__pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + error_t err; + int drain; + struct __pthread *self; + + __pthread_spin_lock (&rwlock->__lock); + if (__pthread_spin_trylock (&rwlock->__held) == 0) + /* Successfully acquired the lock. */ + { + assert (rwlock->__readerqueue == 0); + assert (rwlock->__writerqueue == 0); + assert (rwlock->__readers == 0); + + rwlock->__readers = 1; + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + else + /* Lock is held, but is held by a reader? */ + if (rwlock->__readers > 0) + /* Just add ourself to number of readers. */ + { + assert (rwlock->__readerqueue == 0); + rwlock->__readers++; + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + + /* The lock is busy. */ + + /* Better be blocked by a writer. */ + assert (rwlock->__readers == 0); + + if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + + self = _pthread_self (); + + /* Add ourself to the queue. */ + __pthread_enqueue (&rwlock->__readerqueue, self); + __pthread_spin_unlock (&rwlock->__lock); + + /* Block the thread. */ + if (abstime != NULL) + err = __pthread_timedblock (self, abstime, CLOCK_REALTIME); + else + { + err = 0; + __pthread_block (self); + } + + __pthread_spin_lock (&rwlock->__lock); + if (self->prevp == NULL) + /* Another thread removed us from the queue, which means a wakeup message + has been sent. It was either consumed while we were blocking, or + queued after we timed out and before we acquired the rwlock lock, in + which case the message queue must be drained. */ + drain = err ? 1 : 0; + else + { + /* We're still in the queue. Noone attempted to wake us up, i.e. we + timed out. */ + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&rwlock->__lock); + + if (drain) + __pthread_block (self); + + if (err) + { + assert (err == ETIMEDOUT); + return err; + } + + /* The reader count has already been increment by whoever woke us + up. */ + + assert (rwlock->__readers > 0); + + return 0; +} + +int +__pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); +} +weak_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock) diff --git a/sysdeps/htl/pt-rwlock-timedwrlock.c b/sysdeps/htl/pt-rwlock-timedwrlock.c new file mode 100644 index 0000000000..b30c250d97 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-timedwrlock.c @@ -0,0 +1,103 @@ +/* Acquire a rwlock for writing. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get + it. As a special GNU extension, if ABSTIME is NULL then the wait + shall not time out. */ +int +__pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + error_t err; + int drain; + struct __pthread *self; + + __pthread_spin_lock (&rwlock->__lock); + if (__pthread_spin_trylock (&rwlock->__held) == 0) + /* Successfully acquired the lock. */ + { + assert (rwlock->__readerqueue == 0); + assert (rwlock->__writerqueue == 0); + assert (rwlock->__readers == 0); + + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + + /* The lock is busy. */ + + if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + + self = _pthread_self (); + + /* Add ourselves to the queue. */ + __pthread_enqueue (&rwlock->__writerqueue, self); + __pthread_spin_unlock (&rwlock->__lock); + + /* Block the thread. */ + if (abstime != NULL) + err = __pthread_timedblock (self, abstime, CLOCK_REALTIME); + else + { + err = 0; + __pthread_block (self); + } + + __pthread_spin_lock (&rwlock->__lock); + if (self->prevp == NULL) + /* Another thread removed us from the queue, which means a wakeup message + has been sent. It was either consumed while we were blocking, or + queued after we timed out and before we acquired the rwlock lock, in + which case the message queue must be drained. */ + drain = err ? 1 : 0; + else + { + /* We're still in the queue. Noone attempted to wake us up, i.e. we + timed out. */ + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&rwlock->__lock); + + if (drain) + __pthread_block (self); + + if (err) + { + assert (err == ETIMEDOUT); + return err; + } + + assert (rwlock->__readers == 0); + + return 0; +} + +int +__pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); +} +weak_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock) diff --git a/sysdeps/htl/pt-rwlock-tryrdlock.c b/sysdeps/htl/pt-rwlock-tryrdlock.c new file mode 100644 index 0000000000..39a368c7c1 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-tryrdlock.c @@ -0,0 +1,55 @@ +/* Try to acquire a rwlock for reading. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Try to acquire RWLOCK. */ +int +pthread_rwlock_tryrdlock (struct __pthread_rwlock *rwlock) +{ + __pthread_spin_lock (&rwlock->__lock); + if (__pthread_spin_trylock (&rwlock->__held) == 0) + /* Successfully acquired the lock. */ + { + assert (rwlock->__readerqueue == 0); + assert (rwlock->__writerqueue == 0); + assert (rwlock->__readers == 0); + + rwlock->__readers = 1; + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + else + /* Lock is held, but is held by a reader? */ + if (rwlock->__readers > 0) + { + assert (rwlock->__readerqueue == 0); + rwlock->__readers++; + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + + /* The lock is busy. */ + + __pthread_spin_unlock (&rwlock->__lock); + + return EBUSY; +} diff --git a/sysdeps/htl/pt-rwlock-trywrlock.c b/sysdeps/htl/pt-rwlock-trywrlock.c new file mode 100644 index 0000000000..2f6f7b93ca --- /dev/null +++ b/sysdeps/htl/pt-rwlock-trywrlock.c @@ -0,0 +1,45 @@ +/* Try to acquire a rwlock for writing. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Try to acquire RWLOCK for writing. */ +int +pthread_rwlock_trywrlock (struct __pthread_rwlock *rwlock) +{ + __pthread_spin_lock (&rwlock->__lock); + if (__pthread_spin_trylock (&rwlock->__held) == 0) + /* Successfully acquired the lock. */ + { + assert (rwlock->__readerqueue == 0); + assert (rwlock->__writerqueue == 0); + assert (rwlock->__readers == 0); + + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + + /* The lock is busy. */ + + __pthread_spin_unlock (&rwlock->__lock); + + return EBUSY; +} diff --git a/sysdeps/htl/pt-rwlock-unlock.c b/sysdeps/htl/pt-rwlock-unlock.c new file mode 100644 index 0000000000..9fd1aa87f6 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-unlock.c @@ -0,0 +1,98 @@ +/* Unlock a rwlock. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +/* Unlock *RWLOCK, rescheduling a waiting writer thread or, if there + are no threads waiting for a write lock, rescheduling the reader + threads. */ +int +__pthread_rwlock_unlock (pthread_rwlock_t *rwlock) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&rwlock->__lock); + + assert (__pthread_spin_trylock (&rwlock->__held) == EBUSY); + + if (rwlock->__readers > 1) + /* There are other readers. */ + { + rwlock->__readers--; + __pthread_spin_unlock (&rwlock->__lock); + return 0; + } + + if (rwlock->__readers == 1) + /* Last reader. */ + rwlock->__readers = 0; + + + /* Wake someone else up. Try the writer queue first, then the + reader queue if that is empty. */ + + if (rwlock->__writerqueue) + { + wakeup = rwlock->__writerqueue; + __pthread_dequeue (wakeup); + + /* We do not unlock RWLOCK->held: we are transferring the ownership + to the thread that we are waking up. */ + + __pthread_spin_unlock (&rwlock->__lock); + __pthread_wakeup (wakeup); + + return 0; + } + + if (rwlock->__readerqueue) + { + unsigned n = 0; + + __pthread_queue_iterate (rwlock->__readerqueue, wakeup) + n++; + + { + struct __pthread *wakeups[n]; + unsigned i = 0; + + __pthread_dequeuing_iterate (rwlock->__readerqueue, wakeup) + wakeups[i++] = wakeup; + + rwlock->__readers += n; + rwlock->__readerqueue = 0; + + __pthread_spin_unlock (&rwlock->__lock); + + for (i = 0; i < n; i++) + __pthread_wakeup (wakeups[i]); + } + + return 0; + } + + + /* Noone is waiting. Just unlock it. */ + + __pthread_spin_unlock (&rwlock->__held); + __pthread_spin_unlock (&rwlock->__lock); + return 0; +} +weak_alias (__pthread_rwlock_unlock, pthread_rwlock_unlock); diff --git a/sysdeps/htl/pt-rwlock-wrlock.c b/sysdeps/htl/pt-rwlock-wrlock.c new file mode 100644 index 0000000000..ed129a8349 --- /dev/null +++ b/sysdeps/htl/pt-rwlock-wrlock.c @@ -0,0 +1,36 @@ +/* Acquire a rwlock for writing. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> + +#include <pt-internal.h> + +/* Implemented in pt-rwlock-timedwrlock.c. */ +extern int __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock + *rwlock, + const struct timespec + *abstime); + +/* Acquire RWLOCK for writing. */ +int +__pthread_rwlock_wrlock (struct __pthread_rwlock *rwlock) +{ + return __pthread_rwlock_timedwrlock_internal (rwlock, 0); +} +weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock); diff --git a/sysdeps/htl/pt-rwlockattr-destroy.c b/sysdeps/htl/pt-rwlockattr-destroy.c new file mode 100644 index 0000000000..218fe88f67 --- /dev/null +++ b/sysdeps/htl/pt-rwlockattr-destroy.c @@ -0,0 +1,26 @@ +/* pthread_rwlockattr_destroy. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr) +{ + return 0; +} diff --git a/sysdeps/htl/pt-rwlockattr-getpshared.c b/sysdeps/htl/pt-rwlockattr-getpshared.c new file mode 100644 index 0000000000..09f57c688f --- /dev/null +++ b/sysdeps/htl/pt-rwlockattr-getpshared.c @@ -0,0 +1,27 @@ +/* pthread_rwlockattr_getpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared) +{ + *pshared = attr->__pshared; + return 0; +} diff --git a/sysdeps/htl/pt-rwlockattr-init.c b/sysdeps/htl/pt-rwlockattr-init.c new file mode 100644 index 0000000000..6ba3a3df8b --- /dev/null +++ b/sysdeps/htl/pt-rwlockattr-init.c @@ -0,0 +1,27 @@ +/* pthread_rwlockattr_init. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_rwlockattr_init (pthread_rwlockattr_t *attr) +{ + *attr = __pthread_default_rwlockattr; + return 0; +} diff --git a/sysdeps/htl/pt-rwlockattr-setpshared.c b/sysdeps/htl/pt-rwlockattr-setpshared.c new file mode 100644 index 0000000000..acb5ea4e0d --- /dev/null +++ b/sysdeps/htl/pt-rwlockattr-setpshared.c @@ -0,0 +1,37 @@ +/* pthread_rwlockattr_setpshared. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared) +{ + switch (pshared) + { + case PTHREAD_PROCESS_PRIVATE: + attr->__pshared = pshared; + return 0; + + case PTHREAD_PROCESS_SHARED: + return ENOTSUP; + + default: + return EINVAL; + } +} diff --git a/sysdeps/htl/pt-setconcurrency.c b/sysdeps/htl/pt-setconcurrency.c new file mode 100644 index 0000000000..3f05005a2b --- /dev/null +++ b/sysdeps/htl/pt-setconcurrency.c @@ -0,0 +1,33 @@ +/* Set the desired level of concurrency. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int __pthread_concurrency; + +int +pthread_setconcurrency (int new_level) +{ + if (new_level < 0) + return EINVAL; + + __pthread_concurrency = new_level; + + return 0; +} diff --git a/sysdeps/htl/pt-setschedparam.c b/sysdeps/htl/pt-setschedparam.c new file mode 100644 index 0000000000..f8bce35943 --- /dev/null +++ b/sysdeps/htl/pt-setschedparam.c @@ -0,0 +1,30 @@ +/* Set the scheduling parameters for a thread. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +__pthread_setschedparam (pthread_t thread, int policy, + const struct sched_param *param) +{ + return ENOSYS; +} + +strong_alias (__pthread_setschedparam, pthread_setschedparam); +stub_warning (pthread_setschedparam) diff --git a/sysdeps/htl/pt-setschedprio.c b/sysdeps/htl/pt-setschedprio.c new file mode 100644 index 0000000000..1d13cbd23b --- /dev/null +++ b/sysdeps/htl/pt-setschedprio.c @@ -0,0 +1,28 @@ +/* Set the scheduling priority of a thread. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_setschedprio (pthread_t thread, int prio) +{ + return ENOSYS; +} + +stub_warning (pthread_setschedprio) diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c new file mode 100644 index 0000000000..8492b5dafa --- /dev/null +++ b/sysdeps/htl/pt-setspecific.c @@ -0,0 +1,50 @@ +/* pthread_setspecific. Generic version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +int +__pthread_setspecific (pthread_key_t key, const void *value) +{ + struct __pthread *self = _pthread_self (); + + if (key < 0 || key >= __pthread_key_count + || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID) + return EINVAL; + + if (key >= self->thread_specifics_size) + { + /* Amortize reallocation cost. */ + int newsize = 2 * key + 1; + void **new = realloc (self->thread_specifics, + newsize * sizeof (new[0])); + if (new == NULL) + return ENOMEM; + + memset (&new[self->thread_specifics_size], 0, + (newsize - self->thread_specifics_size) * sizeof (new[0])); + self->thread_specifics = new; + self->thread_specifics_size = newsize; + } + + self->thread_specifics[key] = (void *) value; + return 0; +} +strong_alias (__pthread_setspecific, pthread_setspecific); diff --git a/sysdeps/htl/pt-spin.c b/sysdeps/htl/pt-spin.c new file mode 100644 index 0000000000..0840baba0a --- /dev/null +++ b/sysdeps/htl/pt-spin.c @@ -0,0 +1,50 @@ +/* Spin locks. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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) +{ + int i; + + while (1) + { + for (i = 0; i < __pthread_spin_count; i++) + { + if (__pthread_spin_trylock (lock) == 0) + return 0; + } + + __sched_yield (); + } +} diff --git a/sysdeps/htl/pt-startup.c b/sysdeps/htl/pt-startup.c new file mode 100644 index 0000000000..dc3bc596c2 --- /dev/null +++ b/sysdeps/htl/pt-startup.c @@ -0,0 +1,24 @@ +/* Thread initialization. Generic version. + Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pt-internal.h> + +void +__pthread_startup (void) +{ +} diff --git a/sysdeps/htl/pthread-functions.h b/sysdeps/htl/pthread-functions.h new file mode 100644 index 0000000000..a0d06cc039 --- /dev/null +++ b/sysdeps/htl/pthread-functions.h @@ -0,0 +1,140 @@ +/* Declaration of libc stubs for pthread functions. Hurd version. + Copyright (C) 2003-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _PTHREAD_FUNCTIONS_H +#define _PTHREAD_FUNCTIONS_H 1 + +#include <pthread.h> + +int __pthread_attr_destroy (pthread_attr_t *); +int __pthread_attr_init (pthread_attr_t *); +int __pthread_attr_getdetachstate (const pthread_attr_t *, int *); +int __pthread_attr_setdetachstate (pthread_attr_t *, int); +int __pthread_attr_getinheritsched (const pthread_attr_t *, int *); +int __pthread_attr_setinheritsched (pthread_attr_t *, int); +int __pthread_attr_getschedparam (const pthread_attr_t *, + struct sched_param *); +int __pthread_attr_setschedparam (pthread_attr_t *, + const struct sched_param *); +int __pthread_attr_getschedpolicy (const pthread_attr_t *, int *); +int __pthread_attr_setschedpolicy (pthread_attr_t *, int); +int __pthread_attr_getscope (const pthread_attr_t *, int *); +int __pthread_attr_setscope (pthread_attr_t *, int); +int __pthread_condattr_destroy (pthread_condattr_t *); +int __pthread_condattr_init (pthread_condattr_t *); +int __pthread_cond_broadcast (pthread_cond_t *); +int __pthread_cond_destroy (pthread_cond_t *); +int __pthread_cond_init (pthread_cond_t *, + const pthread_condattr_t *); +int __pthread_cond_signal (pthread_cond_t *); +int __pthread_cond_wait (pthread_cond_t *, pthread_mutex_t *); +int __pthread_cond_timedwait (pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); +int __pthread_equal (pthread_t, pthread_t); +void __pthread_exit (void *); +int __pthread_getschedparam (pthread_t, int *, struct sched_param *); +int __pthread_setschedparam (pthread_t, int, + const struct sched_param *); +int _pthread_mutex_destroy (pthread_mutex_t *); +int _pthread_mutex_init (pthread_mutex_t *, + const pthread_mutexattr_t *); +int __pthread_mutex_lock (pthread_mutex_t *); +int __pthread_mutex_trylock (pthread_mutex_t *); +int __pthread_mutex_unlock (pthread_mutex_t *); +pthread_t __pthread_self (void); +int __pthread_setcancelstate (int, int *); +int __pthread_setcanceltype (int, int *); +struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void); +int __pthread_once (pthread_once_t *, void (*) (void)); +int __pthread_rwlock_rdlock (pthread_rwlock_t *); +int __pthread_rwlock_wrlock (pthread_rwlock_t *); +int __pthread_rwlock_unlock (pthread_rwlock_t *); +int __pthread_key_create (pthread_key_t *, void (*) (void *)); +void *__pthread_getspecific (pthread_key_t); +int __pthread_setspecific (pthread_key_t, const void *); + +void _cthreads_flockfile (FILE *); +void _cthreads_funlockfile (FILE *); +int _cthreads_ftrylockfile (FILE *); + +/* Data type shared with libc. The libc uses it to pass on calls to + the thread functions. Wine pokes directly into this structure, + so if possible avoid breaking it and append new hooks to the end. */ +struct pthread_functions +{ + int (*ptr_pthread_attr_destroy) (pthread_attr_t *); + int (*ptr_pthread_attr_init) (pthread_attr_t *); + int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *, + struct sched_param *); + int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *, + const struct sched_param *); + int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int); + int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *); + int (*ptr_pthread_condattr_init) (pthread_condattr_t *); + int (*ptr_pthread_cond_broadcast) (pthread_cond_t *); + int (*ptr_pthread_cond_destroy) (pthread_cond_t *); + int (*ptr_pthread_cond_init) (pthread_cond_t *, + const pthread_condattr_t *); + int (*ptr_pthread_cond_signal) (pthread_cond_t *); + int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *); + int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); + int (*ptr_pthread_equal) (pthread_t, pthread_t); + void (*ptr___pthread_exit) (void *); + int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *); + int (*ptr_pthread_setschedparam) (pthread_t, int, + const struct sched_param *); + int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *); + int (*ptr_pthread_mutex_init) (pthread_mutex_t *, + const pthread_mutexattr_t *); + int (*ptr_pthread_mutex_lock) (pthread_mutex_t *); + int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *); + int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *); + pthread_t (*ptr_pthread_self) (void); + int (*ptr___pthread_setcancelstate) (int, int *); + int (*ptr_pthread_setcanceltype) (int, int *); + struct __pthread_cancelation_handler **(*ptr___pthread_get_cleanup_stack) (void); + int (*ptr_pthread_once) (pthread_once_t *, void (*) (void)); + int (*ptr_pthread_rwlock_rdlock) (pthread_rwlock_t *); + int (*ptr_pthread_rwlock_wrlock) (pthread_rwlock_t *); + int (*ptr_pthread_rwlock_unlock) (pthread_rwlock_t *); + int (*ptr___pthread_key_create) (pthread_key_t *, void (*) (void *)); + void *(*ptr___pthread_getspecific) (pthread_key_t); + int (*ptr___pthread_setspecific) (pthread_key_t, const void *); + void (*ptr__IO_flockfile) (FILE *); + void (*ptr__IO_funlockfile) (FILE *); + int (*ptr__IO_ftrylockfile) (FILE *); +}; + +/* Variable in libc.so. */ +extern struct pthread_functions __libc_pthread_functions attribute_hidden; +extern int __libc_pthread_functions_init attribute_hidden; + +void __libc_pthread_init (const struct pthread_functions *functions); + +#define PTHFCT_CALL(fct, params) \ + __libc_pthread_functions.fct params + +#endif /* pthread-functions.h */ diff --git a/sysdeps/htl/pthread.h b/sysdeps/htl/pthread.h new file mode 100644 index 0000000000..91ab9b319a --- /dev/null +++ b/sysdeps/htl/pthread.h @@ -0,0 +1,883 @@ +/* Posix threads. Hurd version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +/* + * POSIX Threads Extension: ??? <pthread.h> + */ + +#ifndef _PTHREAD_H +#define _PTHREAD_H 1 + +#include <features.h> + +#include <sys/cdefs.h> +#ifndef __extern_inline +/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99 + inline semantics, unless -fgnu89-inline is used. */ +# if !defined __cplusplus || __GNUC_PREREQ (4,3) +# if defined __GNUC_STDC_INLINE__ || defined __cplusplus +# define __extern_inline extern __inline __attribute__ ((__gnu_inline__)) +# if __GNUC_PREREQ (4,3) +# define __extern_always_inline \ + extern __always_inline __attribute__ ((__gnu_inline__, __artificial__)) +# else +# define __extern_always_inline \ + extern __always_inline __attribute__ ((__gnu_inline__)) +# endif +# else +# define __extern_inline extern __inline +# define __extern_always_inline extern __always_inline +# endif +# endif +#endif + +#include <sched.h> +#include <time.h> + +__BEGIN_DECLS + +#include <bits/pthreadtypes.h> + +#include <bits/pthread.h> + +/* Possible values for the process shared attribute. */ +#define PTHREAD_PROCESS_PRIVATE __PTHREAD_PROCESS_PRIVATE +#define PTHREAD_PROCESS_SHARED __PTHREAD_PROCESS_SHARED + + +/* Thread attributes. */ + +/* Possible values for the inheritsched attribute. */ +#define PTHREAD_EXPLICIT_SCHED __PTHREAD_EXPLICIT_SCHED +#define PTHREAD_INHERIT_SCHED __PTHREAD_INHERIT_SCHED + +/* Possible values for the `contentionscope' attribute. */ +#define PTHREAD_SCOPE_SYSTEM __PTHREAD_SCOPE_SYSTEM +#define PTHREAD_SCOPE_PROCESS __PTHREAD_SCOPE_PROCESS + +/* Possible values for the `detachstate' attribute. */ +#define PTHREAD_CREATE_JOINABLE __PTHREAD_CREATE_JOINABLE +#define PTHREAD_CREATE_DETACHED __PTHREAD_CREATE_DETACHED + +#include <bits/types/struct___pthread_attr.h> + +/* Initialize the thread attribute object in *ATTR to the default + values. */ +extern int pthread_attr_init (pthread_attr_t *__attr) __THROW __nonnull ((1)); + +/* Destroy the thread attribute object in *ATTR. */ +extern int pthread_attr_destroy (pthread_attr_t *__attr) + __THROW __nonnull ((1)); + + +/* Return the value of the inheritsched attribute in *ATTR in + *INHERITSCHED. */ +extern int pthread_attr_getinheritsched (const pthread_attr_t *__restrict __attr, + int *__restrict __inheritsched) + __THROW __nonnull ((1, 2)); + +/* Set the value of the inheritsched attribute in *ATTR to + INHERITSCHED. */ +extern int pthread_attr_setinheritsched (pthread_attr_t *__attr, + int __inheritsched) + __THROW __nonnull ((1)); + + +/* Return the value of the schedparam attribute in *ATTR in *PARAM. */ +extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr, + struct sched_param *__restrict __param) + __THROW __nonnull ((1, 2)); + +/* Set the value of the schedparam attribute in *ATTR to PARAM. */ +extern int pthread_attr_setschedparam (pthread_attr_t *__restrict __attr, + const struct sched_param *__restrict + __param) __THROW __nonnull ((1, 2)); + + +/* Return the value of the schedpolicy attribute in *ATTR to *POLICY. */ +extern int pthread_attr_getschedpolicy (const pthread_attr_t *__restrict __attr, + int *__restrict __policy) + __THROW __nonnull ((1, 2)); + +/* Set the value of the schedpolicy attribute in *ATTR to POLICY. */ +extern int pthread_attr_setschedpolicy (pthread_attr_t *__attr, + int __policy) + __THROW __nonnull ((1)); + + +/* Return the value of the contentionscope attribute in *ATTR in + *CONTENTIONSCOPE. */ +extern int pthread_attr_getscope (const pthread_attr_t *__restrict __attr, + int *__restrict __contentionscope) + __THROW __nonnull ((1, 2)); + +/* Set the value of the contentionscope attribute in *ATTR to + CONTENTIONSCOPE. */ +extern int pthread_attr_setscope (pthread_attr_t *__attr, + int __contentionscope) + __THROW __nonnull ((1)); + + +/* Return the value of the stackaddr attribute in *ATTR in + *STACKADDR. */ +extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict __attr, + void **__restrict __stackaddr) + __THROW __nonnull ((1, 2)); + +/* Set the value of the stackaddr attribute in *ATTR to STACKADDR. */ +extern int pthread_attr_setstackaddr (pthread_attr_t *__attr, + void *__stackaddr) + __THROW __nonnull ((1)); + + +#ifdef __USE_XOPEN2K +/* Return the value of the stackaddr and stacksize attributes in *ATTR + in *STACKADDR and *STACKSIZE respectively. */ +extern int pthread_attr_getstack (const pthread_attr_t *__restrict __attr, + void **__restrict __stackaddr, + size_t *__restrict __stacksize) + __THROW __nonnull ((1, 2, 3)); + +/* Set the value of the stackaddr and stacksize attributes in *ATTR to + STACKADDR and STACKSIZE respectively. */ +extern int pthread_attr_setstack (pthread_attr_t *__attr, + void *__stackaddr, + size_t __stacksize) + __THROW __nonnull ((1)); +#endif + + +/* Return the value of the detachstate attribute in *ATTR in + *DETACHSTATE. */ +extern int pthread_attr_getdetachstate (const pthread_attr_t *__attr, + int *__detachstate) + __THROW __nonnull ((1, 2)); + +/* Set the value of the detachstate attribute in *ATTR to + DETACHSTATE. */ +extern int pthread_attr_setdetachstate (pthread_attr_t *__attr, + int __detachstate) + __THROW __nonnull ((1)); + + +/* Return the value of the guardsize attribute in *ATTR in + *GUARDSIZE. */ +extern int pthread_attr_getguardsize (const pthread_attr_t *__restrict __attr, + size_t *__restrict __guardsize) + __THROW __nonnull ((1, 2)); + +/* Set the value of the guardsize attribute in *ATTR to GUARDSIZE. */ +extern int pthread_attr_setguardsize (pthread_attr_t *__attr, + size_t __guardsize) + __THROW __nonnull ((1)); + + +/* Return the value of the stacksize attribute in *ATTR in + *STACKSIZE. */ +extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict __attr, + size_t *__restrict __stacksize) + __THROW __nonnull ((1, 2)); + +/* Set the value of the stacksize attribute in *ATTR to STACKSIZE. */ +extern int pthread_attr_setstacksize (pthread_attr_t *__attr, + size_t __stacksize) + __THROW __nonnull ((1)); + +#ifdef __USE_GNU +/* Initialize thread attribute *ATTR with attributes corresponding to the + already running thread THREAD. It shall be called on an uninitialized ATTR + and destroyed with pthread_attr_destroy when no longer needed. */ +extern int pthread_getattr_np (pthread_t __thr, pthread_attr_t *__attr) + __THROW __nonnull ((2)); +#endif + + +/* Create a thread with attributes given by ATTR, executing + START_ROUTINE with argument ARG. */ +extern int pthread_create (pthread_t *__restrict __threadp, + __const pthread_attr_t *__restrict __attr, + void *(*__start_routine)(void *), + void *__restrict __arg) __THROWNL __nonnull ((1, 3)); + +/* Terminate the current thread and make STATUS available to any + thread that might join us. */ +extern void pthread_exit (void *__status) __attribute__ ((__noreturn__)); + +/* Make calling thread wait for termination of thread THREAD. Return + the exit status of the thread in *STATUS. */ +extern int pthread_join (pthread_t __threadp, void **__status); + +/* Indicate that the storage for THREAD can be reclaimed when it + terminates. */ +extern int pthread_detach (pthread_t __threadp); + +/* Compare thread IDs T1 and T2. Return nonzero if they are equal, 0 + if they are not. */ +extern int pthread_equal (pthread_t __t1, pthread_t __t2); + +#ifdef __USE_EXTERN_INLINES + +__extern_inline int +pthread_equal (pthread_t __t1, pthread_t __t2) +{ + return __pthread_equal (__t1, __t2); +} + +#endif /* Use extern inlines. */ + + +/* Return the thread ID of the calling thread. */ +extern pthread_t pthread_self (void) __THROW; + + +/* Mutex attributes. */ + +#define PTHREAD_PRIO_NONE_NP __PTHREAD_PRIO_NONE +#define PTHREAD_PRIO_INHERIT_NP __PTHREAD_PRIO_INHERIT +#define PTHREAD_PRIO_PROTECT_NP __PTHREAD_PRIO_PROTECT +#ifdef __USE_UNIX98 +# define PTHREAD_PRIO_NONE PTHREAD_PRIO_NONE_NP +# define PTHREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT_NP +# define PTHREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT_NP +#endif + +#define PTHREAD_MUTEX_TIMED_NP __PTHREAD_MUTEX_TIMED +#define PTHREAD_MUTEX_ERRORCHECK_NP __PTHREAD_MUTEX_ERRORCHECK +#define PTHREAD_MUTEX_RECURSIVE_NP __PTHREAD_MUTEX_RECURSIVE +#if defined __USE_UNIX98 || defined __USE_XOPEN2K8 +# define PTHREAD_MUTEX_NORMAL PTHREAD_MUTEX_TIMED_NP +# define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP +# define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL +#endif +#ifdef __USE_GNU +/* For compatibility. */ +# define PTHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_TIMED_NP +#endif + +#ifdef __USE_XOPEN2K +# define PTHREAD_MUTEX_STALLED __PTHREAD_MUTEX_STALLED +# define PTHREAD_MUTEX_ROBUST __PTHREAD_MUTEX_ROBUST +#endif + +#include <bits/types/struct___pthread_mutexattr.h> + +/* Initialize the mutex attribute object in *ATTR to the default + values. */ +extern int pthread_mutexattr_init(pthread_mutexattr_t *__attr) + __THROW __nonnull ((1)); + +/* Destroy the mutex attribute structure in *ATTR. */ +extern int pthread_mutexattr_destroy(pthread_mutexattr_t *__attr) + __THROW __nonnull ((1)); + + +#ifdef __USE_UNIX98 +/* Return the value of the prioceiling attribute in *ATTR in + *PRIOCEILING. */ +extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict __attr, + int *__restrict __prioceiling) + __THROW __nonnull ((1, 2)); + +/* Set the value of the prioceiling attribute in *ATTR to + PRIOCEILING. */ +extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *__attr, + int __prioceiling) + __THROW __nonnull ((1)); + + +/* Return the value of the protocol attribute in *ATTR in + *PROTOCOL. */ +extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict __attr, + int *__restrict __protocol) + __THROW __nonnull ((1, 2)); + +/* Set the value of the protocol attribute in *ATTR to PROTOCOL. */ +extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *__attr, + int __protocol) + __THROW __nonnull ((1)); +#endif + +#ifdef __USE_XOPEN2K +/* Get the robustness flag of the mutex attribute ATTR. */ +extern int pthread_mutexattr_getrobust (const pthread_mutexattr_t *__attr, + int *__robustness) + __THROW __nonnull ((1, 2)); +# ifdef __USE_GNU +extern int pthread_mutexattr_getrobust_np (const pthread_mutexattr_t *__attr, + int *__robustness) + __THROW __nonnull ((1, 2)); +# endif + +/* Set the robustness flag of the mutex attribute ATTR. */ +extern int pthread_mutexattr_setrobust (pthread_mutexattr_t *__attr, + int __robustness) + __THROW __nonnull ((1)); +# ifdef __USE_GNU +extern int pthread_mutexattr_setrobust_np (pthread_mutexattr_t *__attr, + int __robustness) + __THROW __nonnull ((1)); +# endif +#endif + + +/* Return the value of the process shared attribute in *ATTR in + *PSHARED. */ +extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict __attr, + int *__restrict __pshared) + __THROW __nonnull ((1, 2)); + +/* Set the value of the process shared attribute in *ATTR to + PSHARED. */ +extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *__attr, + int __pshared) + __THROW __nonnull ((1)); + + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K8 +/* Return the value of the type attribute in *ATTR in *TYPE. */ +extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict __attr, + int *__restrict __type) + __THROW __nonnull ((1, 2)); + +/* Set the value of the type attribute in *ATTR to TYPE. */ +extern int pthread_mutexattr_settype(pthread_mutexattr_t *__attr, + int __type) + __THROW __nonnull ((1)); +#endif + + +/* Mutexes. */ + +#include <bits/types/struct___pthread_mutex.h> + +#define PTHREAD_MUTEX_INITIALIZER __PTHREAD_MUTEX_INITIALIZER +/* Static initializer for recursive mutexes. */ + +#ifdef __USE_GNU +# define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ + __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER +# define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ + __PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#endif + +/* Create a mutex with attributes given by ATTR and store it in + *__MUTEX. */ +extern int pthread_mutex_init (struct __pthread_mutex *__restrict __mutex, + const pthread_mutexattr_t *__restrict __attr) + __THROW __nonnull ((1)); + +/* Destroy the mutex __MUTEX. */ +extern int pthread_mutex_destroy (struct __pthread_mutex *__mutex) + __THROW __nonnull ((1)); + +/* Wait until lock for MUTEX becomes available and lock it. */ +extern int pthread_mutex_lock (pthread_mutex_t *__mutex); + +/* Try to lock MUTEX. */ +extern int pthread_mutex_trylock (pthread_mutex_t *__mutex) + __THROWNL __nonnull ((1)); + +#ifdef __USE_XOPEN2K +/* Try to lock MUTEX, block until *ABSTIME if it is already held. */ +extern int pthread_mutex_timedlock (struct __pthread_mutex *__restrict __mutex, + const struct timespec *__restrict __abstime) + __THROWNL __nonnull ((1, 2)); +#endif + +/* Unlock MUTEX. */ +extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) + __THROWNL __nonnull ((1)); + +/* Transfer ownership of the mutex MUTEX to the thread TID. The + caller must own the lock. */ +extern int __pthread_mutex_transfer_np (struct __pthread_mutex *__mutex, + pthread_t __tid) + __THROWNL __nonnull ((1)); + + +#ifdef __USE_UNIX98 +/* Return the priority ceiling of mutex *MUTEX in *PRIOCEILING. */ +extern int pthread_mutex_getprioceiling (const pthread_mutex_t *__restrict __mutex, + int *__restrict __prioceiling) + __THROW __nonnull ((1, 2)); + +/* After acquiring the mutex *MUTEX, set its priority ceiling to PRIO + and return the old priority ceiling in *OLDPRIO. Before returning, + release the mutex. */ +extern int pthread_mutex_setprioceiling (pthread_mutex_t *__restrict __mutex, + int __prio, int *__restrict __oldprio) + __THROW __nonnull ((1, 3)); +#endif + +#ifdef __USE_XOPEN2K8 + +/* Declare the state protected by robust mutex MTXP as consistent. */ +extern int pthread_mutex_consistent (pthread_mutex_t *__mtxp) + __THROW __nonnull ((1)); + +# ifdef __USE_GNU +extern int pthread_mutex_consistent_np (pthread_mutex_t *__mtxp) + __THROW __nonnull ((1)); +# endif +#endif + + + +/* Condition attributes. */ + +#include <bits/types/struct___pthread_condattr.h> + +/* Initialize the condition attribute in *ATTR to the default + values. */ +extern int pthread_condattr_init (pthread_condattr_t *__attr) + __THROW __nonnull ((1)); + +/* Destroy the condition attribute structure in *ATTR. */ +extern int pthread_condattr_destroy (pthread_condattr_t *__attr) + __THROW __nonnull ((1)); + + +#ifdef __USE_XOPEN2K +/* Return the value of the clock attribute in *ATTR in *CLOCK_ID. */ +extern int pthread_condattr_getclock (const pthread_condattr_t *__restrict __attr, + __clockid_t *__restrict __clock_id) + __THROW __nonnull ((1, 2)); + +/* Set the value of the clock attribute in *ATTR to CLOCK_ID. */ +extern int pthread_condattr_setclock (pthread_condattr_t *__attr, + __clockid_t __clock_id) + __THROW __nonnull ((1)); +#endif + + +/* Return the value of the process shared attribute in *ATTR in + *PSHARED. */ +extern int pthread_condattr_getpshared (const pthread_condattr_t *__restrict __attr, + int *__restrict __pshared) + __THROW __nonnull ((1, 2)); + +/* Set the value of the process shared attribute in *ATTR to + PSHARED. */ +extern int pthread_condattr_setpshared (pthread_condattr_t *__attr, + int __pshared) + __THROW __nonnull ((1)); + + +/* Condition variables. */ + +#include <bits/types/struct___pthread_cond.h> + +#define PTHREAD_COND_INITIALIZER __PTHREAD_COND_INITIALIZER + +extern int pthread_cond_init (pthread_cond_t *__restrict __cond, + const pthread_condattr_t *__restrict __attr) + __THROW __nonnull ((1)); + +extern int pthread_cond_destroy (pthread_cond_t *__cond) + __THROW __nonnull ((1)); + +/* Unblock at least one of the threads that are blocked on condition + variable COND. */ +extern int pthread_cond_signal (pthread_cond_t *__cond) + __THROWNL __nonnull ((1)); + +/* Unblock all threads that are blocked on condition variable COND. */ +extern int pthread_cond_broadcast (pthread_cond_t *__cond) + __THROWNL __nonnull ((1)); + +/* Block on condition variable COND. MUTEX should be held by the + calling thread. On success, MUTEX will be held by the calling + thread. */ +extern int pthread_cond_wait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex) + __nonnull ((1, 2)); + +/* Block on condition variable COND. MUTEX should be held by the + calling thread. On success, MUTEX will be held by the calling + thread. If the time specified by ABSTIME passes, ETIMEDOUT is + returned, and MUTEX will nevertheless be held. */ +extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex, + __const struct timespec *__restrict __abstime) + __nonnull ((1, 2, 3)); + + +/* Spin locks. */ + +#ifdef __USE_XOPEN2K + +# include <bits/types/__pthread_spinlock_t.h> + +# define PTHREAD_SPINLOCK_INITIALIZER __PTHREAD_SPIN_LOCK_INITIALIZER + +/* Destroy the spin lock object LOCK. */ +extern int pthread_spin_destroy (pthread_spinlock_t *__lock) + __nonnull ((1)); + +/* Initialize the spin lock object LOCK. PSHARED determines whether + the spin lock can be operated upon by multiple processes. */ +extern int pthread_spin_init (pthread_spinlock_t *__lock, int __pshared) + __nonnull ((1)); + +/* Lock the spin lock object LOCK. If the lock is held by another + thread spin until it becomes available. */ +extern int pthread_spin_lock (pthread_spinlock_t *__lock) + __nonnull ((1)); + +/* Lock the spin lock object LOCK. Fail if the lock is held by + another thread. */ +extern int pthread_spin_trylock (pthread_spinlock_t *__lock) + __nonnull ((1)); + +/* Unlock the spin lock object LOCK. */ +extern int pthread_spin_unlock (pthread_spinlock_t *__lock) + __nonnull ((1)); + +# if defined __USE_EXTERN_INLINES && defined _LIBC + +# include <bits/spin-lock-inline.h> + +__extern_inline int +pthread_spin_destroy (pthread_spinlock_t *__lock) +{ + return __pthread_spin_destroy (__lock); +} + +__extern_inline int +pthread_spin_init (pthread_spinlock_t *__lock, int __pshared) +{ + return __pthread_spin_init (__lock, __pshared); +} + +__extern_inline int +pthread_spin_lock (pthread_spinlock_t *__lock) +{ + return __pthread_spin_lock (__lock); +} + +__extern_inline int +pthread_spin_trylock (pthread_spinlock_t *__lock) +{ + return __pthread_spin_trylock (__lock); +} + +__extern_inline int +pthread_spin_unlock (pthread_spinlock_t *__lock) +{ + return __pthread_spin_unlock (__lock); +} + +# endif /* Use extern inlines. */ + +#endif /* XPG6. */ + + +/* rwlock attributes. */ + +#if defined __USE_UNIX98 || defined __USE_XOPEN2K + +# include <bits/types/struct___pthread_rwlockattr.h> + +/* Initialize rwlock attribute object in *ATTR to the default + values. */ +extern int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr) + __THROW __nonnull ((1)); + +/* Destroy the rwlock attribute object in *ATTR. */ +extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr) + __THROW __nonnull ((1)); + + +/* Return the value of the process shared attribute in *ATTR in + *PSHARED. */ +extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *__restrict __attr, + int *__restrict __pshared) + __THROW __nonnull ((1, 2)); + +/* Set the value of the process shared atrribute in *ATTR to + PSHARED. */ +extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr, + int __pshared) + __THROW __nonnull ((1)); + +/* Return current setting of reader/writer preference. */ +extern int pthread_rwlockattr_getkind_np (const pthread_rwlockattr_t * + __restrict __attr, + int *__restrict __pref) + __THROW __nonnull ((1, 2)); + +/* Set reader/write preference. */ +extern int pthread_rwlockattr_setkind_np (pthread_rwlockattr_t *__attr, + int __pref) __THROW __nonnull ((1)); + + +/* rwlocks. */ + +# include <bits/types/struct___pthread_rwlock.h> + +# define PTHREAD_RWLOCK_INITIALIZER __PTHREAD_RWLOCK_INITIALIZER +/* Create a rwlock object with attributes given by ATTR and strore the + result in *RWLOCK. */ +extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock, + const pthread_rwlockattr_t *__restrict __attr) + __THROW __nonnull ((1)); + +/* Destroy the rwlock *RWLOCK. */ +extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock) + __THROW __nonnull ((1)); + +/* Acquire the rwlock *RWLOCK for reading. */ +extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock) + __THROWNL __nonnull ((1)); + +/* Acquire the rwlock *RWLOCK for reading. */ +extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock) + __THROWNL __nonnull ((1)); + +# ifdef __USE_XOPEN2K +/* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if + it is already held. */ +extern int pthread_rwlock_timedrdlock (struct __pthread_rwlock *__restrict __rwlock, + const struct timespec *__restrict __abstime) + __THROWNL __nonnull ((1, 2)); +# endif + +/* Acquire the rwlock *RWLOCK for writing. */ +extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) + __THROWNL __nonnull ((1)); + +/* Try to acquire the rwlock *RWLOCK for writing. */ +extern int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock) + __THROWNL __nonnull ((1)); + +# ifdef __USE_XOPEN2K +/* Acquire the rwlock *RWLOCK for writing blocking until *ABSTIME if + it is already held. */ +extern int pthread_rwlock_timedwrlock (struct __pthread_rwlock *__restrict __rwlock, + const struct timespec *__restrict __abstime) + __THROWNL __nonnull ((1, 2)); +# endif + +/* Release the lock held by the current thread on *RWLOCK. */ +extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) + __THROWNL __nonnull ((1)); + +#endif /* __USE_UNIX98 || __USE_XOPEN2K */ + + + +/* Cancelation. */ + +/* Register a cleanup handler. */ +extern void pthread_cleanup_push (void (*__routine) (void *), void *__arg); + +/* Unregister a cleanup handler. */ +extern void pthread_cleanup_pop (int __execute); + +#include <bits/cancelation.h> + +#define pthread_cleanup_push(rt, rtarg) __pthread_cleanup_push(rt, rtarg) +#define pthread_cleanup_pop(execute) __pthread_cleanup_pop(execute) + +#define PTHREAD_CANCEL_DISABLE 0 +#define PTHREAD_CANCEL_ENABLE 1 + +/* Return the calling thread's cancelation state in *OLDSTATE and set + its state to STATE. */ +extern int pthread_setcancelstate (int __state, int *__oldstate); + +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 + +/* Return the calling thread's cancelation type in *OLDTYPE and set + its type to TYPE. */ +extern int pthread_setcanceltype (int __type, int *__oldtype); + +/* Value returned by pthread_join if the target thread was + canceled. */ +#define PTHREAD_CANCELED ((void *) -1) + +/* Cancel THEAD. */ +extern int pthread_cancel (pthread_t __thr); + +/* Add an explicit cancelation point. */ +extern void pthread_testcancel (void); + + +/* Barriers attributes. */ + +#ifdef __USE_XOPEN2K + +# include <bits/types/struct___pthread_barrierattr.h> + +/* Initialize barrier attribute object in *ATTR to the default + values. */ +extern int pthread_barrierattr_init (pthread_barrierattr_t *__attr) + __THROW __nonnull ((1)); + +/* Destroy the barrier attribute object in *ATTR. */ +extern int pthread_barrierattr_destroy (pthread_barrierattr_t *__attr) + __THROW __nonnull ((1)); + + +/* Return the value of the process shared attribute in *ATTR in + *PSHARED. */ +extern int pthread_barrierattr_getpshared (const pthread_barrierattr_t *__restrict __attr, + int *__restrict __pshared) + __THROW __nonnull ((1, 2)); + +/* Set the value of the process shared atrribute in *ATTR to + PSHARED. */ +extern int pthread_barrierattr_setpshared (pthread_barrierattr_t *__attr, + int __pshared) + __THROW __nonnull ((1)); + + +/* Barriers. */ + +# include <bits/types/struct___pthread_barrier.h> + +/* Returned by pthread_barrier_wait to exactly one thread each time a + barrier is passed. */ +# define PTHREAD_BARRIER_SERIAL_THREAD -1 + +/* Initialize barrier BARRIER. */ +extern int pthread_barrier_init (pthread_barrier_t *__restrict __barrier, + const pthread_barrierattr_t *__restrict __attr, + unsigned __count) + __THROW __nonnull ((1)); + +/* Destroy barrier BARRIER. */ +extern int pthread_barrier_destroy (pthread_barrier_t *__barrier) + __THROW __nonnull ((1)); + +/* Wait on barrier BARRIER. */ +extern int pthread_barrier_wait (pthread_barrier_t *__barrier) + __THROWNL __nonnull ((1)); + +#endif /* __USE_XOPEN2K */ + + + +/* Thread specific data. */ + +#include <bits/types/__pthread_key.h> + +/* Create a thread specific data key in KEY visible to all threads. + On thread destruction, DESTRUCTOR shall be called with the thread + specific data associate with KEY if it is not NULL. */ +extern int pthread_key_create (pthread_key_t *__key, + void (*__destructor) (void *)) + __THROW __nonnull ((1)); + +/* Delete the thread specific data key KEY. The associated destructor + function is not called. */ +extern int pthread_key_delete (pthread_key_t __key) __THROW; + +/* Return the caller thread's thread specific value of KEY. */ +extern void *pthread_getspecific (pthread_key_t __key) __THROW; + +/* Set the caller thread's thread specific value of KEY to VALUE. */ +extern int pthread_setspecific (pthread_key_t __key, const void *__value) + __THROW; + + +/* Dynamic package initialization. */ + +#include <bits/types/struct___pthread_once.h> + +#define PTHREAD_ONCE_INIT __PTHREAD_ONCE_INIT + +/* Call INIT_ROUTINE if this function has never been called with + *ONCE_CONTROL, otherwise do nothing. */ +extern int pthread_once (pthread_once_t *__once_control, + void (*__init_routine) (void)) __nonnull ((1, 2)); + + +/* Concurrency. */ + +#ifdef __USE_UNIX98 +/* Set the desired concurrency level to NEW_LEVEL. */ +extern int pthread_setconcurrency (int __new_level) __THROW; + +/* Get the current concurrency level. */ +extern int pthread_getconcurrency (void) __THROW; +#endif + + +/* Forking. */ + +/* Register the function PREPARE to be run before the process forks, + the function PARENT to be run after a fork in the parent and the + function CHILD to be run in the child after the fork. If no + handling is desired then any of PREPARE, PARENT and CHILD may be + NULL. The prepare handles will be called in the reverse order + which they were registered and the parent and child handlers in the + order in which they were registered. */ +extern int pthread_atfork (void (*__prepare) (void), void (*__parent) (void), + void (*__child) (void)) __THROW; + + +/* Signals (should be in <signal.h>). */ + +/* Send signal SIGNO to thread THREAD. */ +extern int pthread_kill (pthread_t __thr, int __signo) __THROW; + + +/* Time. */ + +#ifdef __USE_XOPEN2K +/* Return the thread cpu clock. */ +extern int pthread_getcpuclockid (pthread_t __thr, __clockid_t *__clock) + __THROW __nonnull ((2)); +#endif + + +/* Scheduling. */ + +/* Return thread THREAD's scheduling paramters. */ +extern int pthread_getschedparam (pthread_t __thr, int *__restrict __policy, + struct sched_param *__restrict __param) + __THROW __nonnull ((2, 3)); + +/* Set thread THREAD's scheduling paramters. */ +extern int pthread_setschedparam (pthread_t __thr, int __policy, + const struct sched_param *__param) + __THROW __nonnull ((3)); + +/* Set thread THREAD's scheduling priority. */ +extern int pthread_setschedprio (pthread_t __thr, int __prio) __THROW; + +#ifdef __USE_GNU +/* Yield the processor to another thread or process. + This function is similar to the POSIX `sched_yield' function but + might be differently implemented in the case of a m-on-n thread + implementation. */ +extern int pthread_yield (void) __THROW; +#endif + + +/* Kernel-specific interfaces. */ + +#include <bits/pthread-np.h> + + +__END_DECLS + +#endif /* pthread.h */ diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h new file mode 100644 index 0000000000..c37974945a --- /dev/null +++ b/sysdeps/htl/pthreadP.h @@ -0,0 +1,46 @@ +/* Declarations of internal pthread functions used by libc. Hurd version. + Copyright (C) 2016-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _PTHREADP_H +#define _PTHREADP_H 1 + +#include <pthread.h> + +/* These represent the interface used by glibc itself. */ + +extern pthread_t __pthread_self (void); +extern int __pthread_kill (pthread_t threadid, int signo); +extern struct __pthread **__pthread_threads; + +extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); +extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex); + +typedef struct __cthread *__cthread_t; +typedef int __cthread_key_t; +typedef void * (*__cthread_fn_t)(void *__arg); + +__cthread_t __cthread_fork (__cthread_fn_t, void *); +void __cthread_detach (__cthread_t); +int __cthread_keycreate (__cthread_key_t *); +int __cthread_getspecific (__cthread_key_t, void **); +int __cthread_setspecific (__cthread_key_t, void *); + +int __pthread_getattr_np (pthread_t, pthread_attr_t *); +int __pthread_attr_getstack (const pthread_attr_t *, void **, size_t *); + +#endif /* pthreadP.h */ diff --git a/sysdeps/htl/raise.c b/sysdeps/htl/raise.c new file mode 100644 index 0000000000..d2f21c8a3f --- /dev/null +++ b/sysdeps/htl/raise.c @@ -0,0 +1,51 @@ +/* raise.c - Generic raise implementation. + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Neal H. Walfield <neal@gnu.org>. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 3 of + the License, or (at your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/>. */ + +#include <pthreadP.h> +#include <signal.h> +#include <unistd.h> + +#pragma weak __pthread_kill +#pragma weak __pthread_self +#pragma weak __pthread_threads +int +raise (int signo) +{ + /* According to POSIX, if we implement threads (and we do), then + "the effect of the raise() function shall be equivalent to + calling: pthread_kill(pthread_self(), sig);" */ + + if (__pthread_kill != NULL && __pthread_threads != NULL) + { + int err; + err = __pthread_kill (__pthread_self (), signo); + if (err) + { + errno = err; + return -1; + } + return 0; + } + else + return __kill (__getpid (), signo); +} + +libc_hidden_def (raise) +weak_alias (raise, gsignal) diff --git a/sysdeps/htl/sem-close.c b/sysdeps/htl/sem-close.c new file mode 100644 index 0000000000..10a96ca836 --- /dev/null +++ b/sysdeps/htl/sem-close.c @@ -0,0 +1,31 @@ +/* Close a named semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_close (sem_t *sem) +{ + errno = EOPNOTSUPP; + return -1; +} + +strong_alias (__sem_close, sem_close); diff --git a/sysdeps/htl/sem-destroy.c b/sysdeps/htl/sem-destroy.c new file mode 100644 index 0000000000..c1c5bcb423 --- /dev/null +++ b/sysdeps/htl/sem-destroy.c @@ -0,0 +1,37 @@ +/* Destroy a semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_destroy (sem_t *sem) +{ + if (sem->__queue) + /* There are threads waiting on *SEM. */ + { + errno = EBUSY; + return -1; + } + + return 0; +} + +strong_alias (__sem_destroy, sem_destroy); diff --git a/sysdeps/htl/sem-getvalue.c b/sysdeps/htl/sem-getvalue.c new file mode 100644 index 0000000000..2065458527 --- /dev/null +++ b/sysdeps/htl/sem-getvalue.c @@ -0,0 +1,32 @@ +/* Get the value of a semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <pt-internal.h> + +int +__sem_getvalue (sem_t *restrict sem, int *restrict value) +{ + __pthread_spin_lock (&sem->__lock); + *value = sem->__value; + __pthread_spin_unlock (&sem->__lock); + + return 0; +} + +strong_alias (__sem_getvalue, sem_getvalue); diff --git a/sysdeps/htl/sem-init.c b/sysdeps/htl/sem-init.c new file mode 100644 index 0000000000..5faa8ef1a1 --- /dev/null +++ b/sysdeps/htl/sem-init.c @@ -0,0 +1,45 @@ +/* Initialize a semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_init (sem_t *sem, int pshared, unsigned value) +{ + if (pshared != 0) + { + errno = EOPNOTSUPP; + return -1; + } + +#ifdef SEM_VALUE_MAX + if (value > SEM_VALUE_MAX) + { + errno = EINVAL; + return -1; + } +#endif + + *sem = (sem_t) __SEMAPHORE_INITIALIZER (pshared, value); + return 0; +} + +strong_alias (__sem_init, sem_init); diff --git a/sysdeps/htl/sem-open.c b/sysdeps/htl/sem-open.c new file mode 100644 index 0000000000..2d708f03fd --- /dev/null +++ b/sysdeps/htl/sem-open.c @@ -0,0 +1,31 @@ +/* Open a named semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +sem_t * +__sem_open (const char *name, int open_flags, ...) +{ + errno = EOPNOTSUPP; + return SEM_FAILED; +} + +strong_alias (__sem_open, sem_open); diff --git a/sysdeps/htl/sem-post.c b/sysdeps/htl/sem-post.c new file mode 100644 index 0000000000..12cb36c85a --- /dev/null +++ b/sysdeps/htl/sem-post.c @@ -0,0 +1,61 @@ +/* Post a semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_post (sem_t *sem) +{ + struct __pthread *wakeup; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Do a quick up. */ + { + assert (sem->__queue == NULL); + sem->__value++; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + if (sem->__queue == NULL) + /* No one waiting. */ + { + sem->__value = 1; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + /* Wake someone up. */ + + /* First dequeue someone. */ + wakeup = sem->__queue; + __pthread_dequeue (wakeup); + + /* Then drop the lock and transfer control. */ + __pthread_spin_unlock (&sem->__lock); + + __pthread_wakeup (wakeup); + + return 0; +} + +strong_alias (__sem_post, sem_post); diff --git a/sysdeps/htl/sem-timedwait.c b/sysdeps/htl/sem-timedwait.c new file mode 100644 index 0000000000..54a4ea44a8 --- /dev/null +++ b/sysdeps/htl/sem-timedwait.c @@ -0,0 +1,98 @@ +/* Wait on a semaphore with a timeout. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> +#include <assert.h> + +#include <pt-internal.h> + +int +__sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + error_t err; + int drain; + struct __pthread *self; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value--; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + if (timeout != NULL && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + { + errno = EINVAL; + return -1; + } + + /* Add ourselves to the queue. */ + self = _pthread_self (); + + __pthread_enqueue (&sem->__queue, self); + __pthread_spin_unlock (&sem->__lock); + + /* Block the thread. */ + if (timeout != NULL) + err = __pthread_timedblock (self, timeout, CLOCK_REALTIME); + else + { + err = 0; + __pthread_block (self); + } + + __pthread_spin_lock (&sem->__lock); + if (self->prevp == NULL) + /* Another thread removed us from the queue, which means a wakeup message + has been sent. It was either consumed while we were blocking, or + queued after we timed out and before we acquired the semaphore lock, in + which case the message queue must be drained. */ + drain = err ? 1 : 0; + else + { + /* We're still in the queue. Noone attempted to wake us up, i.e. we + timed out. */ + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&sem->__lock); + + if (drain) + __pthread_block (self); + + if (err) + { + assert (err == ETIMEDOUT); + errno = err; + return -1; + } + + return 0; +} + +int +__sem_timedwait (sem_t *restrict sem, const struct timespec *restrict timeout) +{ + return __sem_timedwait_internal (sem, timeout); +} + +weak_alias (__sem_timedwait, sem_timedwait); diff --git a/sysdeps/htl/sem-trywait.c b/sysdeps/htl/sem-trywait.c new file mode 100644 index 0000000000..e84b08d414 --- /dev/null +++ b/sysdeps/htl/sem-trywait.c @@ -0,0 +1,41 @@ +/* Lock a semaphore if it does not require blocking. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_trywait (sem_t *sem) +{ + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value--; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + __pthread_spin_unlock (&sem->__lock); + + errno = EAGAIN; + return -1; +} + +strong_alias (__sem_trywait, sem_trywait); diff --git a/sysdeps/htl/sem-unlink.c b/sysdeps/htl/sem-unlink.c new file mode 100644 index 0000000000..a5f6390124 --- /dev/null +++ b/sysdeps/htl/sem-unlink.c @@ -0,0 +1,31 @@ +/* Unlink a named semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <errno.h> + +#include <pt-internal.h> + +int +__sem_unlink (const char *name) +{ + errno = EOPNOTSUPP; + return -1; +} + +strong_alias (__sem_unlink, sem_unlink); diff --git a/sysdeps/htl/sem-wait.c b/sysdeps/htl/sem-wait.c new file mode 100644 index 0000000000..e45b0b1b89 --- /dev/null +++ b/sysdeps/htl/sem-wait.c @@ -0,0 +1,31 @@ +/* Wait on a semaphore. Generic version. + Copyright (C) 2005-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <semaphore.h> +#include <pt-internal.h> + +extern int __sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout); + +int +__sem_wait (sem_t *sem) +{ + return __sem_timedwait_internal (sem, 0); +} + +strong_alias (__sem_wait, sem_wait); diff --git a/sysdeps/htl/shm-directory.h b/sysdeps/htl/shm-directory.h new file mode 100644 index 0000000000..cddd5e5144 --- /dev/null +++ b/sysdeps/htl/shm-directory.h @@ -0,0 +1,30 @@ +/* Header for directory for shm/sem files. libpthread version. + Copyright (C) 2014-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SHM_DIRECTORY_H + +#include <sysdeps/posix/shm-directory.h> + +/* For libpthread the __shm_directory function lives in libpthread. + We don't want PLT calls from there. But it's also used from + librt, so it cannot just be declared hidden. */ + +#if IS_IN (libpthread) +hidden_proto (__shm_directory) +#endif +#endif /* shm-directory.h */ diff --git a/sysdeps/htl/timer_routines.h b/sysdeps/htl/timer_routines.h new file mode 100644 index 0000000000..a8134f510f --- /dev/null +++ b/sysdeps/htl/timer_routines.h @@ -0,0 +1,46 @@ +/* Helper code for POSIX timer implementation on Hurd. + Copyright (C) 2000-2018 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; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _TIMER_ROUTINES_H +#define _TIMER_ROUTINES_H 1 + +#include <bits/pthreadtypes.h> + +/* Compare two pthread_attr_t thread attributes for exact equality. + Returns 1 if they are equal, otherwise zero if they are not equal + or contain illegal values. This version is Hurd-specific for + performance reason. One could use the access functions to get the + values of all the fields of the attribute structure. */ +static inline int +thread_attr_compare (const pthread_attr_t * left, const pthread_attr_t * right) +{ + struct __pthread_attr *ileft = (struct __pthread_attr *) left; + struct __pthread_attr *iright = (struct __pthread_attr *) right; + + return ileft->__schedparam.sched_priority + == iright->__schedparam.sched_priority + && ileft->__stackaddr == iright->__stackaddr + && ileft->__stacksize == iright->__stacksize + && ileft->__guardsize == iright->__guardsize + && ileft->__detachstate == iright->__detachstate + && ileft->__inheritsched == iright->__inheritsched + && ileft->__contentionscope == iright->__contentionscope + && ileft->__schedpolicy == iright->__schedpolicy; +} + +#endif /* timer_routines.h */ diff --git a/sysdeps/hurd/htl/pt-kill.c b/sysdeps/hurd/htl/pt-kill.c new file mode 100644 index 0000000000..5b72701426 --- /dev/null +++ b/sysdeps/hurd/htl/pt-kill.c @@ -0,0 +1,51 @@ +/* pthread_kill. Hurd version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> +#include <signal.h> +#include <hurd/signal.h> + +#include <pt-internal.h> + +int +__pthread_kill (pthread_t thread, int sig) +{ + struct __pthread *pthread; + struct hurd_signal_detail detail; + struct hurd_sigstate *ss; + + /* Lookup the thread structure for THREAD. */ + pthread = __pthread_getid (thread); + if (pthread == NULL) + return ESRCH; + + ss = _hurd_thread_sigstate (pthread->kernel_thread); + assert (ss); + + if (sig == 0) + return 0; + + detail.exc = 0; + detail.code = sig; + detail.error = 0; + + __spin_lock (&ss->lock); + return _hurd_raise_signal (ss, sig, &detail); +} +strong_alias (__pthread_kill, pthread_kill) diff --git a/sysdeps/i386/htl/bits/pthreadtypes-arch.h b/sysdeps/i386/htl/bits/pthreadtypes-arch.h new file mode 100644 index 0000000000..75ba63223f --- /dev/null +++ b/sysdeps/i386/htl/bits/pthreadtypes-arch.h @@ -0,0 +1,22 @@ +/* Machine-specific pthread type layouts. Hurd i386 version. + Copyright (C) 2002-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_PTHREADTYPES_ARCH_H +#define _BITS_PTHREADTYPES_ARCH_H 1 + +#endif /* bits/pthreadtypes.h */ diff --git a/sysdeps/i386/htl/machine-sp.h b/sysdeps/i386/htl/machine-sp.h new file mode 100644 index 0000000000..8470f2fa97 --- /dev/null +++ b/sysdeps/i386/htl/machine-sp.h @@ -0,0 +1,29 @@ +/* Machine-specific function to return the stack pointer. i386 version. + Copyright (C) 1994-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _MACHINE_SP_H +#define _MACHINE_SP_H + +/* Return the current stack pointer. */ + +#define __thread_stack_pointer() ({ \ + register void *__sp__ asm("esp"); \ + __sp__; \ +}) + +#endif /* machine-sp.h */ diff --git a/sysdeps/i386/htl/pt-machdep.h b/sysdeps/i386/htl/pt-machdep.h new file mode 100644 index 0000000000..bfb50aff15 --- /dev/null +++ b/sysdeps/i386/htl/pt-machdep.h @@ -0,0 +1,28 @@ +/* Machine dependent pthreads internal defenitions. i386 version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_MACHDEP_H +#define _PT_MACHDEP_H 1 + +struct pthread_mcontext +{ + void *pc; + void *sp; +}; + +#endif /* pt-machdep.h */ diff --git a/sysdeps/mach/htl/Implies b/sysdeps/mach/htl/Implies new file mode 100644 index 0000000000..5215f33d98 --- /dev/null +++ b/sysdeps/mach/htl/Implies @@ -0,0 +1 @@ +htl diff --git a/sysdeps/mach/htl/bits/spin-lock-inline.h b/sysdeps/mach/htl/bits/spin-lock-inline.h new file mode 100644 index 0000000000..695c6dccde --- /dev/null +++ b/sysdeps/mach/htl/bits/spin-lock-inline.h @@ -0,0 +1,87 @@ +/* Definitions of user-visible names for spin locks. + Copyright (C) 1994-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_SPIN_LOCK_INLINE_H +#define _BITS_SPIN_LOCK_INLINE_H 1 + +#include <features.h> +#include <bits/types/__pthread_spinlock_t.h> +#include <lock-intern.h> /* This does all the work. */ + +__BEGIN_DECLS + +#if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES + +# ifndef __EBUSY +# include <errno.h> +# define __EBUSY EBUSY +# endif + +# ifndef __PT_SPIN_INLINE +# define __PT_SPIN_INLINE __extern_inline +# endif + +__PT_SPIN_INLINE int __pthread_spin_destroy (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_destroy (__pthread_spinlock_t *__lock) +{ + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_init (__pthread_spinlock_t *__lock, + int __pshared); + +__PT_SPIN_INLINE int +__pthread_spin_init (__pthread_spinlock_t *__lock, int __pshared) +{ + *__lock = __PTHREAD_SPIN_LOCK_INITIALIZER; + return 0; +} + +__PT_SPIN_INLINE int __pthread_spin_trylock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_trylock (__pthread_spinlock_t *__lock) +{ + return __spin_try_lock ((__spin_lock_t *) __lock) ? 0 : __EBUSY; +} + +__PT_SPIN_INLINE int __pthread_spin_lock (__pthread_spinlock_t *__lock); + +__PT_SPIN_INLINE int +__pthread_spin_lock (__pthread_spinlock_t *__lock) +{ + __spin_lock ((__spin_lock_t *) __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 ((__spin_lock_t *) __lock); + return 0; +} + +#endif /* Use extern inlines or force inlines. */ + +__END_DECLS + +#endif /* bits/types/__pthread_spinlock_t.h */ diff --git a/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h new file mode 100644 index 0000000000..038e2b429c --- /dev/null +++ b/sysdeps/mach/htl/bits/types/__pthread_spinlock_t.h @@ -0,0 +1,34 @@ +/* Definitions of user-visible names for spin locks. + Copyright (C) 1994-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES___PTHREAD_SPINLOCK_T_H +#define _BITS_TYPES___PTHREAD_SPINLOCK_T_H 1 + +#include <features.h> + +__BEGIN_DECLS + +/* The type of a spin lock object. */ +typedef volatile int __pthread_spinlock_t; + +/* Initializer for a spin lock object. */ +#define __PTHREAD_SPIN_LOCK_INITIALIZER 0 + +__END_DECLS + +#endif /* bits/types/__pthread_spinlock_t.h */ diff --git a/sysdeps/mach/htl/pt-block.c b/sysdeps/mach/htl/pt-block.c new file mode 100644 index 0000000000..1ffda81f1f --- /dev/null +++ b/sysdeps/mach/htl/pt-block.c @@ -0,0 +1,38 @@ +/* Block a thread. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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/sysdeps/mach/htl/pt-spin.c b/sysdeps/mach/htl/pt-spin.c new file mode 100644 index 0000000000..b2e00eab81 --- /dev/null +++ b/sysdeps/mach/htl/pt-spin.c @@ -0,0 +1,31 @@ +/* Spin locks. Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <machine-lock.h> + +/* In glibc. */ +extern void __spin_lock_solid (__spin_lock_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 (__spin_lock_t *lock) +{ + __spin_lock_solid (lock); + return 0; +} diff --git a/sysdeps/mach/htl/pt-stack-alloc.c b/sysdeps/mach/htl/pt-stack-alloc.c new file mode 100644 index 0000000000..6c38c92f64 --- /dev/null +++ b/sysdeps/mach/htl/pt-stack-alloc.c @@ -0,0 +1,67 @@ +/* Allocate a new stack. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <errno.h> + +#include <mach.h> +#include <mach/machine/vm_param.h> + +#include <pt-internal.h> + +/* 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; + +get_stack: + i++; + for (base = next_stack_base; + base < VM_MAX_ADDRESS + && __vm_allocate (__mach_task_self (), &base, + stacksize, FALSE) != KERN_SUCCESS; base += 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 + stacksize; + + (*stackaddr) = (void *) base; + return 0; +} diff --git a/sysdeps/mach/htl/pt-thread-alloc.c b/sysdeps/mach/htl/pt-thread-alloc.c new file mode 100644 index 0000000000..3c763ef7cb --- /dev/null +++ b/sysdeps/mach/htl/pt-thread-alloc.c @@ -0,0 +1,94 @@ +/* Start thread. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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; + } + + /* No need to queue more than one wakeup message on this port. */ + __mach_port_set_qlimit (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port, 1); + + 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) +{ + static int do_create; + error_t err; + + err = create_wakeupmsg (thread); + if (err) + return err; + + if (!do_create) + { + assert (__pthread_total == 0); + thread->kernel_thread = __mach_thread_self (); + do_create = 1; + } + else + { + err = __thread_create (__mach_task_self (), &thread->kernel_thread); + if (err) + { + __mach_port_destroy (__mach_task_self (), + thread->wakeupmsg.msgh_remote_port); + return EAGAIN; + } + } + + return 0; +} diff --git a/sysdeps/mach/htl/pt-thread-start.c b/sysdeps/mach/htl/pt-thread-start.c new file mode 100644 index 0000000000..571c1f2a62 --- /dev/null +++ b/sysdeps/mach/htl/pt-thread-start.c @@ -0,0 +1,53 @@ +/* Start thread. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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) +{ + static int do_start; + error_t err; + + if (!do_start) + { + /* 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; + })); + do_start = 1; + } + else + { + err = __thread_resume (thread->kernel_thread); + assert_perror (err); + } + + return 0; +} diff --git a/sysdeps/mach/htl/pt-thread-terminate.c b/sysdeps/mach/htl/pt-thread-terminate.c new file mode 100644 index 0000000000..418fb400f5 --- /dev/null +++ b/sysdeps/mach/htl/pt-thread-terminate.c @@ -0,0 +1,82 @@ +/* Deallocate the kernel thread resources. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <errno.h> +#include <mach.h> + +#include <mach/mig_support.h> + +#include <pt-internal.h> + +/* Terminate the kernel thread associated with THREAD, and deallocate its + right reference and its stack. The function also drops a reference + on THREAD. */ +void +__pthread_thread_terminate (struct __pthread *thread) +{ + thread_t kernel_thread, self_ktid; + mach_port_t wakeup_port, reply_port; + void *stackaddr; + size_t stacksize; + error_t err; + + kernel_thread = thread->kernel_thread; + + if (thread->stack) + { + stackaddr = thread->stackaddr; + stacksize = ((thread->guardsize + __vm_page_size - 1) + / __vm_page_size) * __vm_page_size + thread->stacksize; + } + else + { + stackaddr = NULL; + stacksize = 0; + } + + wakeup_port = thread->wakeupmsg.msgh_remote_port; + + /* Each thread has its own reply port, allocated from MiG stub code calling + __mig_get_reply_port. Destroying it is a bit tricky because the calls + involved are also RPCs, causing the creation of a new reply port if + currently null. The __thread_terminate_release call is actually a one way + simple routine designed not to require a reply port. */ + self_ktid = __mach_thread_self (); + reply_port = (self_ktid == kernel_thread) + ? __mig_get_reply_port () : MACH_PORT_NULL; + __mach_port_deallocate (__mach_task_self (), self_ktid); + + /* Finally done with the thread structure. */ + __pthread_dealloc (thread); + + /* The wake up port is now no longer needed. */ + __mach_port_destroy (__mach_task_self (), wakeup_port); + + /* Terminate and release all that's left. */ + err = __thread_terminate_release (kernel_thread, mach_task_self (), + kernel_thread, reply_port, + (vm_address_t) stackaddr, stacksize); + + /* The kernel does not support it yet. Leak but at least terminate + correctly. */ + err = __thread_terminate (kernel_thread); + + /* We are out of luck. */ + assert_perror (err); +} diff --git a/sysdeps/mach/htl/pt-timedblock.c b/sysdeps/mach/htl/pt-timedblock.c new file mode 100644 index 0000000000..4255f77397 --- /dev/null +++ b/sysdeps/mach/htl/pt-timedblock.c @@ -0,0 +1,65 @@ +/* Block a thread with a timeout. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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, clockid_t clock_id) +{ + error_t err; + mach_msg_header_t msg; + mach_msg_timeout_t timeout; + struct timespec now; + + /* We have an absolute time and now we have to convert it to a + relative time. Arg. */ + + err = clock_gettime (clock_id, &now); + assert (!err); + + if (now.tv_sec > abstime->tv_sec + || (now.tv_sec == abstime->tv_sec && now.tv_nsec > abstime->tv_nsec)) + return ETIMEDOUT; + + timeout = (abstime->tv_sec - now.tv_sec) * 1000; + + if (abstime->tv_nsec >= now.tv_nsec) + timeout += (abstime->tv_nsec - now.tv_nsec + 999999) / 1000000; + else + /* Need to do a carry. */ + timeout -= (now.tv_nsec - abstime->tv_nsec + 999999) / 1000000; + + 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/sysdeps/mach/htl/pt-wakeup.c b/sysdeps/mach/htl/pt-wakeup.c new file mode 100644 index 0000000000..1e5488f14b --- /dev/null +++ b/sysdeps/mach/htl/pt-wakeup.c @@ -0,0 +1,37 @@ +/* Wakeup a thread. Mach version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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 | MACH_SEND_TIMEOUT, + sizeof (thread->wakeupmsg), 0, MACH_PORT_NULL, + 0, MACH_PORT_NULL); + assert_perror (err); +} diff --git a/sysdeps/mach/hurd/htl/Implies b/sysdeps/mach/hurd/htl/Implies new file mode 100644 index 0000000000..64daad184a --- /dev/null +++ b/sysdeps/mach/hurd/htl/Implies @@ -0,0 +1,2 @@ +hurd/htl +mach/htl diff --git a/sysdeps/mach/hurd/htl/bits/pthread-np.h b/sysdeps/mach/hurd/htl/bits/pthread-np.h new file mode 100644 index 0000000000..0acee62186 --- /dev/null +++ b/sysdeps/mach/hurd/htl/bits/pthread-np.h @@ -0,0 +1,37 @@ +/* Non-portable functions. Hurd on Mach version. + Copyright (C) 2008-2018 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, see <http://www.gnu.org/licenses/>. */ + +/* + * Never include this file directly; use <pthread.h> or <cthreads.h> instead. + */ + +#ifndef _BITS_PTHREAD_NP_H +#define _BITS_PTHREAD_NP_H 1 + +/* Same as pthread_cond_wait, but for Hurd-specific cancellation. + See hurd_thread_cancel. */ +extern int pthread_hurd_cond_wait_np (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex); + +/* Same as pthread_cond_timedwait, but for Hurd-specific cancellation. + See hurd_thread_cancel. */ +extern int pthread_hurd_cond_timedwait_np (pthread_cond_t *__restrict __cond, + pthread_mutex_t *__restrict __mutex, + const struct timespec *__abstime); + +#endif /* bits/pthread-np.h */ diff --git a/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h new file mode 100644 index 0000000000..4fe87cc5f5 --- /dev/null +++ b/sysdeps/mach/hurd/htl/bits/types/struct___pthread_mutex.h @@ -0,0 +1,49 @@ +/* Mutex type. Generic version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H +#define _BITS_TYPES_STRUCT___PTHREAD_MUTEX_H 1 + +#include <bits/types/struct___pthread_mutexattr.h> + +/* User visible part of a mutex. */ +struct __pthread_mutex +{ + unsigned int __lock; + unsigned int __owner_id; + unsigned int __cnt; + int __shpid; + int __type; + int __flags; + unsigned int __reserved1; + unsigned int __reserved2; +}; + +/* Static mutex initializers. */ +#define __PTHREAD_MUTEX_INITIALIZER \ + { 0, 0, 0, 0, __PTHREAD_MUTEX_TIMED, 0, 0, 0 } + +/* The +1 is to mantain binary compatibility with the old + * libpthread implementation. */ +#define __PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \ + { 0, 0, 0, 0, __PTHREAD_MUTEX_ERRORCHECK + 1, 0, 0, 0 } + +#define __PTHREAD_RECURSIVE_MUTEX_INITIALIZER \ + { 0, 0, 0, 0, __PTHREAD_MUTEX_RECURSIVE + 1, 0, 0, 0 } + +#endif /* bits/types/struct___pthread_mutex.h */ diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c new file mode 100644 index 0000000000..711ae67043 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-attr-setstackaddr.c @@ -0,0 +1,27 @@ +/* pthread_attr_setstackaddr. Hurd on Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr) +{ + attr->__stackaddr = stackaddr; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c new file mode 100644 index 0000000000..6a96370ebe --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-attr-setstacksize.c @@ -0,0 +1,27 @@ +/* pthread_attr_setstacksize. Hurd on Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> + +int +pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) +{ + attr->__stacksize = stacksize; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-docancel.c b/sysdeps/mach/hurd/htl/pt-docancel.c new file mode 100644 index 0000000000..a8bcb24cdb --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-docancel.c @@ -0,0 +1,65 @@ +/* Cancel a thread. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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); + + __pthread_mutex_unlock (&p->cancel_lock); + + 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/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c new file mode 100644 index 0000000000..41792e3711 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-timedwait.c @@ -0,0 +1,169 @@ +/* pthread_hurd_cond_timedwait_np. Hurd-specific wait on a condition. + Copyright (C) 2012-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> +#include <hurd/signal.h> + +#include <pt-internal.h> + +extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec + *abstime); + +int +__pthread_hurd_cond_timedwait_np (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + return __pthread_hurd_cond_timedwait_internal (cond, mutex, abstime); +} + +strong_alias (__pthread_hurd_cond_timedwait_np, pthread_hurd_cond_timedwait_np); + +int +__pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + struct hurd_sigstate *ss = _hurd_self_sigstate (); + struct __pthread *self = _pthread_self (); + error_t err = 0; + int cancel, drain; + clockid_t clock_id = __pthread_default_condattr.__clock; + + /* This function will be called by hurd_thread_cancel while we are blocked + We wake up our thread if it's still blocking or about to block, so it will + progress and notice the cancellation flag. */ + void cancel_me (void) + { + int unblock; + + __pthread_spin_lock (&cond->__lock); + /* The thread only needs to be awaken if it's blocking or about to block. + If it was already unblocked, it's not queued any more. */ + unblock = self->prevp != NULL; + if (unblock) + __pthread_dequeue (self); + __pthread_spin_unlock (&cond->__lock); + + if (unblock) + __pthread_wakeup (self); + } + + assert (ss->intr_port == MACH_PORT_NULL); /* Sanity check for signal bugs. */ + + if (abstime != NULL && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + + /* Atomically enqueue our thread on the condition variable's queue of + waiters, and mark our sigstate to indicate that `cancel_me' must be + called to wake us up. We must hold the sigstate lock while acquiring + the condition variable's lock and tweaking it, so that + hurd_thread_cancel can never suspend us and then deadlock waiting for + the condition variable's lock. */ + + __spin_lock (&ss->lock); + __pthread_spin_lock (&cond->__lock); + cancel = ss->cancel; + if (cancel) + /* We were cancelled before doing anything. Don't block at all. */ + ss->cancel = 0; + else + { + /* Put us on the queue so that pthread_cond_broadcast will know to wake + us up. */ + __pthread_enqueue (&cond->__queue, self); + if (cond->__attr) + clock_id = cond->__attr->__clock; + /* Tell hurd_thread_cancel how to unblock us. */ + ss->cancel_hook = &cancel_me; + } + __pthread_spin_unlock (&cond->__lock); + __spin_unlock (&ss->lock); + + if (cancel) + { + /* Cancelled on entry. Just leave the mutex locked. */ + mutex = NULL; + + __spin_lock (&ss->lock); + } + else + { + /* Release MUTEX before blocking. */ + __pthread_mutex_unlock (mutex); + + /* Block the thread. */ + if (abstime != NULL) + err = __pthread_timedblock (self, abstime, clock_id); + else + { + err = 0; + __pthread_block (self); + } + + /* As it was done when enqueueing, prevent hurd_thread_cancel from + suspending us while the condition lock is held. */ + __spin_lock (&ss->lock); + __pthread_spin_lock (&cond->__lock); + if (self->prevp == NULL) + /* Another thread removed us from the list of waiters, which means + a wakeup message has been sent. It was either consumed while + we were blocking, or queued after we timed out and before we + acquired the condition lock, in which case the message queue + must be drained. */ + drain = err ? 1 : 0; + else + { + /* We're still in the list of waiters. Noone attempted to wake us + up, i.e. we timed out. */ + __pthread_dequeue (self); + drain = 0; + } + __pthread_spin_unlock (&cond->__lock); + + if (drain) + __pthread_block (self); + } + + /* Clear the hook, now that we are done blocking. */ + ss->cancel_hook = NULL; + /* Check the cancellation flag; we might have unblocked due to + cancellation rather than a normal pthread_cond_signal or + pthread_cond_broadcast (or we might have just happened to get cancelled + right after waking up). */ + cancel |= ss->cancel; + ss->cancel = 0; + __spin_unlock (&ss->lock); + + if (mutex != NULL) + /* Reacquire the mutex and return. */ + __pthread_mutex_lock (mutex); + + if (cancel) + return EINTR; + else if (err) + { + assert (err == ETIMEDOUT); + return err; + } + + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c new file mode 100644 index 0000000000..2f2b6c293f --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-hurd-cond-wait.c @@ -0,0 +1,40 @@ +/* pthread_hurd_cond_wait. Hurd-specific wait on a condition. + Copyright (C) 2012-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <assert.h> +#include <hurd/signal.h> + +#include <pt-internal.h> + +/* Implemented in pt-hurd-cond-timedwait.c. */ +extern int __pthread_hurd_cond_timedwait_internal (pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec + *abstime); + +int +__pthread_hurd_cond_wait_np (pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + error_t err; + + err = __pthread_hurd_cond_timedwait_internal (cond, mutex, NULL); + return err == EINTR; +} + +strong_alias (__pthread_hurd_cond_wait_np, pthread_hurd_cond_wait_np); diff --git a/sysdeps/mach/hurd/htl/pt-mutex-consistent.c b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c new file mode 100644 index 0000000000..9fd6342be4 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-consistent.c @@ -0,0 +1,48 @@ +/* pthread_mutex_consistent. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutex_consistent (pthread_mutex_t *mtxp) +{ + int ret = EINVAL; + unsigned int val = mtxp->__lock; + + if ((mtxp->__flags & PTHREAD_MUTEX_ROBUST) != 0 && + (val & LLL_DEAD_OWNER) != 0 && + atomic_compare_and_exchange_bool_acq (&mtxp->__lock, + __getpid () | LLL_WAITERS, + val) == 0) + { + /* The mutex is now ours, and it's consistent. */ + mtxp->__owner_id = _pthread_self ()->thread; + mtxp->__cnt = 1; + ret = 0; + } + + return ret; +} + +weak_alias (pthread_mutex_consistent, pthread_mutex_consistent_np) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-destroy.c b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c new file mode 100644 index 0000000000..89b4916eb6 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-destroy.c @@ -0,0 +1,38 @@ +/* pthread_mutex_destroy. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +_pthread_mutex_destroy (pthread_mutex_t *mtxp) +{ + atomic_read_barrier (); + if (*(volatile unsigned int *) &mtxp->__lock != 0) + return EBUSY; + + mtxp->__type = -1; + return 0; +} + +strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c new file mode 100644 index 0000000000..fa6b82b667 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-getprioceiling.c @@ -0,0 +1,35 @@ +/* pthread_mutex_getprioceiling. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutex_getprioceiling (const pthread_mutex_t *mtxp, int *clp) +{ + (void) mtxp; + (void) clp; + return ENOSYS; +} + +stub_warning (pthread_mutex_getprioceiling) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-init.c b/sysdeps/mach/hurd/htl/pt-mutex-init.c new file mode 100644 index 0000000000..8218eb150e --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-init.c @@ -0,0 +1,56 @@ +/* pthread_mutex_init. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +static const pthread_mutexattr_t dfl_attr = { + .__prioceiling = 0, + .__protocol = PTHREAD_PRIO_NONE, + .__pshared = PTHREAD_PROCESS_PRIVATE, + .__mutex_type = __PTHREAD_MUTEX_TIMED +}; + +int +_pthread_mutex_init (pthread_mutex_t *mtxp, const pthread_mutexattr_t *attrp) +{ + if (attrp == NULL) + attrp = &dfl_attr; + + mtxp->__flags = (attrp->__pshared == PTHREAD_PROCESS_SHARED ? + GSYNC_SHARED : 0) | ((attrp-> + __prioceiling & PTHREAD_MUTEX_ROBUST) ? + PTHREAD_MUTEX_ROBUST : 0); + + mtxp->__type = attrp->__mutex_type + + (attrp->__mutex_type != __PTHREAD_MUTEX_TIMED); + + mtxp->__owner_id = 0; + mtxp->__shpid = 0; + mtxp->__cnt = 0; + mtxp->__lock = 0; + + return 0; +} + +strong_alias (_pthread_mutex_init, pthread_mutex_init) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-lock.c b/sysdeps/mach/hurd/htl/pt-mutex-lock.c new file mode 100644 index 0000000000..e4a86f0e49 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-lock.c @@ -0,0 +1,81 @@ +/* pthread_mutex_lock. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutex_lock (pthread_mutex_t *mtxp) +{ + struct __pthread *self; + int flags = mtxp->__flags & GSYNC_SHARED; + int ret = 0; + + switch (MTX_TYPE (mtxp)) + { + case PT_MTX_NORMAL: + lll_lock (&mtxp->__lock, flags); + break; + + case PT_MTX_RECURSIVE: + self = _pthread_self (); + if (mtx_owned_p (mtxp, self, flags)) + { + if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) + return EAGAIN; + + ++mtxp->__cnt; + return ret; + } + + lll_lock (&mtxp->__lock, flags); + mtx_set_owner (mtxp, self, flags); + mtxp->__cnt = 1; + break; + + case PT_MTX_ERRORCHECK: + self = _pthread_self (); + if (mtx_owned_p (mtxp, self, flags)) + return EDEADLK; + + lll_lock (&mtxp->__lock, flags); + mtx_set_owner (mtxp, self, flags); + break; + + case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST: + case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: + case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: + self = _pthread_self (); + ROBUST_LOCK (self, mtxp, __lll_robust_lock, flags); + break; + + default: + ret = EINVAL; + break; + } + + return ret; +} + +strong_alias (__pthread_mutex_lock, _pthread_mutex_lock) +strong_alias (__pthread_mutex_lock, pthread_mutex_lock) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c new file mode 100644 index 0000000000..5f39ebb959 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-setprioceiling.c @@ -0,0 +1,36 @@ +/* pthread_mutex_setprioceiling. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutex_setprioceiling (pthread_mutex_t *mtxp, int cl, int *prp) +{ + (void) mtxp; + (void) cl; + (void) prp; + return ENOSYS; +} + +stub_warning (pthread_mutex_setprioceiling) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c new file mode 100644 index 0000000000..0457445c86 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-timedlock.c @@ -0,0 +1,79 @@ +/* pthread_mutex_timedlock. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp) +{ + struct __pthread *self; + int ret, flags = mtxp->__flags & GSYNC_SHARED; + + switch (MTX_TYPE (mtxp)) + { + case PT_MTX_NORMAL: + ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags); + break; + + case PT_MTX_RECURSIVE: + self = _pthread_self (); + if (mtx_owned_p (mtxp, self, flags)) + { + if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) + return EAGAIN; + + ++mtxp->__cnt; + ret = 0; + } + else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0) + { + mtx_set_owner (mtxp, self, flags); + mtxp->__cnt = 1; + } + + break; + + case PT_MTX_ERRORCHECK: + self = _pthread_self (); + if (mtx_owned_p (mtxp, self, flags)) + ret = EDEADLK; + else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0) + mtx_set_owner (mtxp, self, flags); + + break; + + case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST: + case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: + case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: + self = _pthread_self (); + ROBUST_LOCK (self, mtxp, lll_robust_abstimed_lock, tsp, flags); + break; + + default: + ret = EINVAL; + break; + } + + return ret; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c new file mode 100644 index 0000000000..e89c8dcac7 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-transfer-np.c @@ -0,0 +1,77 @@ +/* pthread_mutex_transfer_np. Transfer mutex ownership to another thread. + Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutex_transfer_np (pthread_mutex_t *mtxp, pthread_t th) +{ + struct __pthread *self = _pthread_self (); + struct __pthread *pt = __pthread_getid (th); + + if (pt == NULL) + return ESRCH; + else if (pt == self) + return 0; + + int ret = 0; + int flags = mtxp->__flags & GSYNC_SHARED; + + switch (MTX_TYPE (mtxp)) + { + case PT_MTX_NORMAL: + break; + + case PT_MTX_RECURSIVE: + case PT_MTX_ERRORCHECK: + if (!mtx_owned_p (mtxp, self, flags)) + ret = EPERM; + else + mtx_set_owner (mtxp, pt, flags); + + break; + + case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST: + case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: + case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: + /* Note that this can be used to transfer an inconsistent + * mutex as well. The new owner will still have the same + * flags as the original. */ + if (mtxp->__owner_id != self->thread || + (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ()) + ret = EPERM; + else + mtxp->__owner_id = pt->thread; + + break; + + default: + ret = EINVAL; + } + + return ret; +} + +weak_alias (__pthread_mutex_transfer_np, pthread_mutex_transfer_np) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-trylock.c b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c new file mode 100644 index 0000000000..36d4f5921c --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-trylock.c @@ -0,0 +1,85 @@ +/* pthread_mutex_trylock. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutex_trylock (pthread_mutex_t *mtxp) +{ + struct __pthread *self; + int ret; + + switch (MTX_TYPE (mtxp)) + { + case PT_MTX_NORMAL: + ret = lll_trylock (&mtxp->__lock); + if (ret) + ret = EBUSY; + break; + + case PT_MTX_RECURSIVE: + self = _pthread_self (); + if (mtx_owned_p (mtxp, self, mtxp->__flags)) + { + if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) + return EAGAIN; + + ++mtxp->__cnt; + ret = 0; + } + else if ((ret = lll_trylock (&mtxp->__lock)) == 0) + { + mtx_set_owner (mtxp, self, mtxp->__flags); + mtxp->__cnt = 1; + } + else + ret = EBUSY; + + break; + + case PT_MTX_ERRORCHECK: + self = _pthread_self (); + if ((ret = lll_trylock (&mtxp->__lock)) == 0) + mtx_set_owner (mtxp, self, mtxp->__flags); + else + ret = EBUSY; + break; + + case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST: + case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: + case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: + self = _pthread_self (); + ROBUST_LOCK (self, mtxp, __lll_robust_trylock); + break; + + default: + ret = EINVAL; + break; + } + + return ret; +} + +strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock) +strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock) diff --git a/sysdeps/mach/hurd/htl/pt-mutex-unlock.c b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c new file mode 100644 index 0000000000..30c62fcb24 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex-unlock.c @@ -0,0 +1,92 @@ +/* pthread_mutex_unlock. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutex_unlock (pthread_mutex_t *mtxp) +{ + struct __pthread *self; + int ret = 0, flags = mtxp->__flags & GSYNC_SHARED; + + switch (MTX_TYPE (mtxp)) + { + case PT_MTX_NORMAL: + lll_unlock (&mtxp->__lock, flags); + break; + + case PT_MTX_RECURSIVE: + self = _pthread_self (); + if (!mtx_owned_p (mtxp, self, flags)) + ret = EPERM; + else if (--mtxp->__cnt == 0) + { + mtxp->__owner_id = mtxp->__shpid = 0; + lll_unlock (&mtxp->__lock, flags); + } + + break; + + case PT_MTX_ERRORCHECK: + self = _pthread_self (); + if (!mtx_owned_p (mtxp, self, flags)) + ret = EPERM; + else + { + mtxp->__owner_id = mtxp->__shpid = 0; + lll_unlock (&mtxp->__lock, flags); + } + + break; + + case PT_MTX_NORMAL | PTHREAD_MUTEX_ROBUST: + case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: + case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: + self = _pthread_self (); + if (mtxp->__owner_id == NOTRECOVERABLE_ID) + ; /* Nothing to do. */ + else if (mtxp->__owner_id != self->thread || + (int) (mtxp->__lock & LLL_OWNER_MASK) != __getpid ()) + ret = EPERM; + else if (--mtxp->__cnt == 0) + { + /* Release the lock. If it's in an inconsistent + * state, mark it as irrecoverable. */ + mtxp->__owner_id = (mtxp->__lock & LLL_DEAD_OWNER) ? + NOTRECOVERABLE_ID : 0; + __lll_robust_unlock (&mtxp->__lock, flags); + } + + break; + + default: + ret = EINVAL; + break; + } + + return ret; +} + +strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock) +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock) diff --git a/sysdeps/mach/hurd/htl/pt-mutex.h b/sysdeps/mach/hurd/htl/pt-mutex.h new file mode 100644 index 0000000000..2daf63e986 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutex.h @@ -0,0 +1,90 @@ +/* Internal definitions for pthreads library. + Copyright (C) 2016-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_MUTEX_H +#define _PT_MUTEX_H 1 + +/* Special ID used to signal an unrecoverable robust mutex. */ +#define NOTRECOVERABLE_ID (1U << 31) + +/* Common path for robust mutexes. Assumes the variable 'ret' + * is bound in the function this is called from. */ +#define ROBUST_LOCK(self, mtxp, cb, ...) \ + if (mtxp->__owner_id == NOTRECOVERABLE_ID) \ + return ENOTRECOVERABLE; \ + else if (mtxp->__owner_id == self->thread && \ + __getpid () == (int)(mtxp->__lock & LLL_OWNER_MASK)) \ + { \ + if (mtxp->__type == PT_MTX_RECURSIVE) \ + { \ + if (__glibc_unlikely (mtxp->__cnt + 1 == 0)) \ + return EAGAIN; \ + \ + ++mtxp->__cnt; \ + return 0; \ + } \ + else if (mtxp->__type == PT_MTX_ERRORCHECK) \ + return EDEADLK; \ + } \ + \ + ret = cb (&mtxp->__lock, ##__VA_ARGS__); \ + if (ret == 0 || ret == EOWNERDEAD) \ + { \ + if (mtxp->__owner_id == ENOTRECOVERABLE) \ + ret = ENOTRECOVERABLE; \ + else \ + { \ + mtxp->__owner_id = self->thread; \ + mtxp->__cnt = 1; \ + if (ret == EOWNERDEAD) \ + { \ + mtxp->__lock = mtxp->__lock | LLL_DEAD_OWNER; \ + atomic_write_barrier (); \ + } \ + } \ + } \ + (void)0 + +/* Check that a thread owns the mutex. For non-robust, task-shared + * objects, we have to check the thread *and* process-id. */ +#define mtx_owned_p(mtx, pt, flags) \ + ((mtx)->__owner_id == (pt)->thread && \ + (((flags) & GSYNC_SHARED) == 0 || \ + (mtx)->__shpid == __getpid ())) + +/* Record a thread as the owner of the mutex. */ +#define mtx_set_owner(mtx, pt, flags) \ + (void) \ + ({ \ + (mtx)->__owner_id = (pt)->thread; \ + if ((flags) & GSYNC_SHARED) \ + (mtx)->__shpid = __getpid (); \ + }) + +/* Redefined mutex types. The +1 is for binary compatibility. */ +#define PT_MTX_NORMAL __PTHREAD_MUTEX_TIMED +#define PT_MTX_RECURSIVE (__PTHREAD_MUTEX_RECURSIVE + 1) +#define PT_MTX_ERRORCHECK (__PTHREAD_MUTEX_ERRORCHECK + 1) + +/* Mutex type, including robustness. */ +#define MTX_TYPE(mtxp) \ + ((mtxp)->__type | ((mtxp)->__flags & PTHREAD_MUTEX_ROBUST)) + +extern int __getpid (void) __attribute__ ((const)); + +#endif /* pt-mutex.h */ diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c new file mode 100644 index 0000000000..9c6cffc5bd --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-destroy.c @@ -0,0 +1,34 @@ +/* pthread_mutexattr_destroy. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutexattr_destroy (pthread_mutexattr_t *attrp) +{ + (void) attrp; + return 0; +} + +weak_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c new file mode 100644 index 0000000000..4532eca989 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprioceiling.c @@ -0,0 +1,35 @@ +/* pthread_mutexattr_getprioceiling. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *ap, int *clp) +{ + (void) ap; + (void) clp; + return ENOSYS; +} + +stub_warning (pthread_mutexattr_getprioceiling) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c new file mode 100644 index 0000000000..33cdc158b2 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getprotocol.c @@ -0,0 +1,32 @@ +/* pthread_mutexattr_getprotocol. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_getprotocol (const pthread_mutexattr_t *attrp, int *ptp) +{ + *ptp = attrp->__protocol; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c new file mode 100644 index 0000000000..d393b4bb7f --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getpshared.c @@ -0,0 +1,32 @@ +/* pthread_mutexattr_getpshared. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_getpshared (const pthread_mutexattr_t *attrp, int *outp) +{ + *outp = attrp->__pshared; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c new file mode 100644 index 0000000000..0999db02d7 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-getrobust.c @@ -0,0 +1,35 @@ +/* pthread_mutexattr_getrobust. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_getrobust (const pthread_mutexattr_t *attrp, int *outp) +{ + *outp = (attrp->__prioceiling & PTHREAD_MUTEX_ROBUST) ? + PTHREAD_MUTEX_ROBUST : PTHREAD_MUTEX_STALLED; + return 0; +} + +weak_alias (pthread_mutexattr_getrobust, pthread_mutexattr_getrobust_np) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c new file mode 100644 index 0000000000..6881a5b816 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-gettype.c @@ -0,0 +1,32 @@ +/* pthread_mutexattr_gettype. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_gettype (const pthread_mutexattr_t *attrp, int *outp) +{ + *outp = attrp->__mutex_type; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-init.c b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c new file mode 100644 index 0000000000..b135126553 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-init.c @@ -0,0 +1,40 @@ +/* pthread_mutexattr_init. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +static const pthread_mutexattr_t dfl_attr = { + .__prioceiling = 0, + .__protocol = PTHREAD_PRIO_NONE, + .__pshared = PTHREAD_PROCESS_PRIVATE, + .__mutex_type = __PTHREAD_MUTEX_TIMED +}; + +int +__pthread_mutexattr_init (pthread_mutexattr_t *attrp) +{ + *attrp = dfl_attr; + return 0; +} +weak_alias (__pthread_mutexattr_init, pthread_mutexattr_init) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c new file mode 100644 index 0000000000..6011ffb94e --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprioceiling.c @@ -0,0 +1,35 @@ +/* pthread_mutexattr_setprioceiling. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_setprioceiling (pthread_mutexattr_t *attrp, int cl) +{ + (void) attrp; + (void) cl; + return ENOSYS; +} + +stub_warning (pthread_mutexattr_setprioceiling) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c new file mode 100644 index 0000000000..5173a487c4 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setprotocol.c @@ -0,0 +1,34 @@ +/* pthread_mutexattr_setprotocol. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_setprotocol (pthread_mutexattr_t *attrp, int proto) +{ + (void) attrp; + return proto == PTHREAD_PRIO_NONE ? 0 : + proto != PTHREAD_PRIO_INHERIT && + proto != PTHREAD_PRIO_PROTECT ? EINVAL : ENOTSUP; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c new file mode 100644 index 0000000000..7e0e607151 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setpshared.c @@ -0,0 +1,35 @@ +/* pthread_mutexattr_setpshared. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_setpshared (pthread_mutexattr_t *attrp, int pshared) +{ + if (pshared != PTHREAD_PROCESS_PRIVATE && pshared != PTHREAD_PROCESS_SHARED) + return EINVAL; + + attrp->__pshared = pshared; + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c new file mode 100644 index 0000000000..f38c7a747e --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-setrobust.c @@ -0,0 +1,37 @@ +/* pthread_mutexattr_setrobust. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +pthread_mutexattr_setrobust (pthread_mutexattr_t *attrp, int robust) +{ + if (robust != PTHREAD_MUTEX_ROBUST && robust != PTHREAD_MUTEX_STALLED) + return EINVAL; + + attrp->__prioceiling |= robust; + return 0; +} + +weak_alias (pthread_mutexattr_setrobust, pthread_mutexattr_setrobust_np) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c new file mode 100644 index 0000000000..c856fd7859 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr-settype.c @@ -0,0 +1,36 @@ +/* pthread_mutexattr_settype. Hurd version. + Copyright (C) 2016-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program 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. + + This program 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 this program; if not, see + <http://www.gnu.org/licenses/>. +*/ + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <pt-internal.h> +#include "pt-mutex.h" +#include <hurdlock.h> + +int +__pthread_mutexattr_settype (pthread_mutexattr_t *attrp, int type) +{ + if (type < 0 || type > __PTHREAD_MUTEX_RECURSIVE) + return EINVAL; + + attrp->__mutex_type = type; + return 0; +} +weak_alias (__pthread_mutexattr_settype, pthread_mutexattr_settype) diff --git a/sysdeps/mach/hurd/htl/pt-mutexattr.c b/sysdeps/mach/hurd/htl/pt-mutexattr.c new file mode 100644 index 0000000000..40a8c178f1 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-mutexattr.c @@ -0,0 +1 @@ +/* empty */ diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c new file mode 100644 index 0000000000..69de5cad01 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-sigstate-destroy.c @@ -0,0 +1,26 @@ +/* Destroy the signal state. Hurd on Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> + +#include <pt-internal.h> + +void +__pthread_sigstate_destroy (struct __pthread *thread) +{ +} diff --git a/sysdeps/mach/hurd/htl/pt-sigstate-init.c b/sysdeps/mach/hurd/htl/pt-sigstate-init.c new file mode 100644 index 0000000000..a6b4f76b25 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-sigstate-init.c @@ -0,0 +1,44 @@ +/* Initialize the signal state. Hurd on Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <pthread.h> +#include <pt-internal.h> +#include <hurd/signal.h> + +error_t +__pthread_sigstate_init (struct __pthread *thread) +{ + static int do_init_global; + + /* Mark the thread as a global signal receiver so as to conform with + the pthread semantics. However, we must be careful. The first + pthread created is the main thread, during libpthread initialization. + We must not mark it, otherwise the sigprocmask call in + __pthread_create would try to access _hurd_global_sigstate, + which is not initialized yet. When glibc runs _hurdsig_init later + on, the message thread is created, which must not be marked either. */ + if (do_init_global) + { + struct hurd_sigstate *ss = _hurd_thread_sigstate (thread->kernel_thread); + (void) ss; + } + else if (__pthread_num_threads >= 2) + do_init_global = 1; + + return 0; +} diff --git a/sysdeps/mach/hurd/htl/pt-sigstate.c b/sysdeps/mach/hurd/htl/pt-sigstate.c new file mode 100644 index 0000000000..5f0a1b4f9a --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-sigstate.c @@ -0,0 +1,70 @@ +/* Set a thread's signal state. Hurd on Mach version. + Copyright (C) 2002-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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); + + __spin_lock (&ss->lock); + + if (oset != NULL) + *oset = ss->blocked; + + if (set != NULL) + { + 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; + } + ss->blocked &= ~_SIG_CANT_MASK; + } + + if (!err && clear_pending) + __sigemptyset (&ss->pending); + + __spin_unlock (&ss->lock); + + return err; +} diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c new file mode 100644 index 0000000000..40ebc8e6d6 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-sysdep.c @@ -0,0 +1,99 @@ +/* System dependent pthreads code. Hurd version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> + +#include <mach.h> +#include <mach/mig_support.h> + +#include <pt-internal.h> + +__thread struct __pthread *___pthread_self; + +/* 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 *stack) +{ + struct __pthread *thread; + int err; + pthread_attr_t attr, *attrp = 0; + + if (__pthread_threads != NULL) + /* Already initialized */ + return 0; + + /* Initialize the library. */ + ___pthread_init (); + + if (stack != NULL) + { + /* We are getting initialized due to dlopening a library using libpthread + while the main program was not linked against libpthread. */ + /* Avoid allocating another stack */ + attrp = &attr; + pthread_attr_init (attrp); + pthread_attr_setstack (attrp, stack, __vm_page_size); + } + + /* Create the pthread structure for the main thread (i.e. us). */ + err = __pthread_create_internal (&thread, attrp, 0, 0); + assert_perror (err); + + /* XXX The caller copies the command line arguments and the environment + to the new stack. Pretend it wasn't allocated so that it remains + valid if the main thread terminates. */ + thread->stack = 0; + + ___pthread_self = 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); + + return thread->mcontext.sp; +} + +static void * +init_routine (void) +{ + return _init_routine (0); +} + +#ifdef SHARED +__attribute__ ((constructor)) +static void +dynamic_init_routine (void) +{ + _init_routine (__libc_stack_end); +} +#endif diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.h b/sysdeps/mach/hurd/htl/pt-sysdep.h new file mode 100644 index 0000000000..09778068b7 --- /dev/null +++ b/sysdeps/mach/hurd/htl/pt-sysdep.h @@ -0,0 +1,65 @@ +/* Internal definitions for pthreads library. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#ifndef _PT_SYSDEP_H +#define _PT_SYSDEP_H 1 + +#include <mach.h> + +/* XXX */ +#define _POSIX_THREAD_THREADS_MAX 64 + +/* The default stack size. */ +#define PTHREAD_STACK_DEFAULT (8 * 1024 * 1024) + +#define PTHREAD_SYSDEP_MEMBERS \ + thread_t kernel_thread; \ + mach_msg_header_t wakeupmsg; + +extern __thread struct __pthread *___pthread_self; +#define _pthread_self() \ + ({ \ + struct __pthread *thread; \ + \ + assert (__pthread_threads); \ + thread = ___pthread_self; \ + \ + 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/sysdeps/mach/hurd/i386/Implies b/sysdeps/mach/hurd/i386/Implies index 94db5e92ef..eedc9eada9 100644 --- a/sysdeps/mach/hurd/i386/Implies +++ b/sysdeps/mach/hurd/i386/Implies @@ -1 +1,2 @@ mach/hurd/x86 +mach/hurd/i386/htl diff --git a/sysdeps/mach/hurd/i386/htl/Implies b/sysdeps/mach/hurd/i386/htl/Implies new file mode 100644 index 0000000000..7a0f99d772 --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/Implies @@ -0,0 +1,2 @@ +mach/hurd/htl +i386/htl diff --git a/sysdeps/mach/hurd/i386/htl/pt-machdep.c b/sysdeps/mach/hurd/i386/htl/pt-machdep.c new file mode 100644 index 0000000000..9b2083d2da --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/pt-machdep.c @@ -0,0 +1,82 @@ +/* Machine dependent pthreads code. Hurd/i386 version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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/sysdeps/mach/hurd/i386/htl/pt-setup.c b/sysdeps/mach/hurd/i386/htl/pt-setup.c new file mode 100644 index 0000000000..a59f71b7be --- /dev/null +++ b/sysdeps/mach/hurd/i386/htl/pt-setup.c @@ -0,0 +1,110 @@ +/* Setup thread stack. Hurd/i386 version. + Copyright (C) 2000-2018 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, see <http://www.gnu.org/licenses/>. */ + +#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 | + ----------------- + */ + +/* 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 + + ((thread->guardsize + __vm_page_size - 1) + / __vm_page_size) * __vm_page_size); + + if (start_routine != NULL) + { + /* And then the call frame. */ + top -= 3; + top = (uintptr_t *) ((uintptr_t) top & ~0xf); + top[2] = (uintptr_t) arg; /* Argument to START_ROUTINE. */ + top[1] = (uintptr_t) start_routine; + top[0] = (uintptr_t) thread; + *--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) (struct __pthread *, void *(*)(void *), + void *), void *(*start_routine) (void *), + void *arg) +{ + tcbhead_t *tcb; + 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) + /* Fix up the TCB for the main thread. The C library has already + installed a TCB, which we want to keep using. This TCB must not + be freed so don't register it in the thread structure. On the + other hand, it's not yet possible to reliably release a TCB. + Leave the unused one registered so that it doesn't leak. The + only thing left to do is to correctly set the `self' member in + the already existing TCB. */ + tcb = THREAD_SELF; + else + { + err = __thread_set_pcsptp (thread->kernel_thread, + 1, thread->mcontext.pc, + 1, thread->mcontext.sp, + 1, thread->tcb); + assert_perror (err); + tcb = thread->tcb; + } + __mach_port_deallocate (__mach_task_self (), ktid); + + tcb->self = thread->kernel_thread; + + return 0; +} diff --git a/sysdeps/mach/hurd/i386/libpthread.abilist b/sysdeps/mach/hurd/i386/libpthread.abilist new file mode 100644 index 0000000000..e11569f176 --- /dev/null +++ b/sysdeps/mach/hurd/i386/libpthread.abilist @@ -0,0 +1,151 @@ +GLIBC_2.12 GLIBC_2.12 A +GLIBC_2.12 __mutex_lock_solid F +GLIBC_2.12 __mutex_unlock_solid F +GLIBC_2.12 __pthread_get_cleanup_stack F +GLIBC_2.12 __pthread_key_create F +GLIBC_2.12 __pthread_kill F +GLIBC_2.12 __pthread_mutex_transfer_np F +GLIBC_2.12 __pthread_spin_destroy F +GLIBC_2.12 __pthread_spin_init F +GLIBC_2.12 __pthread_spin_lock F +GLIBC_2.12 __pthread_spin_trylock F +GLIBC_2.12 __pthread_spin_unlock F +GLIBC_2.12 _cthread_init_routine D 0x4 +GLIBC_2.12 _cthreads_flockfile F +GLIBC_2.12 _cthreads_ftrylockfile F +GLIBC_2.12 _cthreads_funlockfile F +GLIBC_2.12 _pthread_mutex_destroy F +GLIBC_2.12 _pthread_mutex_init F +GLIBC_2.12 _pthread_mutex_lock F +GLIBC_2.12 _pthread_mutex_trylock F +GLIBC_2.12 _pthread_mutex_unlock F +GLIBC_2.12 _pthread_rwlock_destroy F +GLIBC_2.12 _pthread_rwlock_init F +GLIBC_2.12 _pthread_spin_lock F +GLIBC_2.12 cthread_detach F +GLIBC_2.12 cthread_fork F +GLIBC_2.12 cthread_getspecific F +GLIBC_2.12 cthread_keycreate F +GLIBC_2.12 cthread_setspecific F +GLIBC_2.12 flockfile F +GLIBC_2.12 ftrylockfile F +GLIBC_2.12 funlockfile F +GLIBC_2.12 pthread_atfork F +GLIBC_2.12 pthread_attr_destroy F +GLIBC_2.12 pthread_attr_getdetachstate F +GLIBC_2.12 pthread_attr_getguardsize F +GLIBC_2.12 pthread_attr_getinheritsched F +GLIBC_2.12 pthread_attr_getschedparam F +GLIBC_2.12 pthread_attr_getschedpolicy F +GLIBC_2.12 pthread_attr_getscope F +GLIBC_2.12 pthread_attr_getstack F +GLIBC_2.12 pthread_attr_getstackaddr F +GLIBC_2.12 pthread_attr_getstacksize F +GLIBC_2.12 pthread_attr_init F +GLIBC_2.12 pthread_attr_setdetachstate F +GLIBC_2.12 pthread_attr_setguardsize F +GLIBC_2.12 pthread_attr_setinheritsched F +GLIBC_2.12 pthread_attr_setschedparam F +GLIBC_2.12 pthread_attr_setschedpolicy F +GLIBC_2.12 pthread_attr_setscope F +GLIBC_2.12 pthread_attr_setstack F +GLIBC_2.12 pthread_attr_setstackaddr F +GLIBC_2.12 pthread_attr_setstacksize F +GLIBC_2.12 pthread_barrier_destroy F +GLIBC_2.12 pthread_barrier_init F +GLIBC_2.12 pthread_barrier_wait F +GLIBC_2.12 pthread_barrierattr_destroy F +GLIBC_2.12 pthread_barrierattr_getpshared F +GLIBC_2.12 pthread_barrierattr_init F +GLIBC_2.12 pthread_barrierattr_setpshared F +GLIBC_2.12 pthread_cancel F +GLIBC_2.12 pthread_cond_broadcast F +GLIBC_2.12 pthread_cond_destroy F +GLIBC_2.12 pthread_cond_init F +GLIBC_2.12 pthread_cond_signal F +GLIBC_2.12 pthread_cond_timedwait F +GLIBC_2.12 pthread_cond_wait F +GLIBC_2.12 pthread_condattr_destroy F +GLIBC_2.12 pthread_condattr_getclock F +GLIBC_2.12 pthread_condattr_getpshared F +GLIBC_2.12 pthread_condattr_init F +GLIBC_2.12 pthread_condattr_setclock F +GLIBC_2.12 pthread_condattr_setpshared F +GLIBC_2.12 pthread_create F +GLIBC_2.12 pthread_detach F +GLIBC_2.12 pthread_equal F +GLIBC_2.12 pthread_exit F +GLIBC_2.12 pthread_getattr_np F +GLIBC_2.12 pthread_getconcurrency F +GLIBC_2.12 pthread_getcpuclockid F +GLIBC_2.12 pthread_getschedparam F +GLIBC_2.12 pthread_getspecific F +GLIBC_2.12 pthread_join F +GLIBC_2.12 pthread_key_create F +GLIBC_2.12 pthread_key_delete F +GLIBC_2.12 pthread_kill F +GLIBC_2.12 pthread_mutex_destroy F +GLIBC_2.12 pthread_mutex_getprioceiling F +GLIBC_2.12 pthread_mutex_init F +GLIBC_2.12 pthread_mutex_lock F +GLIBC_2.12 pthread_mutex_setprioceiling F +GLIBC_2.12 pthread_mutex_timedlock F +GLIBC_2.12 pthread_mutex_transfer_np F +GLIBC_2.12 pthread_mutex_trylock F +GLIBC_2.12 pthread_mutex_unlock F +GLIBC_2.12 pthread_mutexattr_destroy F +GLIBC_2.12 pthread_mutexattr_getprioceiling F +GLIBC_2.12 pthread_mutexattr_getprotocol F +GLIBC_2.12 pthread_mutexattr_getpshared F +GLIBC_2.12 pthread_mutexattr_gettype F +GLIBC_2.12 pthread_mutexattr_init F +GLIBC_2.12 pthread_mutexattr_setprioceiling F +GLIBC_2.12 pthread_mutexattr_setprotocol F +GLIBC_2.12 pthread_mutexattr_setpshared F +GLIBC_2.12 pthread_mutexattr_settype F +GLIBC_2.12 pthread_once F +GLIBC_2.12 pthread_rwlock_destroy F +GLIBC_2.12 pthread_rwlock_init F +GLIBC_2.12 pthread_rwlock_rdlock F +GLIBC_2.12 pthread_rwlock_timedrdlock F +GLIBC_2.12 pthread_rwlock_timedwrlock F +GLIBC_2.12 pthread_rwlock_tryrdlock F +GLIBC_2.12 pthread_rwlock_trywrlock F +GLIBC_2.12 pthread_rwlock_unlock F +GLIBC_2.12 pthread_rwlock_wrlock F +GLIBC_2.12 pthread_rwlockattr_destroy F +GLIBC_2.12 pthread_rwlockattr_getpshared F +GLIBC_2.12 pthread_rwlockattr_init F +GLIBC_2.12 pthread_rwlockattr_setpshared F +GLIBC_2.12 pthread_self F +GLIBC_2.12 pthread_setcancelstate F +GLIBC_2.12 pthread_setcanceltype F +GLIBC_2.12 pthread_setconcurrency F +GLIBC_2.12 pthread_setschedparam F +GLIBC_2.12 pthread_setschedprio F +GLIBC_2.12 pthread_setspecific F +GLIBC_2.12 pthread_sigmask F +GLIBC_2.12 pthread_spin_destroy F +GLIBC_2.12 pthread_spin_init F +GLIBC_2.12 pthread_spin_lock F +GLIBC_2.12 pthread_spin_trylock F +GLIBC_2.12 pthread_spin_unlock F +GLIBC_2.12 pthread_testcancel F +GLIBC_2.12 pthread_yield F +GLIBC_2.12 sem_close F +GLIBC_2.12 sem_destroy F +GLIBC_2.12 sem_getvalue F +GLIBC_2.12 sem_init F +GLIBC_2.12 sem_open F +GLIBC_2.12 sem_post F +GLIBC_2.12 sem_timedwait F +GLIBC_2.12 sem_trywait F +GLIBC_2.12 sem_unlink F +GLIBC_2.12 sem_wait F +GLIBC_2.2.6 GLIBC_2.2.6 A +GLIBC_2.2.6 _IO_flockfile F +GLIBC_2.2.6 _IO_ftrylockfile F +GLIBC_2.2.6 _IO_funlockfile F +GLIBC_2.21 GLIBC_2.21 A +GLIBC_2.21 pthread_hurd_cond_timedwait_np F +GLIBC_2.21 pthread_hurd_cond_wait_np F |