At initialization, override the pthread stub routines in libc
by filling in the jump table. Convert uses of pthread routines within libc_r to use the internal versions (_pthread_foo instead of pthread_foo). Remove a couple of globals from application namespace.
This commit is contained in:
parent
fb22a377c6
commit
f38fac1471
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=106867
@ -944,7 +944,7 @@ SCLASS struct pthread *_thread_initial
|
||||
#endif
|
||||
|
||||
/* Default thread attributes: */
|
||||
SCLASS struct pthread_attr pthread_attr_default
|
||||
SCLASS struct pthread_attr _pthread_attr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY,
|
||||
PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL,
|
||||
@ -954,20 +954,11 @@ SCLASS struct pthread_attr pthread_attr_default
|
||||
#endif
|
||||
|
||||
/* Default mutex attributes: */
|
||||
SCLASS struct pthread_mutex_attr pthread_mutexattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
#define PTHREAD_MUTEXATTR_DEFAULT \
|
||||
{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }
|
||||
|
||||
/* Default condition variable attributes: */
|
||||
SCLASS struct pthread_cond_attr pthread_condattr_default
|
||||
#ifdef GLOBAL_PTHREAD_PRIVATE
|
||||
= { COND_TYPE_FAST, 0 };
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
#define PTHREAD_CONDATTR_DEFAULT { COND_TYPE_FAST, 0 }
|
||||
|
||||
/*
|
||||
* Standard I/O file descriptors need special flag treatment since
|
||||
|
@ -51,7 +51,7 @@ _pthread_attr_init(pthread_attr_t *attr)
|
||||
ret = ENOMEM;
|
||||
else {
|
||||
/* Initialise the attribute object with the defaults: */
|
||||
memcpy(pattr, &pthread_attr_default, sizeof(struct pthread_attr));
|
||||
memcpy(pattr, &_pthread_attr_default, sizeof(*pattr));
|
||||
|
||||
/* Return a pointer to the attribute object: */
|
||||
*attr = pattr;
|
||||
|
@ -33,6 +33,9 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <pthread_private.h>
|
||||
|
||||
/*
|
||||
* This module uses GCC extentions to initialize the
|
||||
* threads package at program start-up time.
|
||||
|
@ -34,7 +34,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
/*
|
||||
@ -43,16 +45,30 @@
|
||||
static inline pthread_t cond_queue_deq(pthread_cond_t);
|
||||
static inline void cond_queue_remove(pthread_cond_t, pthread_t);
|
||||
static inline void cond_queue_enq(pthread_cond_t, pthread_t);
|
||||
int __pthread_cond_timedwait(pthread_cond_t *,
|
||||
pthread_mutex_t *, const struct timespec *);
|
||||
int __pthread_cond_wait(pthread_cond_t *,
|
||||
pthread_mutex_t *);
|
||||
|
||||
|
||||
/*
|
||||
* Double underscore versions are cancellation points. Single underscore
|
||||
* versions are not and are provided for libc internal usage (which
|
||||
* shouldn't introduce cancellation points).
|
||||
*/
|
||||
__weak_reference(__pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
|
||||
__weak_reference(_pthread_cond_init, pthread_cond_init);
|
||||
__weak_reference(_pthread_cond_destroy, pthread_cond_destroy);
|
||||
__weak_reference(_pthread_cond_wait, pthread_cond_wait);
|
||||
__weak_reference(_pthread_cond_timedwait, pthread_cond_timedwait);
|
||||
__weak_reference(_pthread_cond_signal, pthread_cond_signal);
|
||||
__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast);
|
||||
|
||||
|
||||
/* Reinitialize a condition variable to defaults. */
|
||||
/*
|
||||
* Reinitialize a private condition variable; this is only used for
|
||||
* internal condition variables. Currently, there is no difference.
|
||||
*/
|
||||
int
|
||||
_cond_reinit(pthread_cond_t *cond)
|
||||
{
|
||||
@ -61,7 +77,7 @@ _cond_reinit(pthread_cond_t *cond)
|
||||
if (cond == NULL)
|
||||
ret = EINVAL;
|
||||
else if (*cond == NULL)
|
||||
ret = pthread_cond_init(cond, NULL);
|
||||
ret = _pthread_cond_init(cond, NULL);
|
||||
else {
|
||||
/*
|
||||
* Initialize the condition variable structure:
|
||||
@ -172,8 +188,6 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
int interrupted = 0;
|
||||
int seqno;
|
||||
|
||||
_thread_enter_cancellation_point();
|
||||
|
||||
if (cond == NULL)
|
||||
return (EINVAL);
|
||||
|
||||
@ -182,7 +196,7 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
* perform the dynamic initialization:
|
||||
*/
|
||||
if (*cond == NULL &&
|
||||
(rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
(rval = _pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
|
||||
/*
|
||||
@ -316,15 +330,24 @@ _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
curthread->continuation((void *) curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thread_leave_cancellation_point();
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
const struct timespec * abstime)
|
||||
__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
int ret;
|
||||
|
||||
_thread_enter_cancellation_point();
|
||||
ret = _pthread_cond_wait(cond, mutex);
|
||||
_thread_leave_cancellation_point();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
int rval = 0;
|
||||
@ -332,8 +355,6 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
int interrupted = 0;
|
||||
int seqno;
|
||||
|
||||
_thread_enter_cancellation_point();
|
||||
|
||||
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
|
||||
abstime->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
@ -341,7 +362,7 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
if (*cond == NULL && (rval = pthread_cond_init(cond, NULL)) != 0)
|
||||
if (*cond == NULL && (rval = _pthread_cond_init(cond, NULL)) != 0)
|
||||
return (rval);
|
||||
|
||||
/*
|
||||
@ -487,14 +508,24 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
curthread->continuation((void *) curthread);
|
||||
} while ((done == 0) && (rval == 0));
|
||||
|
||||
_thread_leave_cancellation_point();
|
||||
|
||||
/* Return the completion status: */
|
||||
return (rval);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_signal(pthread_cond_t * cond)
|
||||
__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int ret;
|
||||
|
||||
_thread_enter_cancellation_point();
|
||||
ret = _pthread_cond_timedwait(cond, mutex, abstime);
|
||||
_thread_enter_cancellation_point();
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
int rval = 0;
|
||||
pthread_t pthread;
|
||||
@ -505,7 +536,8 @@ _pthread_cond_signal(pthread_cond_t * cond)
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
else if (*cond != NULL || (rval = pthread_cond_init(cond, NULL)) == 0) {
|
||||
else if (*cond != NULL ||
|
||||
(rval = _pthread_cond_init(cond, NULL)) == 0) {
|
||||
/*
|
||||
* Defer signals to protect the scheduling queues
|
||||
* from access by the signal handler:
|
||||
@ -556,7 +588,7 @@ _pthread_cond_signal(pthread_cond_t * cond)
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
_pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
int rval = 0;
|
||||
pthread_t pthread;
|
||||
@ -567,7 +599,8 @@ _pthread_cond_broadcast(pthread_cond_t * cond)
|
||||
* If the condition variable is statically initialized, perform dynamic
|
||||
* initialization.
|
||||
*/
|
||||
else if (*cond != NULL || (rval = pthread_cond_init(cond, NULL)) == 0) {
|
||||
else if (*cond != NULL ||
|
||||
(rval = _pthread_cond_init(cond, NULL)) == 0) {
|
||||
/*
|
||||
* Defer signals to protect the scheduling queues
|
||||
* from access by the signal handler:
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
__weak_reference(_pthread_condattr_init, pthread_condattr_init);
|
||||
|
||||
static struct pthread_cond_attr default_condattr = PTHREAD_CONDATTR_DEFAULT;
|
||||
|
||||
int
|
||||
_pthread_condattr_init(pthread_condattr_t *attr)
|
||||
{
|
||||
@ -46,11 +48,11 @@ _pthread_condattr_init(pthread_condattr_t *attr)
|
||||
pthread_condattr_t pattr;
|
||||
|
||||
if ((pattr = (pthread_condattr_t)
|
||||
malloc(sizeof(struct pthread_cond_attr))) == NULL) {
|
||||
malloc(sizeof(struct pthread_cond_attr))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
} else {
|
||||
memcpy(pattr, &pthread_condattr_default,
|
||||
sizeof(struct pthread_cond_attr));
|
||||
memcpy(pattr, &default_condattr,
|
||||
sizeof(struct pthread_cond_attr));
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
|
@ -39,7 +39,10 @@
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
#include <machine/reg.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "pthread_private.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
@ -88,7 +91,7 @@ _pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
/* Check if default thread attributes are required: */
|
||||
if (attr == NULL || *attr == NULL) {
|
||||
/* Use the default thread attributes: */
|
||||
pattr = &pthread_attr_default;
|
||||
pattr = &_pthread_attr_default;
|
||||
} else {
|
||||
pattr = *attr;
|
||||
}
|
||||
@ -244,8 +247,8 @@ _pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
* Start a garbage collector thread
|
||||
* if necessary.
|
||||
*/
|
||||
if (f_gc && pthread_create(&gc_thread,NULL,
|
||||
_thread_gc,NULL) != 0)
|
||||
if (f_gc && _pthread_create(&gc_thread, NULL,
|
||||
_thread_gc, NULL) != 0)
|
||||
PANIC("Can't create gc thread");
|
||||
|
||||
}
|
||||
@ -264,7 +267,7 @@ _thread_start(void)
|
||||
_thread_kern_in_sched = 0;
|
||||
|
||||
/* Run the current thread's start routine with argument: */
|
||||
pthread_exit(curthread->start_routine(curthread->arg));
|
||||
_pthread_exit(curthread->start_routine(curthread->arg));
|
||||
|
||||
/* This point should never be reached. */
|
||||
PANIC("Thread has resumed after exit");
|
||||
|
@ -37,12 +37,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
#define FLAGS_IN_SCHEDQ \
|
||||
(PTHREAD_FLAGS_IN_PRIOQ|PTHREAD_FLAGS_IN_WAITQ|PTHREAD_FLAGS_IN_WORKQ)
|
||||
|
||||
__weak_reference(_pthread_exit, pthread_exit);
|
||||
|
||||
void _exit(int status)
|
||||
@ -173,7 +172,7 @@ _pthread_exit(void *status)
|
||||
* Lock the garbage collector mutex to ensure that the garbage
|
||||
* collector is not using the dead thread list.
|
||||
*/
|
||||
if (pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
/* Add this thread to the list of dead threads. */
|
||||
@ -183,7 +182,7 @@ _pthread_exit(void *status)
|
||||
* Signal the garbage collector thread that there is something
|
||||
* to clean up.
|
||||
*/
|
||||
if (pthread_cond_signal(&_gc_cond) != 0)
|
||||
if (_pthread_cond_signal(&_gc_cond) != 0)
|
||||
PANIC("Cannot signal gc cond");
|
||||
|
||||
/*
|
||||
@ -194,7 +193,7 @@ _pthread_exit(void *status)
|
||||
_thread_kern_sig_defer();
|
||||
|
||||
/* Unlock the garbage collector mutex: */
|
||||
if (pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot unlock gc mutex");
|
||||
|
||||
/* Check if there is a thread joining this one: */
|
||||
|
@ -40,7 +40,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
pthread_addr_t
|
||||
@ -58,7 +60,7 @@ _thread_gc(pthread_addr_t arg)
|
||||
|
||||
/* Block all signals */
|
||||
sigfillset(&mask);
|
||||
pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
_pthread_sigmask(SIG_BLOCK, &mask, NULL);
|
||||
|
||||
/* Mark this thread as a library thread (not a user thread). */
|
||||
curthread->flags |= PTHREAD_FLAGS_PRIVATE;
|
||||
@ -104,7 +106,7 @@ _thread_gc(pthread_addr_t arg)
|
||||
* Lock the garbage collector mutex which ensures that
|
||||
* this thread sees another thread exit:
|
||||
*/
|
||||
if (pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
/*
|
||||
@ -187,13 +189,13 @@ _thread_gc(pthread_addr_t arg)
|
||||
* Wait for a signal from a dying thread or a
|
||||
* timeout (for a backup poll).
|
||||
*/
|
||||
if ((ret = pthread_cond_timedwait(&_gc_cond,
|
||||
if ((ret = _pthread_cond_timedwait(&_gc_cond,
|
||||
&_gc_mutex, &abstime)) != 0 && ret != ETIMEDOUT)
|
||||
PANIC("gc cannot wait for a signal");
|
||||
}
|
||||
|
||||
/* Unlock the garbage collector mutex: */
|
||||
if (pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot unlock gc mutex");
|
||||
|
||||
/*
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include <paths.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -65,11 +66,16 @@
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "libc_private.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
|
||||
int __pthread_mutex_lock(pthread_mutex_t *);
|
||||
int __pthread_mutex_trylock(pthread_mutex_t *);
|
||||
|
||||
/*
|
||||
* All weak references used within libc should be in this table.
|
||||
* This will is so that static libraries will work.
|
||||
* This allows static libraries to work.
|
||||
*/
|
||||
static void *references[] = {
|
||||
&_accept,
|
||||
@ -96,6 +102,10 @@ static void *references[] = {
|
||||
&_listen,
|
||||
&_nanosleep,
|
||||
&_open,
|
||||
&_pthread_cond_destroy,
|
||||
&_pthread_cond_init,
|
||||
&_pthread_cond_signal,
|
||||
&_pthread_cond_wait,
|
||||
&_pthread_getspecific,
|
||||
&_pthread_key_create,
|
||||
&_pthread_key_delete,
|
||||
@ -129,9 +139,9 @@ static void *references[] = {
|
||||
|
||||
/*
|
||||
* These are needed when linking statically. All references within
|
||||
* libgcc (and in the future libc) to these routines are weak, but
|
||||
* if they are not (strongly) referenced by the application or other
|
||||
* libraries, then the actual functions will not be loaded.
|
||||
* libgcc (and libc) to these routines are weak, but if they are not
|
||||
* (strongly) referenced by the application or other libraries, then
|
||||
* the actual functions will not be loaded.
|
||||
*/
|
||||
static void *libgcc_references[] = {
|
||||
&_pthread_once,
|
||||
@ -146,6 +156,43 @@ static void *libgcc_references[] = {
|
||||
&_pthread_mutex_unlock
|
||||
};
|
||||
|
||||
#define DUAL_ENTRY(entry) \
|
||||
(pthread_func_t)entry, (pthread_func_t)entry
|
||||
|
||||
static pthread_func_t jmp_table[][2] = {
|
||||
{DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */
|
||||
{DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */
|
||||
{DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */
|
||||
{DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */
|
||||
{(pthread_func_t)__pthread_cond_wait,
|
||||
(pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */
|
||||
{DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */
|
||||
{DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */
|
||||
{DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/
|
||||
{DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */
|
||||
{DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */
|
||||
{DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */
|
||||
{(pthread_func_t)__pthread_mutex_lock,
|
||||
(pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */
|
||||
{(pthread_func_t)__pthread_mutex_trylock,
|
||||
(pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */
|
||||
{DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */
|
||||
{DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */
|
||||
{DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */
|
||||
{DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */
|
||||
{DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */
|
||||
{DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */
|
||||
{DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */
|
||||
{DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */
|
||||
{DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */
|
||||
{DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */
|
||||
{DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */
|
||||
{DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */
|
||||
{DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */
|
||||
{DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */
|
||||
{DUAL_ENTRY(_pthread_sigmask)} /* PJT_SIGMASK */
|
||||
};
|
||||
|
||||
int _pthread_guard_default;
|
||||
int _pthread_page_size;
|
||||
|
||||
@ -165,18 +212,18 @@ _thread_init(void)
|
||||
struct clockinfo clockinfo;
|
||||
struct sigaction act;
|
||||
|
||||
_pthread_page_size = getpagesize();
|
||||
_pthread_guard_default = getpagesize();
|
||||
sched_stack_size = getpagesize();
|
||||
|
||||
pthread_attr_default.guardsize_attr = _pthread_guard_default;
|
||||
|
||||
|
||||
/* Check if this function has already been called: */
|
||||
if (_thread_initial)
|
||||
/* Only initialise the threaded application once. */
|
||||
return;
|
||||
|
||||
_pthread_page_size = getpagesize();;
|
||||
_pthread_guard_default = _pthread_page_size;
|
||||
sched_stack_size = _pthread_page_size;
|
||||
|
||||
_pthread_attr_default.guardsize_attr = _pthread_guard_default;
|
||||
|
||||
/*
|
||||
* Make gcc quiescent about {,libgcc_}references not being
|
||||
* referenced:
|
||||
@ -184,6 +231,14 @@ _thread_init(void)
|
||||
if ((references[0] == NULL) || (libgcc_references[0] == NULL))
|
||||
PANIC("Failed loading mandatory references in _thread_init");
|
||||
|
||||
/*
|
||||
* Check the size of the jump table to make sure it is preset
|
||||
* with the correct number of entries.
|
||||
*/
|
||||
if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
|
||||
PANIC("Thread jump table not properly initialized");
|
||||
memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));
|
||||
|
||||
/*
|
||||
* Check for the special case of this process running as
|
||||
* or in place of init as pid = 1:
|
||||
@ -288,7 +343,7 @@ _thread_init(void)
|
||||
_sched_switch_hook = NULL;
|
||||
|
||||
/* Give this thread default attributes: */
|
||||
memcpy((void *) &_thread_initial->attr, &pthread_attr_default,
|
||||
memcpy((void *) &_thread_initial->attr, &_pthread_attr_default,
|
||||
sizeof(struct pthread_attr));
|
||||
|
||||
/* Find the stack top */
|
||||
@ -480,10 +535,11 @@ _thread_init(void)
|
||||
|
||||
/* Initialise the garbage collector mutex and condition variable. */
|
||||
if (_pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
|
||||
pthread_cond_init(&_gc_cond,NULL) != 0)
|
||||
_pthread_cond_init(&_gc_cond,NULL) != 0)
|
||||
PANIC("Failed to initialise garbage collector mutex or condvar");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Special start up code for NetBSD/Alpha
|
||||
*/
|
||||
|
@ -32,7 +32,9 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
__weak_reference(_pthread_join, pthread_join);
|
||||
@ -64,7 +66,7 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
||||
* Lock the garbage collector mutex to ensure that the garbage
|
||||
* collector is not using the dead thread list.
|
||||
*/
|
||||
if (pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
/*
|
||||
@ -77,7 +79,7 @@ _pthread_join(pthread_t pthread, void **thread_return)
|
||||
* Unlock the garbage collector mutex, now that the garbage collector
|
||||
* can't be run:
|
||||
*/
|
||||
if (pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
/*
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
__weak_reference(_pthread_mutexattr_init, pthread_mutexattr_init);
|
||||
|
||||
static struct pthread_mutex_attr default_mutexattr = PTHREAD_MUTEXATTR_DEFAULT;
|
||||
|
||||
int
|
||||
_pthread_mutexattr_init(pthread_mutexattr_t *attr)
|
||||
{
|
||||
@ -49,10 +51,10 @@ _pthread_mutexattr_init(pthread_mutexattr_t *attr)
|
||||
malloc(sizeof(struct pthread_mutex_attr))) == NULL) {
|
||||
ret = ENOMEM;
|
||||
} else {
|
||||
memcpy(pattr, &pthread_mutexattr_default,
|
||||
sizeof(struct pthread_mutex_attr));
|
||||
memcpy(pattr, &default_mutexattr,
|
||||
sizeof(struct pthread_mutex_attr));
|
||||
*attr = pattr;
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -88,7 +88,9 @@ __weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy);
|
||||
__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock);
|
||||
|
||||
|
||||
/* Reinitialize a mutex to defaults. */
|
||||
/*
|
||||
* Reinitialize a private mutex; this is only used for internal mutexes.
|
||||
*/
|
||||
int
|
||||
_mutex_reinit(pthread_mutex_t * mutex)
|
||||
{
|
||||
@ -97,7 +99,7 @@ _mutex_reinit(pthread_mutex_t * mutex)
|
||||
if (mutex == NULL)
|
||||
ret = EINVAL;
|
||||
else if (*mutex == NULL)
|
||||
ret = pthread_mutex_init(mutex, NULL);
|
||||
ret = _pthread_mutex_init(mutex, NULL);
|
||||
else {
|
||||
/*
|
||||
* Initialize the mutex structure:
|
||||
@ -107,8 +109,7 @@ _mutex_reinit(pthread_mutex_t * mutex)
|
||||
TAILQ_INIT(&(*mutex)->m_queue);
|
||||
(*mutex)->m_owner = NULL;
|
||||
(*mutex)->m_data.m_count = 0;
|
||||
(*mutex)->m_flags &= MUTEX_FLAGS_PRIVATE;
|
||||
(*mutex)->m_flags |= MUTEX_FLAGS_INITED;
|
||||
(*mutex)->m_flags |= MUTEX_FLAGS_INITED | MUTEX_FLAGS_PRIVATE;
|
||||
(*mutex)->m_refcount = 0;
|
||||
(*mutex)->m_prio = 0;
|
||||
(*mutex)->m_saved_prio = 0;
|
||||
@ -133,7 +134,7 @@ _pthread_mutex_init(pthread_mutex_t * mutex,
|
||||
ret = EINVAL;
|
||||
|
||||
/* Check if default mutex attributes: */
|
||||
else if (mutex_attr == NULL || *mutex_attr == NULL) {
|
||||
if (mutex_attr == NULL || *mutex_attr == NULL) {
|
||||
/* Default to a (error checking) POSIX mutex: */
|
||||
type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
protocol = PTHREAD_PRIO_NONE;
|
||||
@ -213,7 +214,7 @@ _pthread_mutex_init(pthread_mutex_t * mutex,
|
||||
}
|
||||
}
|
||||
/* Return the completion status: */
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
@ -272,7 +273,7 @@ init_static(pthread_mutex_t *mutex)
|
||||
|
||||
_SPINUNLOCK(&static_init_lock);
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -289,7 +290,7 @@ init_static_private(pthread_mutex_t *mutex)
|
||||
|
||||
_SPINUNLOCK(&static_init_lock);
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -759,7 +760,7 @@ int
|
||||
_mutex_cv_lock(pthread_mutex_t * mutex)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = pthread_mutex_lock(mutex)) == 0)
|
||||
if ((ret = _pthread_mutex_lock(mutex)) == 0)
|
||||
(*mutex)->m_refcount--;
|
||||
return (ret);
|
||||
}
|
||||
@ -791,7 +792,7 @@ mutex_self_trylock(pthread_mutex_t mutex)
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -828,7 +829,7 @@ mutex_self_lock(pthread_mutex_t mutex)
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -1445,7 +1446,7 @@ _mutex_unlock_private(pthread_t pthread)
|
||||
for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) {
|
||||
m_next = TAILQ_NEXT(m, m_qe);
|
||||
if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
|
||||
pthread_mutex_unlock(&m);
|
||||
_pthread_mutex_unlock(&m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1502,7 +1503,7 @@ mutex_queue_deq(pthread_mutex_t mutex)
|
||||
break;
|
||||
}
|
||||
|
||||
return(pthread);
|
||||
return (pthread);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -34,7 +34,9 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling);
|
||||
@ -100,13 +102,13 @@ _pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
|
||||
ret = EINVAL;
|
||||
else {
|
||||
/* Lock the mutex: */
|
||||
if ((ret = pthread_mutex_lock(mutex)) == 0) {
|
||||
if ((ret = _pthread_mutex_lock(mutex)) == 0) {
|
||||
/* Return the old ceiling and set the new ceiling: */
|
||||
*old_ceiling = (*mutex)->m_prio;
|
||||
(*mutex)->m_prio = prioceiling;
|
||||
|
||||
/* Unlock the mutex: */
|
||||
ret = pthread_mutex_unlock(mutex);
|
||||
ret = _pthread_mutex_unlock(mutex);
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
|
@ -31,7 +31,9 @@
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
__weak_reference(_pthread_once, pthread_once);
|
||||
@ -42,12 +44,12 @@ _pthread_once(pthread_once_t * once_control, void (*init_routine) (void))
|
||||
if (once_control->state == PTHREAD_NEEDS_INIT) {
|
||||
if (_thread_initial == NULL)
|
||||
_thread_init();
|
||||
pthread_mutex_lock(&(once_control->mutex));
|
||||
_pthread_mutex_lock(&(once_control->mutex));
|
||||
if (once_control->state == PTHREAD_NEEDS_INIT) {
|
||||
init_routine();
|
||||
once_control->state = PTHREAD_DONE_INIT;
|
||||
}
|
||||
pthread_mutex_unlock(&(once_control->mutex));
|
||||
_pthread_mutex_unlock(&(once_control->mutex));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -40,8 +40,10 @@ __FBSDID("$FreeBSD$");
|
||||
extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask);
|
||||
|
||||
__weak_reference(_pselect, pselect);
|
||||
|
||||
int
|
||||
pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
|
||||
const struct timespec *timo, const sigset_t *mask)
|
||||
{
|
||||
int ret;
|
||||
|
@ -30,7 +30,10 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "pthread_private.h"
|
||||
|
||||
/* maximum number of times a read lock may be obtained */
|
||||
@ -56,7 +59,7 @@ init_static (pthread_rwlock_t *rwlock)
|
||||
_SPINLOCK(&static_init_lock);
|
||||
|
||||
if (*rwlock == NULL)
|
||||
ret = pthread_rwlock_init(rwlock, NULL);
|
||||
ret = _pthread_rwlock_init(rwlock, NULL);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
@ -77,9 +80,9 @@ _pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
|
||||
|
||||
prwlock = *rwlock;
|
||||
|
||||
pthread_mutex_destroy(&prwlock->lock);
|
||||
pthread_cond_destroy(&prwlock->read_signal);
|
||||
pthread_cond_destroy(&prwlock->write_signal);
|
||||
_pthread_mutex_destroy(&prwlock->lock);
|
||||
_pthread_cond_destroy(&prwlock->read_signal);
|
||||
_pthread_cond_destroy(&prwlock->write_signal);
|
||||
free(prwlock);
|
||||
|
||||
*rwlock = NULL;
|
||||
@ -103,22 +106,22 @@ _pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
|
||||
return(ENOMEM);
|
||||
|
||||
/* initialize the lock */
|
||||
if ((ret = pthread_mutex_init(&prwlock->lock, NULL)) != 0)
|
||||
if ((ret = _pthread_mutex_init(&prwlock->lock, NULL)) != 0)
|
||||
free(prwlock);
|
||||
else {
|
||||
/* initialize the read condition signal */
|
||||
ret = pthread_cond_init(&prwlock->read_signal, NULL);
|
||||
ret = _pthread_cond_init(&prwlock->read_signal, NULL);
|
||||
|
||||
if (ret != 0) {
|
||||
pthread_mutex_destroy(&prwlock->lock);
|
||||
_pthread_mutex_destroy(&prwlock->lock);
|
||||
free(prwlock);
|
||||
} else {
|
||||
/* initialize the write condition signal */
|
||||
ret = pthread_cond_init(&prwlock->write_signal, NULL);
|
||||
ret = _pthread_cond_init(&prwlock->write_signal, NULL);
|
||||
|
||||
if (ret != 0) {
|
||||
pthread_cond_destroy(&prwlock->read_signal);
|
||||
pthread_mutex_destroy(&prwlock->lock);
|
||||
_pthread_cond_destroy(&prwlock->read_signal);
|
||||
_pthread_mutex_destroy(&prwlock->lock);
|
||||
free(prwlock);
|
||||
} else {
|
||||
/* success */
|
||||
@ -153,16 +156,16 @@ _pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
|
||||
}
|
||||
|
||||
/* grab the monitor lock */
|
||||
if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
return(ret);
|
||||
|
||||
/* give writers priority over readers */
|
||||
while (prwlock->blocked_writers || prwlock->state < 0) {
|
||||
ret = pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
|
||||
ret = _pthread_cond_wait(&prwlock->read_signal, &prwlock->lock);
|
||||
|
||||
if (ret != 0) {
|
||||
/* can't do a whole lot if this fails */
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
@ -179,7 +182,7 @@ _pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
|
||||
* lock. Decrementing 'state' is no good because we probably
|
||||
* don't have the monitor lock.
|
||||
*/
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -204,7 +207,7 @@ _pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
|
||||
}
|
||||
|
||||
/* grab the monitor lock */
|
||||
if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
return(ret);
|
||||
|
||||
/* give writers priority over readers */
|
||||
@ -216,7 +219,7 @@ _pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
|
||||
++prwlock->state; /* indicate we are locked for reading */
|
||||
|
||||
/* see the comment on this in pthread_rwlock_rdlock */
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -241,7 +244,7 @@ _pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
|
||||
}
|
||||
|
||||
/* grab the monitor lock */
|
||||
if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
return(ret);
|
||||
|
||||
if (prwlock->state != 0)
|
||||
@ -251,7 +254,7 @@ _pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
|
||||
prwlock->state = -1;
|
||||
|
||||
/* see the comment on this in pthread_rwlock_rdlock */
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -271,24 +274,24 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
return(EINVAL);
|
||||
|
||||
/* grab the monitor lock */
|
||||
if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
return(ret);
|
||||
|
||||
if (prwlock->state > 0) {
|
||||
if (--prwlock->state == 0 && prwlock->blocked_writers)
|
||||
ret = pthread_cond_signal(&prwlock->write_signal);
|
||||
ret = _pthread_cond_signal(&prwlock->write_signal);
|
||||
} else if (prwlock->state < 0) {
|
||||
prwlock->state = 0;
|
||||
|
||||
if (prwlock->blocked_writers)
|
||||
ret = pthread_cond_signal(&prwlock->write_signal);
|
||||
ret = _pthread_cond_signal(&prwlock->write_signal);
|
||||
else
|
||||
ret = pthread_cond_broadcast(&prwlock->read_signal);
|
||||
ret = _pthread_cond_broadcast(&prwlock->read_signal);
|
||||
} else
|
||||
ret = EINVAL;
|
||||
|
||||
/* see the comment on this in pthread_rwlock_rdlock */
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -313,17 +316,17 @@ _pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
|
||||
}
|
||||
|
||||
/* grab the monitor lock */
|
||||
if ((ret = pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
|
||||
return(ret);
|
||||
|
||||
while (prwlock->state != 0) {
|
||||
++prwlock->blocked_writers;
|
||||
|
||||
ret = pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
|
||||
ret = _pthread_cond_wait(&prwlock->write_signal, &prwlock->lock);
|
||||
|
||||
if (ret != 0) {
|
||||
--prwlock->blocked_writers;
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@ -334,7 +337,7 @@ _pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
|
||||
prwlock->state = -1;
|
||||
|
||||
/* see the comment on this in pthread_rwlock_rdlock */
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
_pthread_mutex_unlock(&prwlock->lock);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
@ -32,7 +32,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <semaphore.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
#include "pthread_private.h"
|
||||
|
||||
#define _SEM_CHECK_VALIDITY(sem) \
|
||||
@ -88,15 +90,15 @@ _sem_init(sem_t *sem, int pshared, unsigned int value)
|
||||
/*
|
||||
* Initialize the semaphore.
|
||||
*/
|
||||
if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
|
||||
if (_pthread_mutex_init(&(*sem)->lock, NULL) != 0) {
|
||||
free(*sem);
|
||||
errno = ENOSPC;
|
||||
retval = -1;
|
||||
goto RETURN;
|
||||
}
|
||||
|
||||
if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
|
||||
pthread_mutex_destroy(&(*sem)->lock);
|
||||
if (_pthread_cond_init(&(*sem)->gtzero, NULL) != 0) {
|
||||
_pthread_mutex_destroy(&(*sem)->lock);
|
||||
free(*sem);
|
||||
errno = ENOSPC;
|
||||
retval = -1;
|
||||
@ -120,17 +122,17 @@ _sem_destroy(sem_t *sem)
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
/* Make sure there are no waiters. */
|
||||
pthread_mutex_lock(&(*sem)->lock);
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
if ((*sem)->nwaiters > 0) {
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
errno = EBUSY;
|
||||
retval = -1;
|
||||
goto RETURN;
|
||||
}
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
pthread_mutex_destroy(&(*sem)->lock);
|
||||
pthread_cond_destroy(&(*sem)->gtzero);
|
||||
_pthread_mutex_destroy(&(*sem)->lock);
|
||||
_pthread_cond_destroy(&(*sem)->gtzero);
|
||||
(*sem)->magic = 0;
|
||||
|
||||
free(*sem);
|
||||
@ -170,16 +172,16 @@ _sem_wait(sem_t *sem)
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
pthread_mutex_lock(&(*sem)->lock);
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
while ((*sem)->count == 0) {
|
||||
(*sem)->nwaiters++;
|
||||
pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
|
||||
_pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock);
|
||||
(*sem)->nwaiters--;
|
||||
}
|
||||
(*sem)->count--;
|
||||
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
@ -194,7 +196,7 @@ _sem_trywait(sem_t *sem)
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
pthread_mutex_lock(&(*sem)->lock);
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
if ((*sem)->count > 0) {
|
||||
(*sem)->count--;
|
||||
@ -204,7 +206,7 @@ _sem_trywait(sem_t *sem)
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
RETURN:
|
||||
return retval;
|
||||
@ -223,13 +225,13 @@ _sem_post(sem_t *sem)
|
||||
*/
|
||||
_thread_kern_sig_defer();
|
||||
|
||||
pthread_mutex_lock(&(*sem)->lock);
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
|
||||
(*sem)->count++;
|
||||
if ((*sem)->nwaiters > 0)
|
||||
pthread_cond_signal(&(*sem)->gtzero);
|
||||
_pthread_cond_signal(&(*sem)->gtzero);
|
||||
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
_thread_kern_sig_undefer();
|
||||
retval = 0;
|
||||
@ -244,9 +246,9 @@ _sem_getvalue(sem_t *sem, int *sval)
|
||||
|
||||
_SEM_CHECK_VALIDITY(sem);
|
||||
|
||||
pthread_mutex_lock(&(*sem)->lock);
|
||||
_pthread_mutex_lock(&(*sem)->lock);
|
||||
*sval = (int)(*sem)->count;
|
||||
pthread_mutex_unlock(&(*sem)->lock);
|
||||
_pthread_mutex_unlock(&(*sem)->lock);
|
||||
|
||||
retval = 0;
|
||||
RETURN:
|
||||
|
@ -35,10 +35,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include "pthread_private.h"
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/param.h>
|
||||
@ -33,6 +34,8 @@
|
||||
#include <sys/user.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "pthread_private.h"
|
||||
|
||||
/* Spare thread stack. */
|
||||
@ -144,7 +147,7 @@ _thread_stack_alloc(size_t stacksize, size_t guardsize)
|
||||
* Use the garbage collector mutex for synchronization of the
|
||||
* spare stack list.
|
||||
*/
|
||||
if (pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
if ((spare_stack = LIST_FIRST(&_dstackq)) != NULL) {
|
||||
@ -154,7 +157,7 @@ _thread_stack_alloc(size_t stacksize, size_t guardsize)
|
||||
}
|
||||
|
||||
/* Unlock the garbage collector mutex. */
|
||||
if (pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot unlock gc mutex");
|
||||
}
|
||||
/*
|
||||
@ -167,7 +170,7 @@ _thread_stack_alloc(size_t stacksize, size_t guardsize)
|
||||
* Use the garbage collector mutex for synchronization of the
|
||||
* spare stack list.
|
||||
*/
|
||||
if (pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_lock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot lock gc mutex");
|
||||
|
||||
LIST_FOREACH(spare_stack, &_mstackq, qe) {
|
||||
@ -180,7 +183,7 @@ _thread_stack_alloc(size_t stacksize, size_t guardsize)
|
||||
}
|
||||
|
||||
/* Unlock the garbage collector mutex. */
|
||||
if (pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
if (_pthread_mutex_unlock(&_gc_mutex) != 0)
|
||||
PANIC("Cannot unlock gc mutex");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user