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.
This commit is contained in:
Samuel Thibault 2018-04-02 01:43:22 +02:00
parent 03e2aa50fd
commit 33574c17ee
250 changed files with 13927 additions and 0 deletions

View File

@ -1,3 +1,27 @@
2018-04-02 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.
2018-04-02 Samuel Thibault <samuel.thibault@ens-lyon.org>
* sysdeps/pthread/timer_routines.c (__timer_thread_start): Block all

237
htl/Makefile Normal file
View File

@ -0,0 +1,237 @@
#
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2, 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
subdir := htl
srcdir = .
MICROKERNEL := mach
SYSDEPS := lockfile
LCLHDRS :=
libpthread-routines := pt-attr pt-attr-destroy pt-attr-getdetachstate \
pt-attr-getguardsize pt-attr-getinheritsched \
pt-attr-getschedparam pt-attr-getschedpolicy pt-attr-getscope \
pt-attr-getstack pt-attr-getstackaddr pt-attr-getstacksize \
pt-attr-init pt-attr-setdetachstate pt-attr-setguardsize \
pt-attr-setinheritsched pt-attr-setschedparam \
pt-attr-setschedpolicy pt-attr-setscope pt-attr-setstack \
pt-attr-setstackaddr pt-attr-setstacksize \
\
pt-barrier-destroy pt-barrier-init pt-barrier-wait \
pt-barrier pt-barrierattr-destroy pt-barrierattr-init \
pt-barrierattr-getpshared pt-barrierattr-setpshared \
\
pt-destroy-specific pt-init-specific \
pt-key-create pt-key-delete \
pt-getspecific pt-setspecific \
\
pt-once \
\
pt-alloc \
pt-create \
pt-getattr \
pt-equal \
pt-dealloc \
pt-detach \
pt-exit \
pt-initialize \
pt-join \
pt-self \
pt-sigmask \
pt-spin-inlines \
pt-cleanup \
pt-setcancelstate \
pt-setcanceltype \
pt-testcancel \
pt-cancel \
\
pt-mutexattr \
pt-mutexattr-destroy pt-mutexattr-init \
pt-mutexattr-getprioceiling pt-mutexattr-getprotocol \
pt-mutexattr-getpshared pt-mutexattr-gettype \
pt-mutexattr-setprioceiling pt-mutexattr-setprotocol \
pt-mutexattr-setpshared pt-mutexattr-settype \
pt-mutexattr-getrobust pt-mutexattr-setrobust \
\
pt-mutex-init pt-mutex-destroy \
pt-mutex-lock pt-mutex-trylock pt-mutex-timedlock \
pt-mutex-unlock \
pt-mutex-transfer-np \
pt-mutex-getprioceiling pt-mutex-setprioceiling \
pt-mutex-consistent \
\
pt-rwlock-attr \
pt-rwlockattr-init pt-rwlockattr-destroy \
pt-rwlockattr-getpshared pt-rwlockattr-setpshared \
\
pt-rwlock-init pt-rwlock-destroy \
pt-rwlock-rdlock pt-rwlock-tryrdlock \
pt-rwlock-trywrlock pt-rwlock-wrlock \
pt-rwlock-timedrdlock pt-rwlock-timedwrlock \
pt-rwlock-unlock \
\
pt-cond \
pt-condattr-init pt-condattr-destroy \
pt-condattr-getclock pt-condattr-getpshared \
pt-condattr-setclock pt-condattr-setpshared \
\
pt-cond-destroy pt-cond-init \
pt-cond-brdcast \
pt-cond-signal \
pt-cond-wait \
pt-cond-timedwait \
pt-hurd-cond-wait \
pt-hurd-cond-timedwait \
\
pt-stack-alloc \
pt-thread-alloc \
pt-thread-start \
pt-thread-terminate \
pt-startup \
\
pt-getconcurrency pt-setconcurrency \
\
pt-block \
pt-timedblock \
pt-wakeup \
pt-docancel \
pt-sysdep \
pt-setup \
pt-machdep \
pt-spin \
\
pt-sigstate-init \
pt-sigstate-destroy \
pt-sigstate \
\
pt-atfork \
old_pt-atfork \
pt-kill \
pt-getcpuclockid \
\
pt-getschedparam pt-setschedparam pt-setschedprio \
pt-yield \
\
sem-close sem-destroy sem-getvalue sem-init sem-open \
sem-post sem-timedwait sem-trywait sem-unlink \
sem-wait \
\
shm-directory \
\
cthreads-compat \
$(SYSDEPS)
libpthread-static-only-routines = pt-atfork
headers := \
pthread.h \
semaphore.h \
\
bits/pthread.h \
bits/pthread-np.h \
bits/pthreadtypes.h \
bits/pthreadtypes-arch.h \
bits/thread-shared-types.h \
bits/types/struct___pthread_mutex.h \
bits/types/struct___pthread_cond.h \
bits/types/struct___pthread_condattr.h \
bits/types/__pthread_spinlock_t.h \
bits/spin-lock-inline.h \
bits/cancelation.h \
bits/types/struct___pthread_attr.h \
bits/types/struct___pthread_barrierattr.h \
bits/types/struct___pthread_barrier.h \
bits/types/__pthread_key.h \
bits/types/struct___pthread_once.h \
bits/types/struct___pthread_mutexattr.h \
bits/types/struct___pthread_rwlock.h \
bits/types/struct___pthread_rwlockattr.h \
bits/semaphore.h
distribute :=
routines := forward libc_pthread_init alloca_cutoff
shared-only-routines = forward
extra-libs := libpthread
extra-libs-others := $(extra-libs)
install-lib := libpthread.so
include ../Makeconfig
CFLAGS-lockfile.c = -D_IO_MTSAFE_IO
all: # Make this the default target; it will be defined in Rules.
subdir_install: $(inst_libdir)/libpthread2.a
# XXX: If $(inst_libdir)/libpthread2.a is installed and
# $(inst_libdir)/libpthread is not, we can have some issues.
.PHONY: $(inst_libdir)/libpthread.a $(inst_libdir)/libpthread_pic.a
# XXX: These rules are a hack. But it is better than messing with
# ../Makeconf at the moment. Note that the linker scripts
# $(srcdir)/libpthread.a and $(srcdir)/libpthread_pic.a get overwritten
# when building in $(srcdir) and not a seperate build directory.
$(inst_libdir)/libpthread2.a: $(inst_libdir)/libpthread.a
mv $< $@
$(INSTALL_DATA) $(srcdir)/libpthread.a $<
$(inst_libdir)/libpthread2_pic.a: $(inst_libdir)/libpthread_pic.a
mv $< $@
$(INSTALL_DATA) $(srcdir)/libpthread_pic.a $<
libc-link.so = $(common-objpfx)libc.so
extra-B-pthread.so = -B$(common-objpfx)htl/
include ../Rules
ifeq (yes,$(build-shared))
# What we install as libpthread.so for programs to link against is in fact a
# link script. It contains references for the various libraries we need.
# The libpthread.so object is not complete since some functions are only
# defined in libpthread_nonshared.a.
# We need to use absolute paths since otherwise local copies (if they exist)
# of the files are taken by the linker.
install: $(inst_libdir)/libpthread.so
$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
$(objpfx)libpthread.so$(libpthread.so-version) \
$(inst_libdir)/$(patsubst %,$(libtype.oS),\
$(libprefix)pthread) \
$(+force)
(echo '/* GNU ld script';\
echo ' Use the shared library, but some functions are only in';\
echo ' the static library, so try that secondarily. */';\
cat $<; \
echo 'GROUP ( $(slibdir)/libpthread.so$(libpthread.so-version)' \
'$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)pthread)'\
')' \
) > $@.new
mv -f $@.new $@
$(addprefix $(objpfx), \
$(filter-out $(tests-static) $(xtests-static) $(tests-reverse) \
$(tests-nolibpthread), \
$(tests) $(xtests) $(test-srcs))): $(objpfx)libpthread.so \
$(objpfx)libpthread_nonshared.a
endif
generated += libpthread_nonshared.a

156
htl/Versions Normal file
View File

@ -0,0 +1,156 @@
libc {
GLIBC_2.21 {
pthread_attr_destroy; pthread_attr_getdetachstate;
pthread_attr_getinheritsched; pthread_attr_getschedparam;
pthread_attr_getschedpolicy; pthread_attr_getscope; pthread_attr_init;
pthread_attr_setdetachstate; pthread_attr_setinheritsched;
pthread_attr_setschedparam; pthread_attr_setschedpolicy;
pthread_attr_setscope;
pthread_condattr_destroy; pthread_condattr_init;
pthread_cond_broadcast; pthread_cond_destroy;
pthread_cond_init; pthread_cond_signal; pthread_cond_wait;
pthread_cond_timedwait;
pthread_equal;
pthread_exit; pthread_getschedparam; pthread_setschedparam;
pthread_mutex_destroy; pthread_mutex_init;
pthread_mutex_lock; pthread_mutex_trylock; pthread_mutex_unlock;
pthread_self; pthread_setcancelstate; pthread_setcanceltype;
__pthread_get_cleanup_stack;
}
GLIBC_2.22 {
__register_atfork;
}
GLIBC_PRIVATE {
__libc_alloca_cutoff;
__libc_pthread_init;
}
}
libpthread {
GLIBC_2.2.6 {
_IO_flockfile; _IO_ftrylockfile; _IO_funlockfile;
}
GLIBC_2.12 {
__pthread_errorcheck_mutexattr; __pthread_recursive_mutexattr;
__pthread_get_cleanup_stack;
__pthread_mutex_transfer_np;
_pthread_mutex_destroy; _pthread_mutex_init;
_pthread_mutex_lock; _pthread_mutex_trylock; _pthread_mutex_unlock;
_pthread_rwlock_destroy; _pthread_rwlock_init;
_cthread_init_routine;
cthread_detach;
cthread_fork;
cthread_keycreate;
cthread_getspecific;
cthread_setspecific;
__mutex_lock_solid;
__mutex_unlock_solid;
_cthreads_flockfile;
_cthreads_ftrylockfile;
_cthreads_funlockfile;
flockfile; ftrylockfile; funlockfile;
pthread_atfork;
pthread_attr_destroy; pthread_attr_getdetachstate;
pthread_attr_getguardsize; pthread_attr_getinheritsched;
pthread_attr_getschedparam; pthread_attr_getschedpolicy;
pthread_attr_getscope; pthread_attr_getstack; pthread_attr_getstackaddr;
pthread_attr_getstacksize; pthread_attr_init; pthread_attr_setdetachstate;
pthread_attr_setguardsize; pthread_attr_setinheritsched;
pthread_attr_setschedparam; pthread_attr_setschedpolicy;
pthread_attr_setscope; pthread_attr_setstack; pthread_attr_setstackaddr;
pthread_attr_setstacksize;
pthread_barrier_destroy; pthread_barrier_init; pthread_barrier_wait;
pthread_barrierattr_destroy; pthread_barrierattr_getpshared;
pthread_barrierattr_init; pthread_barrierattr_setpshared;
pthread_cancel;
pthread_cond_broadcast; pthread_cond_destroy; pthread_cond_init;
pthread_cond_signal; pthread_cond_timedwait; pthread_cond_wait;
pthread_condattr_destroy; pthread_condattr_getclock;
pthread_condattr_getpshared; pthread_condattr_init;
pthread_condattr_setclock; pthread_condattr_setpshared;
pthread_create; pthread_detach; pthread_equal; pthread_exit;
pthread_getattr_np;
pthread_getconcurrency; pthread_getcpuclockid;
pthread_getschedparam; pthread_getspecific;
pthread_join;
pthread_key_create; pthread_key_delete;
__pthread_key_create;
pthread_kill;
__pthread_kill;
pthread_mutex_destroy; pthread_mutex_getprioceiling;
pthread_mutex_init; pthread_mutex_lock; pthread_mutex_setprioceiling;
pthread_mutex_timedlock; pthread_mutex_transfer_np;
pthread_mutex_trylock; pthread_mutex_unlock;
pthread_mutexattr_destroy; pthread_mutexattr_getprioceiling;
pthread_mutexattr_getprotocol; pthread_mutexattr_getpshared;
pthread_mutexattr_gettype; pthread_mutexattr_init;
pthread_mutexattr_setprioceiling; pthread_mutexattr_setprotocol;
pthread_mutexattr_setpshared; pthread_mutexattr_settype;
pthread_once;
pthread_rwlock_destroy; pthread_rwlock_init; pthread_rwlock_rdlock;
pthread_rwlock_timedrdlock; pthread_rwlock_timedwrlock;
pthread_rwlock_tryrdlock; pthread_rwlock_trywrlock;
pthread_rwlock_unlock; pthread_rwlock_wrlock;
pthread_rwlockattr_destroy; pthread_rwlockattr_getpshared;
pthread_rwlockattr_init; pthread_rwlockattr_setpshared;
pthread_self;
__pthread_self;
pthread_setcancelstate; pthread_setcanceltype;
pthread_setconcurrency; pthread_setschedparam;
pthread_setschedprio; pthread_setspecific;
pthread_sigmask;
pthread_testcancel;
pthread_yield;
sem_close; sem_destroy; sem_getvalue; sem_init; sem_open; sem_post;
sem_timedwait; sem_trywait; sem_unlink; sem_wait;
pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
pthread_spin_trylock; pthread_spin_unlock;
__pthread_spin_destroy; __pthread_spin_init;
__pthread_spin_lock; __pthread_spin_trylock; __pthread_spin_unlock;
_pthread_spin_lock;
}
GLIBC_2.21 {
pthread_hurd_cond_wait_np;
pthread_hurd_cond_timedwait_np;
}
GLIBC_PRIVATE {
__shm_directory;
__pthread_threads;
__cthread_detach;
__cthread_fork;
__cthread_keycreate;
__cthread_getspecific;
__cthread_setspecific;
__pthread_getattr_np;
__pthread_attr_getstack;
}
}

26
htl/alloca_cutoff.c Normal file
View File

@ -0,0 +1,26 @@
/* Allocate a new thread structure.
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 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 <alloca.h>
int
__libc_alloca_cutoff (size_t size)
{
return size <= 65536;
}
libc_hidden_def (__libc_alloca_cutoff)

2
htl/configure vendored Normal file
View File

@ -0,0 +1,2 @@
libc_add_on_canonical=libpthread
libc_add_on_subdirs=.

4
htl/configure.in Normal file
View File

@ -0,0 +1,4 @@
GLIBC_PROVIDES
libc_add_on_canonical=libpthread
libc_add_on_subdirs=.

101
htl/cthreads-compat.c Normal file
View File

@ -0,0 +1,101 @@
/* Compatibility routines for cthreads.
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 <pthreadP.h>
#define CTHREAD_KEY_INVALID (__cthread_key_t) -1
void
__cthread_detach (__cthread_t thread)
{
int err;
err = pthread_detach ((pthread_t) thread);
assert_perror (err);
}
weak_alias (__cthread_detach, cthread_detach)
__cthread_t
__cthread_fork (__cthread_fn_t func, void *arg)
{
pthread_t thread;
int err;
err = pthread_create (&thread, NULL, func, arg);
assert_perror (err);
return (__cthread_t) thread;
}
weak_alias (__cthread_fork, cthread_fork)
int
__cthread_keycreate (__cthread_key_t *key)
{
error_t err;
err = pthread_key_create (key, 0);
if (err)
{
errno = err;
*key = CTHREAD_KEY_INVALID;
err = -1;
}
return err;
}
weak_alias (__cthread_keycreate, cthread_keycreate)
int
__cthread_getspecific (__cthread_key_t key, void **val)
{
*val = pthread_getspecific (key);
return 0;
}
weak_alias (__cthread_getspecific, cthread_getspecific)
int
__cthread_setspecific (__cthread_key_t key, void *val)
{
error_t err;
err = pthread_setspecific (key, (const void *) val);
if (err)
{
errno = err;
err = -1;
}
return err;
}
weak_alias (__cthread_setspecific, cthread_setspecific)
void
__mutex_lock_solid (void *lock)
{
__pthread_mutex_lock (lock);
}
void
__mutex_unlock_solid (void *lock)
{
if (__pthread_spin_trylock (lock) != 0)
/* Somebody already got the lock, that one will manage waking up others */
return;
__pthread_mutex_unlock (lock);
}

283
htl/forward.c Normal file
View File

@ -0,0 +1,283 @@
/* Libc stubs for pthread functions. Hurd pthread 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 <dlfcn.h>
#include <stdlib.h>
#include <shlib-compat.h>
#include <pthread-functions.h>
#include <libc-lock.h>
#include <fork.h>
/* Pointers to the libc functions. */
struct pthread_functions __libc_pthread_functions attribute_hidden;
int __libc_pthread_functions_init attribute_hidden;
#define FORWARD2(name, rettype, decl, params, defaction) \
rettype \
name decl \
{ \
if (!__libc_pthread_functions_init) \
defaction; \
\
return PTHFCT_CALL (ptr_##name, params); \
}
/* Same as FORWARD2, only without return. */
#define FORWARD_NORETURN(name, rettype, decl, params, defaction) \
rettype \
name decl \
{ \
if (!__libc_pthread_functions_init) \
defaction; \
\
PTHFCT_CALL (ptr_##name, params); \
}
#define FORWARD(name, decl, params, defretval) \
FORWARD2 (name, int, decl, params, return defretval)
FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0)
FORWARD (pthread_attr_init, (pthread_attr_t *attr), (attr), 0)
FORWARD (pthread_attr_getdetachstate,
(const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
0)
FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
(attr, detachstate), 0)
FORWARD (pthread_attr_getinheritsched,
(const pthread_attr_t *attr, int *inherit), (attr, inherit), 0)
FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
(attr, inherit), 0)
FORWARD (pthread_attr_getschedparam,
(const pthread_attr_t *attr, struct sched_param *param),
(attr, param), 0)
FORWARD (pthread_attr_setschedparam,
(pthread_attr_t *attr, const struct sched_param *param),
(attr, param), 0)
FORWARD (pthread_attr_getschedpolicy,
(const pthread_attr_t *attr, int *policy), (attr, policy), 0)
FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
(attr, policy), 0)
FORWARD (pthread_attr_getscope,
(const pthread_attr_t *attr, int *scope), (attr, scope), 0)
FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
(attr, scope), 0)
FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0)
FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0)
FORWARD (pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0)
FORWARD (pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0)
FORWARD (pthread_cond_init,
(pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
(cond, cond_attr), 0)
FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0)
FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
(cond, mutex), 0)
FORWARD (pthread_cond_timedwait,
(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime), (cond, mutex, abstime), 0)
FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
(thread1, thread2), 1)
/* Use an alias to avoid warning, as pthread_exit is declared noreturn. */
FORWARD_NORETURN (__pthread_exit, void, (void *retval), (retval),
exit (EXIT_SUCCESS))
strong_alias (__pthread_exit, pthread_exit);
FORWARD (pthread_getschedparam,
(pthread_t target_thread, int *policy, struct sched_param *param),
(target_thread, policy, param), 0)
FORWARD (pthread_setschedparam,
(pthread_t target_thread, int policy,
const struct sched_param *param), (target_thread, policy, param), 0)
FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
FORWARD (pthread_mutex_init,
(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
(mutex, mutexattr), 0)
FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
FORWARD (__pthread_setcancelstate, (int state, int *oldstate),
(state, oldstate), 0)
strong_alias (__pthread_setcancelstate, pthread_setcancelstate);
FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
struct __pthread_cancelation_handler *dummy_list;
FORWARD2 (__pthread_get_cleanup_stack, struct __pthread_cancelation_handler **,
(void), (), return &dummy_list);
/* Fork interaction */
struct atfork
{
void (*prepare) (void);
void (*parent) (void);
void (*child) (void);
void *dso_handle;
struct atfork *prev;
struct atfork *next;
};
/* TODO: better locking */
__libc_lock_define_initialized (static, atfork_lock);
static struct atfork *fork_handlers, *fork_last_handler;
static void
atfork_pthread_prepare (void)
{
struct atfork *handlers, *last_handler;
__libc_lock_lock (atfork_lock);
handlers = fork_handlers;
last_handler = fork_last_handler;
__libc_lock_unlock (atfork_lock);
if (last_handler == NULL)
return;
while (1)
{
if (last_handler->prepare != NULL)
last_handler->prepare ();
if (last_handler == handlers)
break;
last_handler = last_handler->prev;
}
}
text_set_element (_hurd_atfork_prepare_hook, atfork_pthread_prepare);
static void
atfork_pthread_parent (void)
{
struct atfork *handlers;
__libc_lock_lock (atfork_lock);
handlers = fork_handlers;
__libc_lock_unlock (atfork_lock);
while (handlers != NULL)
{
if (handlers->parent != NULL)
handlers->parent ();
handlers = handlers->next;
}
}
text_set_element (_hurd_atfork_parent_hook, atfork_pthread_parent);
static void
atfork_pthread_child (void)
{
struct atfork *handlers;
__libc_lock_lock (atfork_lock);
handlers = fork_handlers;
__libc_lock_unlock (atfork_lock);
while (handlers != NULL)
{
if (handlers->child != NULL)
handlers->child ();
handlers = handlers->next;
}
}
text_set_element (_hurd_atfork_child_hook, atfork_pthread_child);
int
__register_atfork (void (*prepare) (void),
void (*parent) (void),
void (*child) (void),
void *dso_handle)
{
struct atfork *new = malloc (sizeof (*new));
if (new == NULL)
return errno;
new->prepare = prepare;
new->parent = parent;
new->child = child;
new->dso_handle = dso_handle;
new->prev = NULL;
__libc_lock_lock (atfork_lock);
new->next = fork_handlers;
if (fork_handlers != NULL)
fork_handlers->prev = new;
fork_handlers = new;
if (fork_last_handler == NULL)
fork_last_handler = new;
__libc_lock_unlock (atfork_lock);
return 0;
}
libc_hidden_def (__register_atfork)
void
__unregister_atfork (void *dso_handle)
{
struct atfork **handlers, *prev = NULL, *next;
__libc_lock_lock (atfork_lock);
handlers = &fork_handlers;
while (*handlers != NULL)
{
if ((*handlers)->dso_handle == dso_handle)
{
/* Drop this handler from the list. */
if (*handlers == fork_last_handler)
{
/* Was last, new last is prev, if any. */
fork_last_handler = prev;
}
next = (*handlers)->next;
if (next != NULL)
next->prev = prev;
*handlers = next;
}
else
{
/* Just proceed to next handler. */
prev = *handlers;
handlers = &prev->next;
}
}
__libc_lock_unlock (atfork_lock);
}

33
htl/libc_pthread_init.c Normal file
View File

@ -0,0 +1,33 @@
/* libc initialization for libpthread. Hurd pthread 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 <string.h>
#include <pthread-functions.h>
void
__libc_pthread_init (const struct pthread_functions *functions)
{
#ifdef SHARED
/* We copy the content of the variable pointed to by the FUNCTIONS
parameter to one in libc.so since this means access to the array
can be done with one memory access instead of two. */
memcpy (&__libc_pthread_functions, functions,
sizeof (__libc_pthread_functions));
__libc_pthread_functions_init = 1;
#endif
}

22
htl/libpthread.a Normal file
View File

@ -0,0 +1,22 @@
/* pthread initializer is weak in glibc. It must be included if glibc
is to start threading. */
EXTERN(_cthread_init_routine)
/* Weak references in glibc that must be filled if glibc is to be
thread safe. */
EXTERN(cthread_detach)
EXTERN(cthread_fork)
EXTERN(cthread_keycreate)
EXTERN(cthread_getspecific)
EXTERN(cthread_setspecific)
EXTERN(__mutex_lock_solid)
EXTERN(__mutex_unlock_solid)
/* For libio stream locking. */
EXTERN(_cthreads_flockfile)
EXTERN(_cthreads_funlockfile)
EXTERN(_cthreads_ftrylockfile)
/* To get the sigthread stack layout on fork */
EXTERN(pthread_getattr_np)
EXTERN(pthread_attr_getstack)
GROUP(-lpthread2 -lrt)

22
htl/libpthread_pic.a Normal file
View File

@ -0,0 +1,22 @@
/* pthread initializer is weak in glibc. It must be included if glibc
is to start threading. */
EXTERN(_cthread_init_routine)
/* Weak references in glibc that must be filled if glibc is to be
thread safe. */
EXTERN(cthread_detach)
EXTERN(cthread_fork)
EXTERN(cthread_keycreate)
EXTERN(cthread_getspecific)
EXTERN(cthread_setspecific)
EXTERN(__mutex_lock_solid)
EXTERN(__mutex_unlock_solid)
/* For libio stream locking. */
EXTERN(_cthreads_flockfile)
EXTERN(_cthreads_funlockfile)
EXTERN(_cthreads_ftrylockfile)
/* To get the sigthread stack layout on fork */
EXTERN(pthread_getattr_np)
EXTERN(pthread_attr_getstack)
GROUP(-lpthread2_pic)

60
htl/lockfile.c Normal file
View File

@ -0,0 +1,60 @@
/* lockfile - Handle locking and unlocking of streams. Hurd pthread 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 <cthreads.h>
#include <pthread.h> /* Must come before <stdio.h>! */
#include <stdio.h>
void
_cthreads_flockfile (FILE *fp)
{
_IO_lock_lock (*fp->_lock);
}
void
_cthreads_funlockfile (FILE *fp)
{
_IO_lock_unlock (*fp->_lock);
}
int
_cthreads_ftrylockfile (FILE *fp)
{
return __libc_lock_trylock_recursive (*fp->_lock);
}
#undef _IO_flockfile
#undef _IO_funlockfile
#undef _IO_ftrylockfile
#undef flockfile
#undef funlockfile
#undef ftrylockfile
void _IO_flockfile (FILE *)
__attribute__ ((alias ("_cthreads_flockfile")));
void _IO_funlockfile (FILE *)
__attribute__ ((alias ("_cthreads_funlockfile")));
int _IO_ftrylockfile (FILE *)
__attribute__ ((alias ("_cthreads_ftrylockfile")));
void flockfile (FILE *)
__attribute__ ((alias ("_cthreads_flockfile")));
void funlockfile (FILE *)
__attribute__ ((alias ("_cthreads_funlockfile")));
int ftrylockfile (FILE *)
__attribute__ ((alias ("_cthreads_ftrylockfile")));

214
htl/pt-alloc.c Normal file
View File

@ -0,0 +1,214 @@
/* Allocate a new thread structure.
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 <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <pt-internal.h>
/* This braindamage is necessary because the standard says that some
of the threads functions "shall fail" if "No thread could be found
corresponding to that specified by the given thread ID." */
/* Thread ID lookup table. */
struct __pthread **__pthread_threads;
/* The size of the thread ID lookup table. */
int __pthread_max_threads;
/* The total number of thread IDs currently in use, or on the list of
available thread IDs. */
int __pthread_num_threads;
/* A lock for the table, and the other variables above. */
pthread_rwlock_t __pthread_threads_lock;
/* List of thread structures corresponding to free thread IDs. */
struct __pthread *__pthread_free_threads;
pthread_mutex_t __pthread_free_threads_lock;
static inline error_t
initialize_pthread (struct __pthread *new)
{
error_t err;
err = __pthread_init_specific (new);
if (err)
return err;
new->nr_refs = 1;
new->cancel_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
new->cancel_hook = NULL;
new->cancel_hook_arg = NULL;
new->cancel_state = PTHREAD_CANCEL_ENABLE;
new->cancel_type = PTHREAD_CANCEL_DEFERRED;
new->cancel_pending = 0;
new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
new->cancelation_handlers = 0;
memset (&new->res_state, '\0', sizeof (new->res_state));
new->tcb = NULL;
new->next = 0;
new->prevp = 0;
return 0;
}
/* Allocate a new thread structure and its pthread thread ID (but not
a kernel thread). */
int
__pthread_alloc (struct __pthread **pthread)
{
error_t err;
struct __pthread *new;
struct __pthread **threads;
struct __pthread **old_threads;
int max_threads;
int new_max_threads;
pthread_mutex_lock (&__pthread_free_threads_lock);
for (new = __pthread_free_threads; new; new = new->next)
{
/* There is no need to take NEW->STATE_LOCK: if NEW is on this
list, then it is protected by __PTHREAD_FREE_THREADS_LOCK
except in __pthread_dealloc where after it is added to the
list (with the lock held), it drops the lock and then sets
NEW->STATE and immediately stops using NEW. */
if (new->state == PTHREAD_TERMINATED)
{
__pthread_dequeue (new);
break;
}
}
pthread_mutex_unlock (&__pthread_free_threads_lock);
if (new)
{
if (new->tcb)
{
/* Drop old values */
_dl_deallocate_tls (new->tcb, 1);
}
err = initialize_pthread (new);
if (!err)
*pthread = new;
return err;
}
/* Allocate a new thread structure. */
new = malloc (sizeof (struct __pthread));
if (new == NULL)
return ENOMEM;
err = initialize_pthread (new);
if (err)
{
free (new);
return err;
}
retry:
__pthread_rwlock_wrlock (&__pthread_threads_lock);
if (__pthread_num_threads < __pthread_max_threads)
{
/* We have a free slot. Use the slot number plus one as the
thread ID for the new thread. */
new->thread = 1 + __pthread_num_threads++;
__pthread_threads[new->thread - 1] = NULL;
__pthread_rwlock_unlock (&__pthread_threads_lock);
*pthread = new;
return 0;
}
#ifdef PTHREAD_THREADS_MAX
else if (__pthread_num_threads >= PTHREAD_THREADS_MAX)
{
/* We have reached the limit on the number of threads per process. */
__pthread_rwlock_unlock (&__pthread_threads_lock);
free (new);
return EAGAIN;
}
#endif
/* We are going to enlarge the threads table. Save its current
size. We're going to release the lock before doing the necessary
memory allocation, since that's a potentially blocking operation. */
max_threads = __pthread_max_threads;
__pthread_rwlock_unlock (&__pthread_threads_lock);
/* Allocate a new lookup table that's twice as large. */
new_max_threads
= max_threads > 0 ? max_threads * 2 : _POSIX_THREAD_THREADS_MAX;
threads = malloc (new_max_threads * sizeof (struct __pthread *));
if (threads == NULL)
{
free (new);
return ENOMEM;
}
__pthread_rwlock_wrlock (&__pthread_threads_lock);
/* Check if nobody else has already enlarged the table. */
if (max_threads != __pthread_max_threads)
{
/* Yep, they did. */
__pthread_rwlock_unlock (&__pthread_threads_lock);
/* Free the newly allocated table and try again to allocate a slot. */
free (threads);
goto retry;
}
/* Copy over the contents of the old table. */
memcpy (threads, __pthread_threads,
__pthread_max_threads * sizeof (struct __pthread *));
/* Save the location of the old table. We want to deallocate its
storage after we released the lock. */
old_threads = __pthread_threads;
/* Replace the table with the new one. */
__pthread_max_threads = new_max_threads;
__pthread_threads = threads;
/* And allocate ourselves one of the newly created slots. */
new->thread = 1 + __pthread_num_threads++;
__pthread_threads[new->thread - 1] = NULL;
__pthread_rwlock_unlock (&__pthread_threads_lock);
free (old_threads);
*pthread = new;
return 0;
}

62
htl/pt-cancel.c Normal file
View File

@ -0,0 +1,62 @@
/* 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>
int
pthread_cancel (pthread_t t)
{
int err = 0;
struct __pthread *p;
p = __pthread_getid (t);
if (p == NULL)
return ESRCH;
__pthread_mutex_lock (&p->cancel_lock);
if (p->cancel_pending)
{
__pthread_mutex_unlock (&p->cancel_lock);
return 0;
}
p->cancel_pending = 1;
if (p->cancel_state != PTHREAD_CANCEL_ENABLE)
{
__pthread_mutex_unlock (&p->cancel_lock);
return 0;
}
if (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS)
/* CANCEL_LOCK is unlocked by this call. */
err = __pthread_do_cancel (p);
else
{
if (p->cancel_hook != NULL)
/* Thread blocking on a cancellation point. Invoke hook to unblock.
See __pthread_cond_timedwait_internal. */
p->cancel_hook (p->cancel_hook_arg);
__pthread_mutex_unlock (&p->cancel_lock);
}
return err;
}

27
htl/pt-cleanup.c Normal file
View File

@ -0,0 +1,27 @@
/* Add a cancelation handler to the stack.
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>
struct __pthread_cancelation_handler **
__pthread_get_cleanup_stack (void)
{
return &_pthread_self ()->cancelation_handlers;
}

246
htl/pt-create.c Normal file
View File

@ -0,0 +1,246 @@
/* Thread creation.
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 <pthread.h>
#include <signal.h>
#include <resolv.h>
#include <atomic.h>
#include <hurd/resource.h>
#include <pt-internal.h>
#if IS_IN (libpthread)
# include <ctype.h>
#endif
#ifdef HAVE_USELOCALE
# include <locale.h>
#endif
/* The total number of pthreads currently active. This is defined
here since it would be really stupid to have a threads-using
program that doesn't call `pthread_create'. */
unsigned int __pthread_total;
/* The entry-point for new threads. */
static void
entry_point (struct __pthread *self, void *(*start_routine) (void *), void *arg)
{
___pthread_self = self;
__resp = &self->res_state;
#if IS_IN (libpthread)
/* Initialize pointers to locale data. */
__ctype_init ();
#endif
#ifdef HAVE_USELOCALE
/* A fresh thread needs to be bound to the global locale. */
uselocale (LC_GLOBAL_LOCALE);
#endif
__pthread_startup ();
pthread_exit (start_routine (arg));
}
/* Create a thread with attributes given by ATTR, executing
START_ROUTINE with argument ARG. */
int
pthread_create (pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg)
{
int err;
struct __pthread *pthread;
err = __pthread_create_internal (&pthread, attr, start_routine, arg);
if (!err)
*thread = pthread->thread;
else if (err == ENOMEM)
err = EAGAIN;
return err;
}
/* Internal version of pthread_create. See comment in
pt-internal.h. */
int
__pthread_create_internal (struct __pthread **thread,
const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg)
{
int err;
struct __pthread *pthread;
const struct __pthread_attr *setup;
sigset_t sigset;
size_t stacksize;
/* Allocate a new thread structure. */
err = __pthread_alloc (&pthread);
if (err)
goto failed;
/* Use the default attributes if ATTR is NULL. */
setup = attr ? attr : &__pthread_default_attr;
stacksize = setup->__stacksize;
if (stacksize == 0)
{
struct rlimit rlim;
__getrlimit (RLIMIT_STACK, &rlim);
if (rlim.rlim_cur != RLIM_INFINITY)
stacksize = rlim.rlim_cur;
if (stacksize == 0)
stacksize = PTHREAD_STACK_DEFAULT;
}
/* Initialize the thread state. */
pthread->state = (setup->__detachstate == PTHREAD_CREATE_DETACHED
? PTHREAD_DETACHED : PTHREAD_JOINABLE);
if (setup->__stackaddr)
{
pthread->stackaddr = setup->__stackaddr;
/* If the user supplied a stack, it is not our responsibility to
setup a stack guard. */
pthread->guardsize = 0;
pthread->stack = 0;
}
else
{
/* Allocate a stack. */
err = __pthread_stack_alloc (&pthread->stackaddr,
((setup->__guardsize + __vm_page_size - 1)
/ __vm_page_size) * __vm_page_size
+ stacksize);
if (err)
goto failed_stack_alloc;
pthread->guardsize = setup->__guardsize;
pthread->stack = 1;
}
pthread->stacksize = stacksize;
/* Allocate the kernel thread and other required resources. */
err = __pthread_thread_alloc (pthread);
if (err)
goto failed_thread_alloc;
pthread->tcb = _dl_allocate_tls (NULL);
if (pthread->tcb == NULL)
{
err = ENOMEM;
goto failed_thread_tls_alloc;
}
pthread->tcb->tcb = pthread->tcb;
/* And initialize the rest of the machine context. This may include
additional machine- and system-specific initializations that
prove convenient. */
err = __pthread_setup (pthread, entry_point, start_routine, arg);
if (err)
goto failed_setup;
/* Initialize the system-specific signal state for the new
thread. */
err = __pthread_sigstate_init (pthread);
if (err)
goto failed_sigstate;
/* If the new thread is joinable, add a reference for the caller. */
if (pthread->state == PTHREAD_JOINABLE)
pthread->nr_refs++;
/* Set the new thread's signal mask and set the pending signals to
empty. POSIX says: "The signal mask shall be inherited from the
creating thread. The set of signals pending for the new thread
shall be empty." If the currnet thread is not a pthread then we
just inherit the process' sigmask. */
if (__pthread_num_threads == 1)
err = sigprocmask (0, 0, &sigset);
else
err = __pthread_sigstate (_pthread_self (), 0, 0, &sigset, 0);
assert_perror (err);
err = __pthread_sigstate (pthread, SIG_SETMASK, &sigset, 0, 1);
assert_perror (err);
/* Increase the total number of threads. We do this before actually
starting the new thread, since the new thread might immediately
call `pthread_exit' which decreases the number of threads and
calls `exit' if the number of threads reaches zero. Increasing
the number of threads from within the new thread isn't an option
since this thread might return and call `pthread_exit' before the
new thread runs. */
atomic_increment (&__pthread_total);
/* Store a pointer to this thread in the thread ID lookup table. We
could use __thread_setid, however, we only lock for reading as no
other thread should be using this entry (we also assume that the
store is atomic). */
__pthread_rwlock_rdlock (&__pthread_threads_lock);
__pthread_threads[pthread->thread - 1] = pthread;
__pthread_rwlock_unlock (&__pthread_threads_lock);
/* At this point it is possible to guess our pthread ID. We have to
make sure that all functions taking a pthread_t argument can
handle the fact that this thread isn't really running yet. Since
the new thread might be passed its ID through pthread_create (to
avoid calling pthread_self), read it before starting the thread. */
*thread = pthread;
/* Schedule the new thread. */
err = __pthread_thread_start (pthread);
if (err)
goto failed_starting;
return 0;
failed_starting:
/* If joinable, a reference was added for the caller. */
if (pthread->state == PTHREAD_JOINABLE)
__pthread_dealloc (pthread);
__pthread_setid (pthread->thread, NULL);
atomic_decrement (&__pthread_total);
failed_sigstate:
__pthread_sigstate_destroy (pthread);
failed_setup:
_dl_deallocate_tls (pthread->tcb, 1);
pthread->tcb = NULL;
failed_thread_tls_alloc:
__pthread_thread_terminate (pthread);
/* __pthread_thread_terminate has taken care of deallocating the stack and
the thread structure. */
goto failed;
failed_thread_alloc:
if (pthread->stack)
__pthread_stack_dealloc (pthread->stackaddr,
((setup->__guardsize + __vm_page_size - 1)
/ __vm_page_size) * __vm_page_size + stacksize);
failed_stack_alloc:
__pthread_dealloc (pthread);
failed:
return err;
}

68
htl/pt-dealloc.c Normal file
View File

@ -0,0 +1,68 @@
/* Deallocate a thread structure.
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 <pthread.h>
#include <stdlib.h>
#include <pt-internal.h>
#include <atomic.h>
/* List of thread structures corresponding to free thread IDs. */
extern struct __pthread *__pthread_free_threads;
extern pthread_mutex_t __pthread_free_threads_lock;
/* Deallocate the thread structure for PTHREAD. */
void
__pthread_dealloc (struct __pthread *pthread)
{
assert (pthread->state != PTHREAD_TERMINATED);
if (!atomic_decrement_and_test (&pthread->nr_refs))
return;
/* Withdraw this thread from the thread ID lookup table. */
__pthread_setid (pthread->thread, NULL);
/* Mark the thread as terminated. We broadcast the condition
here to prevent pthread_join from waiting for this thread to
exit where it was never really started. Such a call to
pthread_join is completely bogus, but unfortunately allowed
by the standards. */
__pthread_mutex_lock (&pthread->state_lock);
if (pthread->state != PTHREAD_EXITED)
__pthread_cond_broadcast (&pthread->state_cond);
__pthread_mutex_unlock (&pthread->state_lock);
/* We do not actually deallocate the thread structure, but add it to
a list of re-usable thread structures. */
__pthread_mutex_lock (&__pthread_free_threads_lock);
__pthread_enqueue (&__pthread_free_threads, pthread);
__pthread_mutex_unlock (&__pthread_free_threads_lock);
/* Setting PTHREAD->STATE to PTHREAD_TERMINATED makes this TCB
available for reuse. After that point, we can no longer assume
that PTHREAD is valid.
Note that it is safe to not lock this update to PTHREAD->STATE:
the only way that it can now be accessed is in __pthread_alloc,
which reads this variable. */
pthread->state = PTHREAD_TERMINATED;
}

79
htl/pt-detach.c Normal file
View File

@ -0,0 +1,79 @@
/* Detach a thread.
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 <pthread.h>
#include <stddef.h>
#include <pt-internal.h>
/* Indicate that the storage for THREAD can be reclaimed when it
terminates. */
int
pthread_detach (pthread_t thread)
{
struct __pthread *pthread;
int err = 0;
/* Lookup the thread structure for THREAD. */
pthread = __pthread_getid (thread);
if (pthread == NULL)
return ESRCH;
__pthread_mutex_lock (&pthread->state_lock);
switch (pthread->state)
{
case PTHREAD_JOINABLE:
/* THREAD still running. Mark it as detached such that its
resources can be reclaimed as soon as the thread exits. */
pthread->state = PTHREAD_DETACHED;
/* Broadcast the condition. This will make threads that are
waiting to join THREAD continue with hopefully disastrous
consequences instead of blocking indefinitely. */
pthread_cond_broadcast (&pthread->state_cond);
__pthread_mutex_unlock (&pthread->state_lock);
__pthread_dealloc (pthread);
break;
case PTHREAD_EXITED:
__pthread_mutex_unlock (&pthread->state_lock);
/* THREAD has already exited. PTHREAD remained after the thread
exited in order to provide the exit status, but it turns out
it won't be needed. */
__pthread_dealloc (pthread);
break;
case PTHREAD_TERMINATED:
/* Pretend THREAD wasn't there in the first place. */
__pthread_mutex_unlock (&pthread->state_lock);
err = ESRCH;
break;
default:
/* Thou shalt not detach non-joinable threads! */
__pthread_mutex_unlock (&pthread->state_lock);
err = EINVAL;
break;
}
return err;
}

111
htl/pt-exit.c Normal file
View File

@ -0,0 +1,111 @@
/* Thread termination.
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 <pthread.h>
#include <stdlib.h>
#include <pt-internal.h>
#include <atomic.h>
/* Terminate the current thread and make STATUS available to any
thread that might join it. */
void
__pthread_exit (void *status)
{
struct __pthread *self = _pthread_self ();
struct __pthread_cancelation_handler **handlers;
int oldstate;
/* Run any cancelation handlers. According to POSIX, the
cancellation cleanup handlers should be called with cancellation
disabled. */
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
for (handlers = __pthread_get_cleanup_stack ();
*handlers != NULL;
*handlers = (*handlers)->__next)
(*handlers)->__handler ((*handlers)->__arg);
pthread_setcancelstate (oldstate, &oldstate);
/* Decrease the number of threads. We use an atomic operation to
make sure that only the last thread calls `exit'. */
if (atomic_decrement_and_test (&__pthread_total))
/* We are the last thread. */
exit (0);
/* Note that after this point the process can be terminated at any
point if another thread calls `pthread_exit' and happens to be
the last thread. */
__pthread_mutex_lock (&self->state_lock);
if (self->cancel_state == PTHREAD_CANCEL_ENABLE && self->cancel_pending)
status = PTHREAD_CANCELED;
switch (self->state)
{
default:
assert (!"Consistency error: unexpected self->state");
abort ();
break;
case PTHREAD_DETACHED:
__pthread_mutex_unlock (&self->state_lock);
break;
case PTHREAD_JOINABLE:
/* We need to stay around for a while since another thread
might want to join us. */
self->state = PTHREAD_EXITED;
/* We need to remember the exit status. A thread joining us
might ask for it. */
self->status = status;
/* Broadcast the condition. This will wake up threads that are
waiting to join us. */
__pthread_cond_broadcast (&self->state_cond);
__pthread_mutex_unlock (&self->state_lock);
break;
}
/* Destroy any thread specific data. */
__pthread_destroy_specific (self);
/* Destroy any signal state. */
__pthread_sigstate_destroy (self);
/* Self terminating requires TLS, so defer the release of the TCB until
the thread structure is reused. */
/* Release kernel resources, including the kernel thread and the stack,
and drop the self reference. */
__pthread_thread_terminate (self);
/* NOTREACHED */
abort ();
}
strong_alias (__pthread_exit, pthread_exit);

51
htl/pt-getattr.c Normal file
View File

@ -0,0 +1,51 @@
/* Thread attributes retrieval.
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 <assert.h>
#include <errno.h>
#include <pthread.h>
#include <pt-internal.h>
/* 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. */
int
__pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
{
struct __pthread *pthread;
pthread = __pthread_getid (thread);
if (pthread == NULL)
return ESRCH;
/* Some attributes (schedparam, inheritsched, contentionscope and schedpolicy)
are not supported yet, so fill them with our default values. */
*attr = __pthread_default_attr;
attr->__stackaddr = pthread->stackaddr +
((pthread->guardsize + __vm_page_size - 1)
/ __vm_page_size * __vm_page_size);
attr->__stacksize = pthread->stacksize;
attr->__guardsize = pthread->guardsize;
attr->__detachstate = (pthread->state == PTHREAD_DETACHED
? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE);
return 0;
}
weak_alias (__pthread_getattr_np, pthread_getattr_np)

83
htl/pt-initialize.c Normal file
View File

@ -0,0 +1,83 @@
/* Initialize 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/>. */
#include <assert.h>
#include <string.h>
#include <pt-internal.h>
#include <set-hooks.h>
#include <pthread.h>
#include <pthread-functions.h>
#if IS_IN (libpthread)
static const struct pthread_functions pthread_functions = {
.ptr_pthread_attr_destroy = __pthread_attr_destroy,
.ptr_pthread_attr_init = __pthread_attr_init,
.ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
.ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
.ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
.ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
.ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
.ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
.ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
.ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
.ptr_pthread_attr_getscope = __pthread_attr_getscope,
.ptr_pthread_attr_setscope = __pthread_attr_setscope,
.ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
.ptr_pthread_condattr_init = __pthread_condattr_init,
.ptr_pthread_cond_broadcast = __pthread_cond_broadcast,
.ptr_pthread_cond_destroy = __pthread_cond_destroy,
.ptr_pthread_cond_init = __pthread_cond_init,
.ptr_pthread_cond_signal = __pthread_cond_signal,
.ptr_pthread_cond_wait = __pthread_cond_wait,
.ptr_pthread_cond_timedwait = __pthread_cond_timedwait,
.ptr_pthread_equal = __pthread_equal,
.ptr___pthread_exit = __pthread_exit,
.ptr_pthread_getschedparam = __pthread_getschedparam,
.ptr_pthread_setschedparam = __pthread_setschedparam,
.ptr_pthread_mutex_destroy = _pthread_mutex_destroy,
.ptr_pthread_mutex_init = _pthread_mutex_init,
.ptr_pthread_mutex_lock = __pthread_mutex_lock,
.ptr_pthread_mutex_trylock = __pthread_mutex_trylock,
.ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
.ptr_pthread_self = __pthread_self,
.ptr___pthread_setcancelstate = __pthread_setcancelstate,
.ptr_pthread_setcanceltype = __pthread_setcanceltype,
.ptr___pthread_get_cleanup_stack = __pthread_get_cleanup_stack,
.ptr_pthread_once = __pthread_once,
.ptr_pthread_rwlock_rdlock = __pthread_rwlock_rdlock,
.ptr_pthread_rwlock_wrlock = __pthread_rwlock_wrlock,
.ptr_pthread_rwlock_unlock = __pthread_rwlock_unlock,
.ptr___pthread_key_create = __pthread_key_create,
.ptr___pthread_getspecific = __pthread_getspecific,
.ptr___pthread_setspecific = __pthread_setspecific,
.ptr__IO_flockfile = _cthreads_flockfile,
.ptr__IO_funlockfile = _cthreads_funlockfile,
.ptr__IO_ftrylockfile = _cthreads_ftrylockfile,
};
#endif /* IS_IN (libpthread) */
/* Initialize the pthreads library. */
void
___pthread_init (void)
{
#if IS_IN (libpthread)
__libc_pthread_init (&pthread_functions);
#endif
}

324
htl/pt-internal.h Normal file
View File

@ -0,0 +1,324 @@
/* Internal defenitions 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_INTERNAL_H
#define _PT_INTERNAL_H 1
#include <pthread.h>
#include <stddef.h>
#include <sched.h>
#include <signal.h>
#include <assert.h>
#include <bits/types/res_state.h>
#include <atomic.h>
#include <pt-key.h>
#include <pt-sysdep.h>
#include <pt-machdep.h>
#if IS_IN (libpthread)
# include <ldsodefs.h>
#endif
/* Thread state. */
enum pthread_state
{
/* The thread is running and joinable. */
PTHREAD_JOINABLE = 0,
/* The thread is running and detached. */
PTHREAD_DETACHED,
/* A joinable thread exited and its return code is available. */
PTHREAD_EXITED,
/* The thread structure is unallocated and available for reuse. */
PTHREAD_TERMINATED
};
#ifndef PTHREAD_KEY_MEMBERS
# define PTHREAD_KEY_MEMBERS
#endif
#ifndef PTHREAD_SYSDEP_MEMBERS
# define PTHREAD_SYSDEP_MEMBERS
#endif
#if !(IS_IN (libpthread))
/* Type of the TCB. */
typedef struct
{
void *tcb; /* Points to this structure. */
void *dtv; /* Vector of pointers to TLS data. */
thread_t self; /* This thread's control port. */
} tcbhead_t;
#endif /* ! IS_IN (libpthread) */
/* This structure describes a POSIX thread. */
struct __pthread
{
/* Thread ID. */
pthread_t thread;
unsigned int nr_refs; /* Detached threads have a self reference only,
while joinable threads have two references.
These are used to keep the structure valid at
thread destruction. Detaching/joining a thread
drops a reference. */
/* Cancellation. */
pthread_mutex_t cancel_lock; /* Protect cancel_xxx members. */
void (*cancel_hook) (void *); /* Called to unblock a thread blocking
in a cancellation point (namely,
__pthread_cond_timedwait_internal). */
void *cancel_hook_arg;
int cancel_state;
int cancel_type;
int cancel_pending;
struct __pthread_cancelation_handler *cancelation_handlers;
/* Thread stack. */
void *stackaddr;
size_t stacksize;
size_t guardsize;
int stack; /* Nonzero if the stack was allocated. */
/* Exit status. */
void *status;
/* Thread state. */
enum pthread_state state;
pthread_mutex_t state_lock; /* Locks the state. */
pthread_cond_t state_cond; /* Signalled when the state changes. */
/* Resolver state. */
struct __res_state res_state;
/* Thread context. */
struct pthread_mcontext mcontext;
PTHREAD_KEY_MEMBERS
PTHREAD_SYSDEP_MEMBERS
tcbhead_t *tcb;
/* Queue links. Since PREVP is used to determine if a thread has been
awaken, it must be protected by the queue lock. */
struct __pthread *next, **prevp;
};
/* Enqueue an element THREAD on the queue *HEAD. */
static inline void
__pthread_enqueue (struct __pthread **head, struct __pthread *thread)
{
assert (thread->prevp == 0);
thread->next = *head;
thread->prevp = head;
if (*head)
(*head)->prevp = &thread->next;
*head = thread;
}
/* Dequeue the element THREAD from the queue it is connected to. */
static inline void
__pthread_dequeue (struct __pthread *thread)
{
assert (thread);
assert (thread->prevp);
if (thread->next)
thread->next->prevp = thread->prevp;
*thread->prevp = thread->next;
thread->prevp = 0;
}
/* Iterate over QUEUE storing each element in ELEMENT. */
#define __pthread_queue_iterate(queue, element) \
for (struct __pthread *__pdi_next = (queue); \
((element) = __pdi_next) \
&& ((__pdi_next = __pdi_next->next), \
1); \
)
/* Iterate over QUEUE dequeuing each element, storing it in
ELEMENT. */
#define __pthread_dequeuing_iterate(queue, element) \
for (struct __pthread *__pdi_next = (queue); \
((element) = __pdi_next) \
&& ((__pdi_next = __pdi_next->next), \
((element)->prevp = 0), \
1); \
)
/* The total number of threads currently active. */
extern unsigned int __pthread_total;
/* The total number of thread IDs currently in use, or on the list of
available thread IDs. */
extern int __pthread_num_threads;
/* Concurrency hint. */
extern int __pthread_concurrency;
/* Array of __pthread structures and its lock. Indexed by the pthread
id minus one. (Why not just use the pthread id? Because some
brain-dead users of the pthread interface incorrectly assume that 0
is an invalid pthread id.) */
extern struct __pthread **__pthread_threads;
extern pthread_rwlock_t __pthread_threads_lock;
#define __pthread_getid(thread) \
({ struct __pthread *__t; \
__pthread_rwlock_rdlock (&__pthread_threads_lock); \
__t = __pthread_threads[thread - 1]; \
__pthread_rwlock_unlock (&__pthread_threads_lock); \
__t; })
#define __pthread_setid(thread, pthread) \
__pthread_rwlock_wrlock (&__pthread_threads_lock); \
__pthread_threads[thread - 1] = pthread; \
__pthread_rwlock_unlock (&__pthread_threads_lock);
/* Similar to pthread_self, but returns the thread descriptor instead
of the thread ID. */
#ifndef _pthread_self
extern struct __pthread *_pthread_self (void);
#endif
/* Initialize the pthreads library. */
extern void ___pthread_init (void);
/* Internal version of pthread_create. Rather than return the new
tid, we return the whole __pthread structure in *PTHREAD. */
extern int __pthread_create_internal (struct __pthread **__restrict pthread,
const pthread_attr_t *__restrict attr,
void *(*start_routine) (void *),
void *__restrict arg);
/* Allocate a new thread structure and a pthread thread ID (but not a
kernel thread or a stack). THREAD has one reference. */
extern int __pthread_alloc (struct __pthread **thread);
/* Deallocate the thread structure. This is the dual of
__pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
__pthread_thread_terminate). THREAD loses one reference and is
released if the reference counter drops to 0. */
extern void __pthread_dealloc (struct __pthread *thread);
/* Allocate a stack of size STACKSIZE. The stack base shall be
returned in *STACKADDR. */
extern int __pthread_stack_alloc (void **stackaddr, size_t stacksize);
/* Deallocate the stack STACKADDR of size STACKSIZE. */
extern void __pthread_stack_dealloc (void *stackaddr, size_t stacksize);
/* Setup thread THREAD's context. */
extern int __pthread_setup (struct __pthread *__restrict thread,
void (*entry_point) (struct __pthread *,
void *(*)(void *),
void *),
void *(*start_routine) (void *),
void *__restrict arg);
/* Allocate a kernel thread (and any miscellaneous system dependent
resources) for THREAD; it must not be placed on the run queue. */
extern int __pthread_thread_alloc (struct __pthread *thread);
/* Start THREAD making it eligible to run. */
extern int __pthread_thread_start (struct __pthread *thread);
/* Terminate the kernel thread associated with THREAD, and deallocate its
stack as well as any other kernel resource associated with it.
In addition, THREAD looses one reference.
This function can be called by any thread, including the target thread.
Since some resources that are destroyed along the kernel thread are
stored in thread-local variables, the conditions required for this
function to behave correctly are a bit unusual : as long as the target
thread hasn't been started, any thread can terminate it, but once it
has started, no other thread can terminate it, so that thread-local
variables created by that thread are correctly released. */
extern void __pthread_thread_terminate (struct __pthread *thread);
/* Called by a thread just before it calls the provided start
routine. */
extern void __pthread_startup (void);
/* Block THREAD. */
extern void __pthread_block (struct __pthread *thread);
/* Block THREAD until *ABSTIME is reached. */
extern error_t __pthread_timedblock (struct __pthread *__restrict thread,
const struct timespec *__restrict abstime,
clockid_t clock_id);
/* Wakeup THREAD. */
extern void __pthread_wakeup (struct __pthread *thread);
/* Perform a cancelation. The CANCEL_LOCK member of the given thread must
be locked before calling this function, which must unlock it. */
extern int __pthread_do_cancel (struct __pthread *thread);
/* Initialize the thread specific data structures. THREAD must be the
calling thread. */
extern error_t __pthread_init_specific (struct __pthread *thread);
/* Call the destructors on all of the thread specific data in THREAD.
THREAD must be the calling thread. */
extern void __pthread_destroy_specific (struct __pthread *thread);
/* Initialize newly create thread *THREAD's signal state data
structures. */
extern error_t __pthread_sigstate_init (struct __pthread *thread);
/* Destroy the signal state data structures associcated with thread
*THREAD. */
extern void __pthread_sigstate_destroy (struct __pthread *thread);
/* Modify thread *THREAD's signal state. */
extern error_t __pthread_sigstate (struct __pthread *__restrict thread, int how,
const sigset_t *__restrict set,
sigset_t *__restrict oset,
int clear_pending);
/* Default thread attributes. */
extern const struct __pthread_attr __pthread_default_attr;
/* Default barrier attributes. */
extern const struct __pthread_barrierattr __pthread_default_barrierattr;
/* Default mutex attributes. */
extern const struct __pthread_mutexattr __pthread_default_mutexattr;
/* Default rdlock attributes. */
extern const struct __pthread_rwlockattr __pthread_default_rwlockattr;
/* Default condition attributes. */
extern const struct __pthread_condattr __pthread_default_condattr;
#endif /* pt-internal.h */

75
htl/pt-join.c Normal file
View File

@ -0,0 +1,75 @@
/* Wait for thread termination.
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 <pthread.h>
#include <stddef.h>
#include <pt-internal.h>
/* Make calling thread wait for termination of thread THREAD. Return
the exit status of the thread in *STATUS. */
int
pthread_join (pthread_t thread, void **status)
{
struct __pthread *pthread;
int err = 0;
/* Lookup the thread structure for THREAD. */
pthread = __pthread_getid (thread);
if (pthread == NULL)
return ESRCH;
__pthread_mutex_lock (&pthread->state_lock);
pthread_cleanup_push ((void (*)(void *)) __pthread_mutex_unlock,
&pthread->state_lock);
/* Rely on pthread_cond_wait being a cancellation point to make
pthread_join one too. */
while (pthread->state == PTHREAD_JOINABLE)
__pthread_cond_wait (&pthread->state_cond, &pthread->state_lock);
pthread_cleanup_pop (0);
switch (pthread->state)
{
case PTHREAD_EXITED:
/* THREAD has already exited. Salvage its exit status. */
if (status != NULL)
*status = pthread->status;
__pthread_mutex_unlock (&pthread->state_lock);
__pthread_dealloc (pthread);
break;
case PTHREAD_TERMINATED:
/* Pretend THREAD wasn't there in the first place. */
__pthread_mutex_unlock (&pthread->state_lock);
err = ESRCH;
break;
default:
/* Thou shalt not join non-joinable threads! */
__pthread_mutex_unlock (&pthread->state_lock);
err = EINVAL;
break;
}
return err;
}

33
htl/pt-self.c Normal file
View File

@ -0,0 +1,33 @@
/* Get calling thread's ID.
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 the thread ID of the calling thread. */
pthread_t
__pthread_self (void)
{
struct __pthread *self = _pthread_self ();
assert (self != NULL);
return self->thread;
}
strong_alias (__pthread_self, pthread_self);

46
htl/pt-setcancelstate.c Normal file
View File

@ -0,0 +1,46 @@
/* Set the cancel state for the calling 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>
int
__pthread_setcancelstate (int state, int *oldstate)
{
struct __pthread *p = _pthread_self ();
switch (state)
{
default:
return EINVAL;
case PTHREAD_CANCEL_ENABLE:
case PTHREAD_CANCEL_DISABLE:
break;
}
__pthread_mutex_lock (&p->cancel_lock);
if (oldstate != NULL)
*oldstate = p->cancel_state;
p->cancel_state = state;
__pthread_mutex_unlock (&p->cancel_lock);
return 0;
}
strong_alias (__pthread_setcancelstate, pthread_setcancelstate);

46
htl/pt-setcanceltype.c Normal file
View File

@ -0,0 +1,46 @@
/* Set the cancel type for the calling 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>
int
__pthread_setcanceltype (int type, int *oldtype)
{
struct __pthread *p = _pthread_self ();
switch (type)
{
default:
return EINVAL;
case PTHREAD_CANCEL_DEFERRED:
case PTHREAD_CANCEL_ASYNCHRONOUS:
break;
}
__pthread_mutex_lock (&p->cancel_lock);
if (oldtype != NULL)
*oldtype = p->cancel_type;
p->cancel_type = type;
__pthread_mutex_unlock (&p->cancel_lock);
return 0;
}
strong_alias (__pthread_setcanceltype, pthread_setcanceltype);

31
htl/pt-sigmask.c Normal file
View File

@ -0,0 +1,31 @@
/* Get or set a thread's signal mask.
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 <signal.h>
#include <pt-internal.h>
int
pthread_sigmask (int how, const sigset_t *set, sigset_t *oset)
{
struct __pthread *self = _pthread_self ();
/* Do not clear SELF's pending signals. */
return __pthread_sigstate (self, how, set, oset, 0);
}

33
htl/pt-spin-inlines.c Normal file
View File

@ -0,0 +1,33 @@
/* Spin locks non-inline functions.
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/>. */
/* <bits/types/__pthread_spinlock_t.h> declares some extern inline functions. These
functions are declared additionally here for use when inlining is
not possible. */
#define _FORCE_INLINES
#define __PT_SPIN_INLINE /* empty */
#include <pthread.h>
/* Weak aliases for the spin lock functions. */
weak_alias (__pthread_spin_destroy, pthread_spin_destroy);
weak_alias (__pthread_spin_init, pthread_spin_init);
weak_alias (__pthread_spin_trylock, pthread_spin_trylock);
weak_alias (__pthread_spin_lock, pthread_spin_lock);
weak_alias (__pthread_spin_unlock, pthread_spin_unlock);

35
htl/pt-testcancel.c Normal file
View File

@ -0,0 +1,35 @@
/* Add an explicit cancelation point.
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_testcancel (void)
{
struct __pthread *p = _pthread_self ();
int cancelled;
__pthread_mutex_lock (&p->cancel_lock);
cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending;
__pthread_mutex_unlock (&p->cancel_lock);
if (cancelled)
pthread_exit (PTHREAD_CANCELED);
}

26
htl/pt-yield.c Normal file
View File

@ -0,0 +1,26 @@
/* Yield the processor to another thread or process.
Copyright (C) 2010-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>
int
pthread_yield (void)
{
return sched_yield ();
}

1
htl/shlib-versions Normal file
View File

@ -0,0 +1 @@
libpthread=0.3

40
htl/tests/Makefile Normal file
View File

@ -0,0 +1,40 @@
ifdef INSTALL_ROOT
INSTALL_ROOT_CPPFLAGS = -isystem $(INSTALL_ROOT)/include
INSTALL_ROOT_LDFLAGS = -L$(INSTALL_ROOT)/lib -Wl,-rpath,$(INSTALL_ROOT)/lib
endif
CFLAGS=-Wall -g
LDLIBS = -lpthread
CHECK_SRC := test-1.c test-2.c test-3.c test-6.c test-7.c test-8.c \
test-9.c test-10.c test-11.c test-12.c test-13.c test-14.c \
test-15.c test-16.c test-17.c test-__pthread_destroy_specific-skip.c
CHECK_OBJS := $(addsuffix .o,$(basename $(notdir $(CHECK_SRC))))
CHECK_PROGS := $(basename $(notdir $(CHECK_SRC))) \
$(addsuffix -static, $(basename $(CHECK_SRC)))
%.o: %.c
$(CC) $(INSTALL_ROOT_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $< -c -o $@
%: %.o
$(CC) $(INSTALL_ROOT_LDFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
%-static: %.o
$(CC) -static $(INSTALL_ROOT_LDFLAGS) $(LDFLAGS) $< -o $@ $(LDLIBS)
check: $(CHECK_OBJS) $(CHECK_PROGS)
for i in $(CHECK_PROGS); do \
echo -n Running $$i...\ ; \
if ./$$i 2>&1 > $$i.out; \
then \
echo Success.; \
else \
echo Failure.; \
fi \
done
clean:
rm -f $(CHECK_OBJS) $(CHECK_PROGS) \
$(addsuffix .out,$(basename $(notdir $(CHECK_PROGS))))

6
htl/tests/README Normal file
View File

@ -0,0 +1,6 @@
Testing of installed package:
$ [libpthread]/configure --prefix=[install_root]
$ make
$ make install
$ make -C [libpthread]/tests/ INSTALL_ROOT=[install_root] clean check

68
htl/tests/test-1.c Normal file
View File

@ -0,0 +1,68 @@
/* Test mutexes.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
#include <error.h>
#include <errno.h>
#include <stdio.h>
#define THREADS 500
void *
foo (void *arg)
{
pthread_mutex_t *mutex = arg;
pthread_mutex_lock (mutex);
pthread_mutex_unlock (mutex);
return mutex;
}
int
main (int argc, char **argv)
{
int i;
error_t err;
pthread_t tid[THREADS];
pthread_mutex_t mutex[THREADS];
for (i = 0; i < THREADS; i++)
{
pthread_mutex_init (&mutex[i], 0);
pthread_mutex_lock (&mutex[i]);
err = pthread_create (&tid[i], 0, foo, &mutex[i]);
if (err)
error (1, err, "pthread_create");
sched_yield ();
}
for (i = THREADS - 1; i >= 0; i--)
{
void *ret;
pthread_mutex_unlock (&mutex[i]);
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == &mutex[i]);
}
return 0;
}

62
htl/tests/test-10.c Normal file
View File

@ -0,0 +1,62 @@
/* Test error checking mutexes.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
int
main (int argc, char **argv)
{
error_t err;
pthread_mutexattr_t mattr;
pthread_mutex_t mutex;
err = pthread_mutexattr_init (&mattr);
if (err)
error (1, err, "pthread_mutexattr_init");
err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_ERRORCHECK);
if (err)
error (1, err, "pthread_mutexattr_settype");
err = pthread_mutex_init (&mutex, &mattr);
if (err)
error (1, err, "pthread_mutex_init");
err = pthread_mutexattr_destroy (&mattr);
if (err)
error (1, err, "pthread_mutexattr_destroy");
err = pthread_mutex_lock (&mutex);
assert (err == 0);
err = pthread_mutex_lock (&mutex);
assert (err == EDEADLK);
err = pthread_mutex_unlock (&mutex);
assert (err == 0);
err = pthread_mutex_unlock (&mutex);
assert (err == EPERM);
return 0;
}

159
htl/tests/test-11.c Normal file
View File

@ -0,0 +1,159 @@
/* Test rwlocks.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#define THREADS 1
int a;
int b;
/* Get a read lock and assert that a == b. */
void *
test1 (void *arg)
{
error_t err;
pthread_rwlock_t *lock = arg;
int i;
for (i = 0; i < 200; i++)
{
err = pthread_rwlock_rdlock (lock);
assert (err == 0);
assert (a == b);
sched_yield ();
assert (a == b);
err = pthread_rwlock_unlock (lock);
assert (err == 0);
}
return 0;
}
int
main (int argc, char **argv)
{
error_t err;
pthread_rwlockattr_t attr;
pthread_rwlock_t lock;
int pshared;
int i;
pthread_t tid[THREADS];
void *ret;
err = pthread_rwlockattr_init (&attr);
if (err)
error (1, err, "pthread_rwlockattr_init");
err = pthread_rwlockattr_getpshared (&attr, &pshared);
if (err)
error (1, err, "pthread_rwlockattr_getpshared");
/* Assert the default state as mandated by POSIX. */
assert (pshared == PTHREAD_PROCESS_PRIVATE);
err = pthread_rwlockattr_setpshared (&attr, pshared);
if (err)
error (1, err, "pthread_rwlockattr_setpshared");
err = pthread_rwlock_init (&lock, &attr);
if (err)
error (1, err, "pthread_rwlock_init");
err = pthread_rwlockattr_destroy (&attr);
if (err)
error (1, err, "pthread_rwlockattr_destroy");
/* Now test the lock. */
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, test1, &lock);
if (err)
error (1, err, "pthread_create");
}
for (i = 0; i < 10; i++)
{
sched_yield ();
/* Get a write lock. */
pthread_rwlock_wrlock (&lock);
/* Increment a and b giving other threads a chance to run in
between. */
sched_yield ();
a++;
sched_yield ();
b++;
sched_yield ();
/* Unlock. */
pthread_rwlock_unlock (&lock);
}
for (i = 0; i < THREADS; i++)
{
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
}
/* Read lock it. */
err = pthread_rwlock_tryrdlock (&lock);
assert (err == 0);
/* Try to write lock it. It should fail with EBUSY. */
err = pthread_rwlock_trywrlock (&lock);
assert (err == EBUSY);
/* Drop the read lock. */
err = pthread_rwlock_unlock (&lock);
assert (err == 0);
/* Get a write lock. */
err = pthread_rwlock_trywrlock (&lock);
assert (err == 0);
/* Fail trying to acquire another write lock. */
err = pthread_rwlock_trywrlock (&lock);
assert (err == EBUSY);
/* Try to get a read lock which should also fail. */
err = pthread_rwlock_tryrdlock (&lock);
assert (err == EBUSY);
/* Unlock it. */
err = pthread_rwlock_unlock (&lock);
assert (err == 0);
err = pthread_rwlock_destroy (&lock);
if (err)
error (1, err, "pthread_rwlock_destroy");
return 0;
}

45
htl/tests/test-12.c Normal file
View File

@ -0,0 +1,45 @@
/* Test concurrency level.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
int
main (int argc, char **argv)
{
int i;
int err;
i = pthread_getconcurrency ();
assert (i == 0);
err = pthread_setconcurrency (-1);
assert (err == EINVAL);
err = pthread_setconcurrency (4);
assert (err == 0);
i = pthread_getconcurrency ();
assert (i == 4);
return 0;
}

82
htl/tests/test-13.c Normal file
View File

@ -0,0 +1,82 @@
/* Test condition attributes and pthread_cond_timedwait.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <sys/time.h>
int
main (int argc, char **argv)
{
error_t err;
int i;
pthread_condattr_t attr;
pthread_cond_t cond;
struct timespec ts;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
struct timeval before, after;
int diff;
err = pthread_condattr_init (&attr);
if (err)
error (1, err, "pthread_condattr_init");
err = pthread_condattr_getpshared (&attr, &i);
if (err)
error (1, err, "pthread_condattr_getpshared");
assert (i == PTHREAD_PROCESS_PRIVATE);
err = pthread_condattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
assert (err == 0);
err = pthread_cond_init (&cond, &attr);
if (err)
error (1, err, "pthread_cond_init");
err = pthread_condattr_destroy (&attr);
if (err)
error (1, err, "pthread_condattr_destroy");
gettimeofday (&before, 0);
ts.tv_sec = before.tv_sec + 1;
ts.tv_nsec = before.tv_usec * 1000;
printf ("Starting wait @ %d\n", (int) before.tv_sec);
pthread_mutex_lock (&m);
err = pthread_cond_timedwait (&cond, &m, &ts);
gettimeofday (&after, 0);
printf ("End wait @ %d (err = %d)\n", (int) after.tv_sec, err);
assert (err == ETIMEDOUT);
diff = after.tv_sec * 1000000 + after.tv_usec
- before.tv_sec * 1000000 - before.tv_usec;
if (diff < 900000 || diff > 1100000)
error (1, EGRATUITOUS, "pthread_cond_timedwait waited %d us", diff);
return 0;
}

60
htl/tests/test-14.c Normal file
View File

@ -0,0 +1,60 @@
/* Test pthread_mutex_timedlock.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <sys/time.h>
int
main (int argc, char **argv)
{
error_t err;
struct timespec ts;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
struct timeval before, after;
int diff;
gettimeofday (&before, 0);
ts.tv_sec = before.tv_sec + 1;
ts.tv_nsec = before.tv_usec * 1000;
printf ("Starting wait @ %d\n", (int) before.tv_sec);
pthread_mutex_lock (&m);
/* A default mutex shall dead lock if locked twice. As such we do
not need spawn a second thread. */
err = pthread_mutex_timedlock (&m, &ts);
assert (err == ETIMEDOUT);
gettimeofday (&after, 0);
printf ("End wait @ %d\n", (int) after.tv_sec);
diff = after.tv_sec * 1000000 + after.tv_usec
- before.tv_sec * 1000000 - before.tv_usec;
if (diff < 900000 || diff > 1100000)
error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
return 0;
}

102
htl/tests/test-15.c Normal file
View File

@ -0,0 +1,102 @@
/* Test pthread_rwlock_timedrdlock and pthread_rwlock_timedwrlock.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <sys/time.h>
#define THREADS 10
pthread_rwlock_t rwlock;
void *
test (void *arg)
{
error_t err;
int foo = (int) arg;
struct timespec ts;
struct timeval before, after;
int diff;
gettimeofday (&before, 0);
ts.tv_sec = before.tv_sec + 1;
ts.tv_nsec = before.tv_usec * 1000;
printf ("Thread %d starting wait @ %d\n", pthread_self (),
(int) before.tv_sec);
if (foo % 2 == 0)
err = pthread_rwlock_timedrdlock (&rwlock, &ts);
else
err = pthread_rwlock_timedwrlock (&rwlock, &ts);
assert (err == ETIMEDOUT);
gettimeofday (&after, 0);
printf ("Thread %d ending wait @ %d\n", pthread_self (), (int) after.tv_sec);
diff = after.tv_sec * 1000000 + after.tv_usec
- before.tv_sec * 1000000 - before.tv_usec;
if (diff < 900000 || diff > 1100000)
error (1, EGRATUITOUS, "pthread_mutex_timedlock waited %d us", diff);
return 0;
}
int
main (int argc, char **argv)
{
error_t err;
int i;
pthread_t tid[THREADS];
err = pthread_rwlock_init (&rwlock, 0);
if (err)
error (1, err, "pthread_rwlock_init");
/* Lock it so all the threads will block. */
err = pthread_rwlock_wrlock (&rwlock);
assert (err == 0);
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, test, (void *) i);
if (err)
error (1, err, "pthread_create");
}
for (i = 0; i < THREADS; i++)
{
void *ret;
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == 0);
}
return 0;
}

87
htl/tests/test-16.c Normal file
View File

@ -0,0 +1,87 @@
/* Test pthread_kill.c.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <hurd/signal.h>
pthread_t testthread;
int i;
void *
test (void *arg)
{
error_t err;
printf ("test: %d\n", pthread_self ());
err = pthread_kill (pthread_self (), SIGINFO);
if (err)
error (1, err, "pthread_kill");
/* To avoid using condition variables in a signal handler. */
while (i == 0)
sched_yield ();
return 0;
}
static void
handler (int sig)
{
assert (pthread_equal (pthread_self (), testthread));
printf ("handler: %d\n", pthread_self ());
i = 1;
}
int
main (int argc, char **argv)
{
error_t err;
struct sigaction sa;
void *ret;
printf ("main: %d\n", pthread_self ());
sa.sa_handler = handler;
sa.sa_mask = 0;
sa.sa_flags = 0;
err = sigaction (SIGINFO, &sa, 0);
if (err)
error (1, err, "sigaction");
err = pthread_create (&testthread, 0, test, 0);
if (err)
error (1, err, "pthread_create");
err = pthread_join (testthread, &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == 0);
return 0;
}

73
htl/tests/test-17.c Normal file
View File

@ -0,0 +1,73 @@
/* Test that the key reuse inside libpthread does not cause thread
specific values to persist.
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/>. */
#define _GNU_SOURCE 1
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
void
work (int iter)
{
error_t err;
pthread_key_t key1;
pthread_key_t key2;
void *value1;
void *value2;
printf ("work/%d: start\n", iter);
err = pthread_key_create (&key1, NULL);
assert (err == 0);
err = pthread_key_create (&key2, NULL);
assert (err == 0);
value1 = pthread_getspecific (key1);
value2 = pthread_getspecific (key2);
printf ("work/%d: pre-setspecific: %p,%p\n", iter, value1, value2);
assert (value1 == NULL);
assert (value2 == NULL);
err = pthread_setspecific (key1, (void *) (0x100 + iter));
assert (err == 0);
err = pthread_setspecific (key2, (void *) (0x200 + iter));
assert (err == 0);
value1 = pthread_getspecific (key1);
value2 = pthread_getspecific (key2);
printf ("work/%d: post-setspecific: %p,%p\n", iter, value1, value2);
assert (value1 == (void *) (0x100 + iter));
assert (value2 == (void *) (0x200 + iter));
err = pthread_key_delete (key1);
assert (err == 0);
err = pthread_key_delete (key2);
assert (err == 0);
}
int
main (int argc, char *argv[])
{
int i;
for (i = 0; i < 8; ++i)
work (i + 1);
return 0;
}

56
htl/tests/test-2.c Normal file
View File

@ -0,0 +1,56 @@
/* Test detachability.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#include <unistd.h>
void *
thread (void *arg)
{
while (1)
sched_yield ();
}
int
main (int argc, char **argv)
{
int err;
pthread_t tid;
void *ret;
err = pthread_create (&tid, 0, thread, 0);
if (err)
error (1, err, "pthread_create");
err = pthread_detach (tid);
if (err)
error (1, err, "pthread_detach");
err = pthread_detach (tid);
assert (err == EINVAL);
err = pthread_join (tid, &ret);
assert (err == EINVAL);
return 0;
}

71
htl/tests/test-3.c Normal file
View File

@ -0,0 +1,71 @@
/* Test the thread attribute get and set methods.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#include <assert.h>
#include <errno.h>
int
main (int argc, char *argv[])
{
error_t err;
pthread_attr_t attr;
int i;
struct sched_param sp;
void *p;
size_t sz;
err = pthread_attr_init (&attr);
assert_perror (err);
err = pthread_attr_destroy (&attr);
assert_perror (err);
err = pthread_attr_init (&attr);
assert_perror (err);
#define TEST1(foo, rv, v) \
err = pthread_attr_get##foo (&attr, rv); \
assert_perror (err); \
\
err = pthread_attr_set##foo (&attr, v); \
assert_perror (err);
#define TEST(foo, rv, v) TEST1(foo, rv, v)
TEST (inheritsched, &i, i);
TEST (schedparam, &sp, &sp);
TEST (schedpolicy, &i, i);
TEST (scope, &i, i);
TEST (stackaddr, &p, p);
TEST (detachstate, &i, i);
TEST (guardsize, &sz, sz);
TEST (stacksize, &sz, sz);
err = pthread_attr_getstack (&attr, &p, &sz);
assert_perror (err);
err = pthread_attr_setstack (&attr, p, sz);
assert_perror (err);
return 0;
}

102
htl/tests/test-4.c Normal file
View File

@ -0,0 +1,102 @@
/* Test the stack guard.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
size_t stacksize;
void *
thr (void *arg)
{
int i;
char *foo;
foo = alloca (3 * stacksize / 4);
for (i = 0; i < sizeof foo; i++)
foo[i] = -1;
return (void *) 1;
}
int
main (int argc, char *argv[])
{
error_t err;
pid_t child;
child = fork ();
switch (child)
{
case -1:
error (1, errno, "fork");
break;
case 0:
{
pthread_attr_t attr;
pthread_t tid;
void *ret;
err = pthread_attr_init (&attr);
assert_perror (err);
err = pthread_attr_getstacksize (&attr, &stacksize);
assert_perror (err);
err = pthread_attr_setguardsize (&attr, stacksize / 2);
if (err == ENOTSUP)
{
printf ("Stack guard attribute not supported.\n");
return 1;
}
assert_perror (err);
err = pthread_create (&tid, &attr, thr, 0);
assert_perror (err);
err = pthread_attr_destroy (&attr);
assert_perror (err);
err = pthread_join (tid, &ret);
/* Should never be successful. */
printf ("Thread did not segfault!?!\n");
assert_perror (err);
return 0;
}
default:
{
pid_t pid;
int status;
pid = waitpid (child, &status, 0);
printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
assert (pid == child);
assert (status != 0);
}
}
return 0;
}

91
htl/tests/test-5.c Normal file
View File

@ -0,0 +1,91 @@
/* Test signals.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <error.h>
#include <assert.h>
#include <sys/resource.h>
#include <sys/wait.h>
void *
thr (void *arg)
{
*(int *) 0 = 0;
return 0;
}
int foobar;
int
main (int argc, char *argv[])
{
error_t err;
pid_t child;
struct rlimit limit;
limit.rlim_cur = 0;
limit.rlim_max = 0;
err = setrlimit (RLIMIT_CORE, &limit);
if (err)
error (1, err, "setrlimit");
child = fork ();
switch (child)
{
case -1:
error (1, errno, "fork");
break;
case 0:
{
pthread_t tid;
void *ret;
err = pthread_create (&tid, 0, thr, 0);
if (err)
error (1, err, "pthread_create");
err = pthread_join (tid, &ret);
assert_perror (err);
/* Should have never returned. Our parent expects us to fail
thus we succeed and indicate the error. */
return 0;
}
default:
{
pid_t pid;
int status;
pid = waitpid (child, &status, 0);
printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
assert (pid == child);
assert (status != 0);
}
}
return 0;
}

114
htl/tests/test-6.c Normal file
View File

@ -0,0 +1,114 @@
/* Test barriers.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <error.h>
#include <assert.h>
#include <errno.h>
#define THREADS 500
#define WAITS 3
void *
dowait (void *arg)
{
pthread_barrier_t *barrier = arg;
int ret;
ret = pthread_barrier_wait (barrier);
printf ("%d ", pthread_self ());
return (void *) ret;
}
int
main (int argc, char **argv)
{
pthread_barrierattr_t attr;
pthread_barrier_t barrier;
int i, j;
error_t err;
pthread_t tid[THREADS];
int havesyncs;
err = pthread_barrierattr_init (&attr);
if (err)
error (1, err, "pthread_barrierattr_init");
err = pthread_barrierattr_getpshared (&attr, &i);
if (err)
error (1, err, "pthread_barrierattr_getpshared");
assert (i == PTHREAD_PROCESS_PRIVATE || i == PTHREAD_PROCESS_SHARED);
err = pthread_barrierattr_setpshared (&attr, PTHREAD_PROCESS_PRIVATE);
if (err)
error (1, err, "pthread_barrierattr_setpshared");
err = pthread_barrier_init (&barrier, &attr, THREADS + 1);
if (err)
error (1, err, "pthread_barrier_init");
for (j = 0; j < WAITS; j++)
{
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, dowait, &barrier);
if (err)
error (1, err, "pthread_create (%d)", i);
}
printf ("Manager will now call pthread_barrier_wait.\n");
havesyncs
= pthread_barrier_wait (&barrier) == PTHREAD_BARRIER_SERIAL_THREAD
? 1 : 0;
for (i = THREADS - 1; i >= 0; i--)
{
void *ret;
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
switch ((int) ret)
{
case 0:
break;
case PTHREAD_BARRIER_SERIAL_THREAD:
havesyncs++;
break;
default:
assert (!"Unknown value returned from pthread_barrier_wait.");
break;
}
}
printf ("\n");
assert (havesyncs == 1);
}
return 0;
}

89
htl/tests/test-7.c Normal file
View File

@ -0,0 +1,89 @@
/* Test Thread-Specific Data.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <stdio.h>
#include <error.h>
#include <errno.h>
#define THREADS 10
#define KEYS 400
pthread_key_t key[KEYS];
void *
thr (void *arg)
{
error_t err;
int i;
for (i = 0; i < KEYS; i++)
{
printf ("pthread_getspecific(%d).\n", key[i]);
assert (pthread_getspecific (key[i]) == NULL);
printf ("pthread_setspecific(%d, %d).\n", key[i], pthread_self ());
err = pthread_setspecific (key[i], (void *) pthread_self ());
printf ("pthread_setspecific(%d, %d) => %d.\n", key[i], pthread_self (),
err);
assert_perror (err);
}
return 0;
}
int
main (int argc, char **argv)
{
error_t err;
int i;
pthread_t tid[THREADS];
void des (void *val)
{
assert ((pthread_t) val == pthread_self ());
}
assert (pthread_getspecific ((pthread_key_t) 0) == NULL);
assert (pthread_setspecific ((pthread_key_t) 0, (void *) 0x1) == EINVAL);
for (i = 0; i < KEYS; i++)
err = pthread_key_create (&key[i], des);
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, thr, 0);
if (err)
error (1, err, "pthread_create (%d)", i);
}
for (i = 0; i < THREADS; i++)
{
void *ret;
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == 0);
}
return 0;
}

78
htl/tests/test-8.c Normal file
View File

@ -0,0 +1,78 @@
/* Test pthread_once.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#define THREADS 10
pthread_once_t inc_var_once = PTHREAD_ONCE_INIT;
int var;
void
inc_var (void)
{
var++;
}
void *
thr (void *arg)
{
int i;
for (i = 0; i < 500; i++)
pthread_once (&inc_var_once, inc_var);
return 0;
}
int
main (int argc, char **argv)
{
error_t err;
int i;
pthread_t tid[THREADS];
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, thr, 0);
if (err)
error (1, err, "pthread_create (%d)", i);
}
assert (thr (0) == 0);
for (i = 0; i < THREADS; i++)
{
void *ret;
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == 0);
}
assert (var == 1);
return 0;
}

104
htl/tests/test-9.c Normal file
View File

@ -0,0 +1,104 @@
/* Test recursive mutexes.
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/>. */
#define _GNU_SOURCE
#include <pthread.h>
#include <assert.h>
#include <error.h>
#include <errno.h>
#define THREADS 10
int foo;
void *
thr (void *arg)
{
int i;
pthread_mutex_lock (arg);
foo = pthread_self ();
for (i = 0; i < 500; i++)
pthread_mutex_lock (arg);
for (i = 0; i < 500; i++)
pthread_mutex_unlock (arg);
assert (foo == pthread_self ());
pthread_mutex_unlock (arg);
return 0;
}
int
main (int argc, char **argv)
{
error_t err;
int i;
pthread_t tid[THREADS];
pthread_mutexattr_t mattr;
pthread_mutex_t mutex;
err = pthread_mutexattr_init (&mattr);
if (err)
error (1, err, "pthread_mutexattr_init");
err = pthread_mutexattr_settype (&mattr, PTHREAD_MUTEX_RECURSIVE);
if (err)
error (1, err, "pthread_mutexattr_settype");
err = pthread_mutex_init (&mutex, &mattr);
if (err)
error (1, err, "pthread_mutex_init");
err = pthread_mutexattr_destroy (&mattr);
if (err)
error (1, err, "pthread_mutexattr_destroy");
pthread_mutex_lock (&mutex);
pthread_mutex_lock (&mutex);
pthread_mutex_unlock (&mutex);
pthread_mutex_unlock (&mutex);
for (i = 0; i < THREADS; i++)
{
err = pthread_create (&tid[i], 0, thr, &mutex);
if (err)
error (1, err, "pthread_create (%d)", i);
}
for (i = 0; i < THREADS; i++)
{
void *ret;
err = pthread_join (tid[i], &ret);
if (err)
error (1, err, "pthread_join");
assert (ret == 0);
}
err = pthread_mutex_destroy (&mutex);
if (err)
error (1, err, "pthread_mutex_destroy");
return 0;
}

View File

@ -0,0 +1,100 @@
/* Check that __pthread_destroy_specific works correctly if it has to skip
unused slots.
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/>. */
#define _GNU_SOURCE
#include <error.h>
#include <pthread.h>
#include <stdio.h>
#define N_k 42
static volatile int v;
static void
d (void *x)
{
int *i = (int *) x;
if (v != *i)
error (1, 0, "FAILED %d %d", v, *i);
v += 2;
printf ("%s %d\n", __FUNCTION__, *i);
fflush (stdout);
}
static void *
test (void *x)
{
pthread_key_t k[N_k];
static int k_v[N_k];
int err, i;
for (i = 0; i < N_k; i += 1)
{
err = pthread_key_create (&k[i], &d);
if (err != 0)
error (1, err, "pthread_key_create %d", i);
}
for (i = 0; i < N_k; i += 1)
{
k_v[i] = i;
err = pthread_setspecific (k[i], &k_v[i]);
if (err != 0)
error (1, err, "pthread_setspecific %d", i);
}
/* Delete every even key. */
for (i = 0; i < N_k; i += 2)
{
err = pthread_key_delete (k[i]);
if (err != 0)
error (1, err, "pthread_key_delete %d", i);
}
v = 1;
pthread_exit (NULL);
return NULL;
}
int
main (void)
{
pthread_t tid;
int err;
err = pthread_create (&tid, 0, test, NULL);
if (err != 0)
error (1, err, "pthread_create");
err = pthread_join (tid, NULL);
if (err)
error (1, err, "pthread_join");
if (v != N_k + 1)
error (1, 0, "FAILED END %d %d", v, N_k + 1);
return 0;
}

View File

@ -1 +1,2 @@
nptl
htl

View File

@ -1 +1,2 @@
nptl
htl

View File

@ -1 +1,2 @@
nptl
htl

1
sysdeps/htl/Implies Normal file
View File

@ -0,0 +1 @@
pthread

11
sysdeps/htl/Makeconfig Normal file
View File

@ -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

7
sysdeps/htl/Makefile Normal file
View File

@ -0,0 +1,7 @@
ifeq ($(subdir),rt)
librt-sysdep_routines += timer_routines
endif
ifeq ($(subdir),posix)
CFLAGS-confstr.c += -DLIBPTHREAD_VERSION='"HTL $(version)"'
endif

1
sysdeps/htl/Subdirs Normal file
View File

@ -0,0 +1 @@
htl

15
sysdeps/htl/Versions Normal file
View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

31
sysdeps/htl/flockfile.c Normal file
View File

@ -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)

29
sysdeps/htl/fork.h Normal file
View File

@ -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)

View File

@ -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)

32
sysdeps/htl/funlockfile.c Normal file
View File

@ -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)

180
sysdeps/htl/libc-lockP.h Normal file
View File

@ -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 */

View File

@ -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

33
sysdeps/htl/pt-atfork.c Normal file
View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

Some files were not shown because too many files have changed in this diff Show More