summaryrefslogtreecommitdiff
path: root/pthread
diff options
context:
space:
mode:
Diffstat (limited to 'pthread')
-rw-r--r--pthread/cthreads-compat.c3
-rw-r--r--pthread/pt-create.c8
-rw-r--r--pthread/pt-exit.c6
-rw-r--r--pthread/pt-initialize.c47
-rw-r--r--pthread/pt-internal.h14
-rw-r--r--pthread/pt-self.c4
-rw-r--r--pthread/pt-setcancelstate.c4
-rw-r--r--pthread/pt-setcanceltype.c4
-rw-r--r--pthread/pthread-functions.h116
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 */