diff options
Diffstat (limited to 'pthread')
-rw-r--r-- | pthread/cthreads-compat.c | 3 | ||||
-rw-r--r-- | pthread/pt-create.c | 8 | ||||
-rw-r--r-- | pthread/pt-exit.c | 6 | ||||
-rw-r--r-- | pthread/pt-initialize.c | 47 | ||||
-rw-r--r-- | pthread/pt-internal.h | 14 | ||||
-rw-r--r-- | pthread/pt-self.c | 4 | ||||
-rw-r--r-- | pthread/pt-setcancelstate.c | 4 | ||||
-rw-r--r-- | pthread/pt-setcanceltype.c | 4 | ||||
-rw-r--r-- | pthread/pthread-functions.h | 116 |
9 files changed, 194 insertions, 12 deletions
diff --git a/pthread/cthreads-compat.c b/pthread/cthreads-compat.c index e0536ef..cbe8170 100644 --- a/pthread/cthreads-compat.c +++ b/pthread/cthreads-compat.c @@ -100,5 +100,8 @@ __mutex_lock_solid (void *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); } diff --git a/pthread/pt-create.c b/pthread/pt-create.c index 346c697..4d81a95 100644 --- a/pthread/pt-create.c +++ b/pthread/pt-create.c @@ -22,7 +22,7 @@ #include <pthread.h> #include <signal.h> -#include <bits/atomic.h> +#include <bits/pt-atomic.h> #include <pt-internal.h> @@ -38,8 +38,12 @@ __atomic_t __pthread_total; /* The entry-point for new threads. */ static void -entry_point (void *(*start_routine)(void *), void *arg) +entry_point (struct __pthread *self, void *(*start_routine)(void *), void *arg) { +#ifdef ENABLE_TLS + ___pthread_self = self; +#endif + #ifdef HAVE_USELOCALE /* A fresh thread needs to be bound to the global locale. */ uselocale (LC_GLOBAL_LOCALE); diff --git a/pthread/pt-exit.c b/pthread/pt-exit.c index c01efda..c47b604 100644 --- a/pthread/pt-exit.c +++ b/pthread/pt-exit.c @@ -24,13 +24,13 @@ #include <pt-internal.h> -#include <bits/atomic.h> +#include <bits/pt-atomic.h> /* Terminate the current thread and make STATUS available to any thread that might join it. */ void -pthread_exit (void *status) +__pthread_exit (void *status) { struct __pthread *self = _pthread_self (); struct __pthread_cancelation_handler **handlers; @@ -120,3 +120,5 @@ pthread_exit (void *status) /* NOTREACHED */ abort (); } + +strong_alias (__pthread_exit, pthread_exit); diff --git a/pthread/pt-initialize.c b/pthread/pt-initialize.c index cf32b8b..831a63d 100644 --- a/pthread/pt-initialize.c +++ b/pthread/pt-initialize.c @@ -23,11 +23,56 @@ #include <pt-internal.h> #include <set-hooks.h> +#include <pthread.h> +#include <pthread-functions.h> + DEFINE_HOOK (__pthread_init, (void)); +#ifdef 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, + }; +#endif /* IS_IN_libpthread */ + /* Initialize the pthreads library. */ void -__pthread_initialize (void) +__pthread_init (void) { +#ifdef IS_IN_libpthread + __libc_pthread_init(&pthread_functions); +#endif RUN_HOOK (__pthread_init, ()); } diff --git a/pthread/pt-internal.h b/pthread/pt-internal.h index 3f69d2d..067fb73 100644 --- a/pthread/pt-internal.h +++ b/pthread/pt-internal.h @@ -26,7 +26,7 @@ #include <signal.h> #include <assert.h> -#include <bits/atomic.h> +#include <bits/pt-atomic.h> #include <pt-key.h> @@ -54,6 +54,7 @@ enum pthread_state # define PTHREAD_SYSDEP_MEMBERS #endif +#ifndef IS_IN_libpthread #ifdef ENABLE_TLS /* Type of the TCB. */ typedef struct @@ -63,6 +64,7 @@ typedef struct thread_t self; /* This thread's control port. */ } tcbhead_t; #endif /* ENABLE_TLS */ +#endif /* IS_IN_libpthread */ /* This structure describes a POSIX thread. */ struct __pthread @@ -82,6 +84,8 @@ struct __pthread size_t guardsize; /* Included in STACKSIZE (i.e. total stack memory is STACKSIZE, not STACKSIZE + GUARDSIZE). */ + /* FIXME: standard says that guardsize is in + addition to stacksize. */ int stack; /* Nonzero if the stack was allocated. */ /* Exit status. */ @@ -186,7 +190,7 @@ extern struct __pthread *_pthread_self (void); /* Initialize the pthreads library. */ -extern void __pthread_initialize (void); +extern void __pthread_init (void); /* Internal version of pthread_create. Rather than return the new tid, we return the whole __pthread structure in *PTHREAD. */ @@ -215,7 +219,8 @@ 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)(void *(*)(void *), + void (*entry_point)(struct __pthread *, + void *(*)(void *), void *), void *(*start_routine)(void *), void *__restrict arg); @@ -252,7 +257,8 @@ 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); + const struct timespec *__restrict abstime, + clockid_t clock_id); /* Wakeup THREAD. */ extern void __pthread_wakeup (struct __pthread *thread); diff --git a/pthread/pt-self.c b/pthread/pt-self.c index 4976864..deb57c0 100644 --- a/pthread/pt-self.c +++ b/pthread/pt-self.c @@ -23,10 +23,12 @@ /* Return the thread ID of the calling thread. */ pthread_t -pthread_self (void) +__pthread_self (void) { struct __pthread *self = _pthread_self (); assert (self); return self->thread; } + +strong_alias (__pthread_self, pthread_self); diff --git a/pthread/pt-setcancelstate.c b/pthread/pt-setcancelstate.c index e2d8183..38550ee 100644 --- a/pthread/pt-setcancelstate.c +++ b/pthread/pt-setcancelstate.c @@ -22,7 +22,7 @@ #include <pt-internal.h> int -pthread_setcancelstate (int state, int *oldstate) +__pthread_setcancelstate (int state, int *oldstate) { struct __pthread *p = _pthread_self (); @@ -41,3 +41,5 @@ pthread_setcancelstate (int state, int *oldstate) return 0; } + +strong_alias (__pthread_setcancelstate, pthread_setcancelstate); diff --git a/pthread/pt-setcanceltype.c b/pthread/pt-setcanceltype.c index 3ce4259..7226a3a 100644 --- a/pthread/pt-setcanceltype.c +++ b/pthread/pt-setcanceltype.c @@ -22,7 +22,7 @@ #include <pt-internal.h> int -pthread_setcanceltype (int type, int *oldtype) +__pthread_setcanceltype (int type, int *oldtype) { struct __pthread *p = _pthread_self (); @@ -41,3 +41,5 @@ pthread_setcanceltype (int type, int *oldtype) return 0; } + +strong_alias (__pthread_setcanceltype, pthread_setcanceltype); diff --git a/pthread/pthread-functions.h b/pthread/pthread-functions.h new file mode 100644 index 0000000..c0ba858 --- /dev/null +++ b/pthread/pthread-functions.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2003, 2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _PTHREAD_FUNCTIONS_H +#define _PTHREAD_FUNCTIONS_H 1 + +#include <pthread.h> + +int __pthread_attr_destroy (pthread_attr_t *); +int __pthread_attr_init (pthread_attr_t *); +int __pthread_attr_getdetachstate (const pthread_attr_t *, int *); +int __pthread_attr_setdetachstate (pthread_attr_t *, int); +int __pthread_attr_getinheritsched (const pthread_attr_t *, int *); +int __pthread_attr_setinheritsched (pthread_attr_t *, int); +int __pthread_attr_getschedparam (const pthread_attr_t *, + struct sched_param *); +int __pthread_attr_setschedparam (pthread_attr_t *, + const struct sched_param *); +int __pthread_attr_getschedpolicy (const pthread_attr_t *, int *); +int __pthread_attr_setschedpolicy (pthread_attr_t *, int); +int __pthread_attr_getscope (const pthread_attr_t *, int *); +int __pthread_attr_setscope (pthread_attr_t *, int); +int __pthread_condattr_destroy (pthread_condattr_t *); +int __pthread_condattr_init (pthread_condattr_t *); +int __pthread_cond_broadcast (pthread_cond_t *); +int __pthread_cond_destroy (pthread_cond_t *); +int __pthread_cond_init (pthread_cond_t *, + const pthread_condattr_t *); +int __pthread_cond_signal (pthread_cond_t *); +int __pthread_cond_wait (pthread_cond_t *, pthread_mutex_t *); +int __pthread_cond_timedwait (pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); +int __pthread_equal (pthread_t, pthread_t); +void __pthread_exit (void *); +int __pthread_getschedparam (pthread_t, int *, struct sched_param *); +int __pthread_setschedparam (pthread_t, int, + const struct sched_param *); +int _pthread_mutex_destroy (pthread_mutex_t *); +int _pthread_mutex_init (pthread_mutex_t *, + const pthread_mutexattr_t *); +int __pthread_mutex_lock (pthread_mutex_t *); +int __pthread_mutex_trylock (pthread_mutex_t *); +int __pthread_mutex_unlock (pthread_mutex_t *); +pthread_t __pthread_self (void); +int __pthread_setcancelstate (int, int *); +int __pthread_setcanceltype (int, int *); +struct __pthread_cancelation_handler **__pthread_get_cleanup_stack (void); + +/* Data type shared with libc. The libc uses it to pass on calls to + the thread functions. Wine pokes directly into this structure, + so if possible avoid breaking it and append new hooks to the end. */ +struct pthread_functions +{ + int (*ptr_pthread_attr_destroy) (pthread_attr_t *); + int (*ptr_pthread_attr_init) (pthread_attr_t *); + int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *, + struct sched_param *); + int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *, + const struct sched_param *); + int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int); + int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *); + int (*ptr_pthread_condattr_init) (pthread_condattr_t *); + int (*ptr_pthread_cond_broadcast) (pthread_cond_t *); + int (*ptr_pthread_cond_destroy) (pthread_cond_t *); + int (*ptr_pthread_cond_init) (pthread_cond_t *, + const pthread_condattr_t *); + int (*ptr_pthread_cond_signal) (pthread_cond_t *); + int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *); + int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *, + const struct timespec *); + int (*ptr_pthread_equal) (pthread_t, pthread_t); + void (*ptr_pthread_exit) (void *); + int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *); + int (*ptr_pthread_setschedparam) (pthread_t, int, + const struct sched_param *); + int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *); + int (*ptr_pthread_mutex_init) (pthread_mutex_t *, + const pthread_mutexattr_t *); + int (*ptr_pthread_mutex_lock) (pthread_mutex_t *); + int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *); + int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *); + pthread_t (*ptr_pthread_self) (void); + int (*ptr_pthread_setcancelstate) (int, int *); + int (*ptr_pthread_setcanceltype) (int, int *); + struct __pthread_cancelation_handler **(*ptr___pthread_get_cleanup_stack) (void); +}; + +/* Variable in libc.so. */ +extern struct pthread_functions __libc_pthread_functions attribute_hidden; + +void __libc_pthread_init (const struct pthread_functions *functions); + +#endif /* pthread-functions.h */ |