mirror of
https://github.com/fluencelabs/musl
synced 2025-06-29 06:32:16 +00:00
reorganize pthread data structures and move the definitions to alltypes.h
this allows sys/types.h to provide the pthread types, as required by POSIX. this design also facilitates forcing ABI-compatible sizes in the arch-specific alltypes.h, while eliminating the need for developers changing the internals of the pthread types to poke around with arch-specific headers they may not be able to test.
This commit is contained in:
@ -78,7 +78,22 @@ TYPEDEF int id_t;
|
|||||||
TYPEDEF int uid_t;
|
TYPEDEF int uid_t;
|
||||||
TYPEDEF int gid_t;
|
TYPEDEF int gid_t;
|
||||||
TYPEDEF int key_t;
|
TYPEDEF int key_t;
|
||||||
|
|
||||||
TYPEDEF struct __pthread * pthread_t;
|
TYPEDEF struct __pthread * pthread_t;
|
||||||
|
TYPEDEF int pthread_once_t;
|
||||||
|
TYPEDEF int pthread_key_t;
|
||||||
|
TYPEDEF int pthread_spinlock_t;
|
||||||
|
|
||||||
|
TYPEDEF struct { union { int __i[9]; size_t __s[2]; } __u; } pthread_attr_t;
|
||||||
|
TYPEDEF unsigned pthread_mutexattr_t;
|
||||||
|
TYPEDEF unsigned pthread_condattr_t;
|
||||||
|
TYPEDEF unsigned pthread_barrierattr_t;
|
||||||
|
TYPEDEF struct { unsigned __attr[2]; } pthread_rwlockattr_t;
|
||||||
|
|
||||||
|
TYPEDEF struct { union { int __i[6]; void *__p[1]; } __u; } pthread_mutex_t;
|
||||||
|
TYPEDEF struct { union { int __i[12]; void *__p[1]; } __u; } pthread_cond_t;
|
||||||
|
TYPEDEF struct { union { int __i[8]; void *__p[1]; } __u; } pthread_rwlock_t;
|
||||||
|
TYPEDEF struct { union { int __i[5]; void *__p[1]; } __u; } pthread_barrier_t;
|
||||||
|
|
||||||
TYPEDEF long long off_t;
|
TYPEDEF long long off_t;
|
||||||
|
|
||||||
|
@ -78,7 +78,22 @@ TYPEDEF int id_t;
|
|||||||
TYPEDEF unsigned int uid_t;
|
TYPEDEF unsigned int uid_t;
|
||||||
TYPEDEF unsigned int gid_t;
|
TYPEDEF unsigned int gid_t;
|
||||||
TYPEDEF int key_t;
|
TYPEDEF int key_t;
|
||||||
|
|
||||||
TYPEDEF struct __pthread * pthread_t;
|
TYPEDEF struct __pthread * pthread_t;
|
||||||
|
TYPEDEF int pthread_once_t;
|
||||||
|
TYPEDEF int pthread_key_t;
|
||||||
|
TYPEDEF int pthread_spinlock_t;
|
||||||
|
|
||||||
|
TYPEDEF struct { union { int __i[14]; size_t __s[2]; } __u; } pthread_attr_t;
|
||||||
|
TYPEDEF unsigned pthread_mutexattr_t;
|
||||||
|
TYPEDEF unsigned pthread_condattr_t;
|
||||||
|
TYPEDEF unsigned pthread_barrierattr_t;
|
||||||
|
TYPEDEF struct { unsigned __attr[2]; } pthread_rwlockattr_t;
|
||||||
|
|
||||||
|
TYPEDEF struct { union { int __i[10]; void *__p[1]; } __u; } pthread_mutex_t;
|
||||||
|
TYPEDEF struct { union { int __i[12]; void *__p[1]; } __u; } pthread_cond_t;
|
||||||
|
TYPEDEF struct { union { int __i[14]; void *__p[1]; } __u; } pthread_rwlock_t;
|
||||||
|
TYPEDEF struct { union { int __i[8]; void *__p[1]; } __u; } pthread_barrier_t;
|
||||||
|
|
||||||
TYPEDEF long off_t;
|
TYPEDEF long off_t;
|
||||||
|
|
||||||
|
@ -8,6 +8,18 @@ extern "C" {
|
|||||||
#define __NEED_struct_timespec
|
#define __NEED_struct_timespec
|
||||||
#define __NEED_sigset_t
|
#define __NEED_sigset_t
|
||||||
#define __NEED_pthread_t
|
#define __NEED_pthread_t
|
||||||
|
#define __NEED_pthread_attr_t
|
||||||
|
#define __NEED_pthread_mutexattr_t
|
||||||
|
#define __NEED_pthread_condattr_t
|
||||||
|
#define __NEED_pthread_rwlockattr_t
|
||||||
|
#define __NEED_pthread_barrierattr_t
|
||||||
|
#define __NEED_pthread_mutex_t
|
||||||
|
#define __NEED_pthread_cond_t
|
||||||
|
#define __NEED_pthread_rwlock_t
|
||||||
|
#define __NEED_pthread_barrier_t
|
||||||
|
#define __NEED_pthread_spinlock_t
|
||||||
|
#define __NEED_pthread_key_t
|
||||||
|
#define __NEED_pthread_once_t
|
||||||
#define __NEED_size_t
|
#define __NEED_size_t
|
||||||
|
|
||||||
#include <bits/alltypes.h>
|
#include <bits/alltypes.h>
|
||||||
@ -15,51 +27,6 @@ extern "C" {
|
|||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
typedef int pthread_once_t, pthread_key_t, pthread_spinlock_t;
|
|
||||||
typedef int pthread_mutexattr_t, pthread_condattr_t, pthread_barrierattr_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t __guardsize;
|
|
||||||
size_t __stacksize;
|
|
||||||
unsigned __detach : 1;
|
|
||||||
unsigned __pad : 31;
|
|
||||||
int __attr[6];
|
|
||||||
} pthread_attr_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int __attr[2];
|
|
||||||
} pthread_rwlockattr_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int __type;
|
|
||||||
int __lock;
|
|
||||||
pthread_t __owner;
|
|
||||||
int __pad2;
|
|
||||||
int __waiters;
|
|
||||||
int __pad;
|
|
||||||
} pthread_mutex_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int __block;
|
|
||||||
int __pad[11];
|
|
||||||
} pthread_cond_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int __wrlock;
|
|
||||||
int __readers;
|
|
||||||
int __waiters;
|
|
||||||
int __owner;
|
|
||||||
int __pad[4];
|
|
||||||
} pthread_rwlock_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int __count;
|
|
||||||
int __limit;
|
|
||||||
int __left;
|
|
||||||
int __waiters;
|
|
||||||
int __barrier[1];
|
|
||||||
} pthread_barrier_t;
|
|
||||||
|
|
||||||
#define PTHREAD_CREATE_JOINABLE 0
|
#define PTHREAD_CREATE_JOINABLE 0
|
||||||
#define PTHREAD_CREATE_DETACHED 1
|
#define PTHREAD_CREATE_DETACHED 1
|
||||||
|
|
||||||
|
@ -42,6 +42,20 @@ extern "C" {
|
|||||||
#define __NEED_suseconds_t
|
#define __NEED_suseconds_t
|
||||||
#define __NEED_blksize_t
|
#define __NEED_blksize_t
|
||||||
|
|
||||||
|
#define __NEED_pthread_t
|
||||||
|
#define __NEED_pthread_attr_t
|
||||||
|
#define __NEED_pthread_mutexattr_t
|
||||||
|
#define __NEED_pthread_condattr_t
|
||||||
|
#define __NEED_pthread_rwlockattr_t
|
||||||
|
#define __NEED_pthread_barrierattr_t
|
||||||
|
#define __NEED_pthread_mutex_t
|
||||||
|
#define __NEED_pthread_cond_t
|
||||||
|
#define __NEED_pthread_rwlock_t
|
||||||
|
#define __NEED_pthread_barrier_t
|
||||||
|
#define __NEED_pthread_spinlock_t
|
||||||
|
#define __NEED_pthread_key_t
|
||||||
|
#define __NEED_pthread_once_t
|
||||||
|
|
||||||
#include <bits/alltypes.h>
|
#include <bits/alltypes.h>
|
||||||
|
|
||||||
#ifdef _GNU_SOURCE
|
#ifdef _GNU_SOURCE
|
||||||
|
@ -38,6 +38,25 @@ struct pthread {
|
|||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define __SU (sizeof(size_t)/sizeof(int))
|
||||||
|
|
||||||
|
#define _a_stacksize __u.__s[0]
|
||||||
|
#define _a_guardsize __u.__s[1]
|
||||||
|
#define _a_detach __u.__i[2*__SU+0]
|
||||||
|
#define _m_type __u.__i[0]
|
||||||
|
#define _m_lock __u.__i[1]
|
||||||
|
#define _m_waiters __u.__i[2]
|
||||||
|
#define _m_owner __u.__i[3]
|
||||||
|
#define _c_block __u.__i[0]
|
||||||
|
#define _rw_wrlock __u.__i[0]
|
||||||
|
#define _rw_readers __u.__i[1]
|
||||||
|
#define _rw_waiters __u.__i[2]
|
||||||
|
#define _rw_owner __u.__i[3]
|
||||||
|
#define _b_count __u.__i[0]
|
||||||
|
#define _b_limit __u.__i[1]
|
||||||
|
#define _b_left __u.__i[2]
|
||||||
|
#define _b_waiters __u.__i[3]
|
||||||
|
|
||||||
#include "pthread_arch.h"
|
#include "pthread_arch.h"
|
||||||
|
|
||||||
#define SIGCANCEL 32
|
#define SIGCANCEL 32
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
int pthread_attr_getdetachstate(pthread_attr_t *a, int *state)
|
int pthread_attr_getdetachstate(pthread_attr_t *a, int *state)
|
||||||
{
|
{
|
||||||
*state = a->__detach;
|
*state = a->_a_detach;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
int pthread_attr_getguardsize(pthread_attr_t *a, size_t *size)
|
int pthread_attr_getguardsize(pthread_attr_t *a, size_t *size)
|
||||||
{
|
{
|
||||||
*size = a->__guardsize + DEFAULT_GUARD_SIZE;
|
*size = a->_a_guardsize + DEFAULT_GUARD_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
int pthread_attr_getstacksize(pthread_attr_t *a, size_t *size)
|
int pthread_attr_getstacksize(pthread_attr_t *a, size_t *size)
|
||||||
{
|
{
|
||||||
*size = a->__stacksize + DEFAULT_STACK_SIZE;
|
*size = a->_a_stacksize + DEFAULT_STACK_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
|
int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
|
||||||
{
|
{
|
||||||
a->__detach = state;
|
a->_a_detach = state;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
|
int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
|
||||||
{
|
{
|
||||||
if (size > SIZE_MAX/8) return EINVAL;
|
if (size > SIZE_MAX/8) return EINVAL;
|
||||||
a->__guardsize = size - DEFAULT_GUARD_SIZE;
|
a->_a_guardsize = size - DEFAULT_GUARD_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
|
int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
|
||||||
{
|
{
|
||||||
if (size-PAGE_SIZE > SIZE_MAX/4) return EINVAL;
|
if (size-PAGE_SIZE > SIZE_MAX/4) return EINVAL;
|
||||||
a->__stacksize = size - DEFAULT_STACK_SIZE;
|
a->_a_stacksize = size - DEFAULT_STACK_SIZE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
int pthread_barrier_init(pthread_barrier_t *b, const pthread_barrierattr_t *a, unsigned count)
|
int pthread_barrier_init(pthread_barrier_t *b, const pthread_barrierattr_t *a, unsigned count)
|
||||||
{
|
{
|
||||||
if (!count) return EINVAL;
|
if (!count) return EINVAL;
|
||||||
*b = (pthread_barrier_t){ .__limit = count-1 };
|
*b = (pthread_barrier_t){ ._b_limit = count-1 };
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,27 +5,27 @@ int pthread_barrier_wait(pthread_barrier_t *b)
|
|||||||
int cur;
|
int cur;
|
||||||
|
|
||||||
/* Trivial case: count was set at 1 */
|
/* Trivial case: count was set at 1 */
|
||||||
if (!b->__limit) return PTHREAD_BARRIER_SERIAL_THREAD;
|
if (!b->_b_limit) return PTHREAD_BARRIER_SERIAL_THREAD;
|
||||||
|
|
||||||
/* Wait for anyone still suspended at previous use of barrier */
|
/* Wait for anyone still suspended at previous use of barrier */
|
||||||
while ((cur=b->__left))
|
while ((cur=b->_b_left))
|
||||||
__wait(&b->__left, &b->__waiters, cur, 0);
|
__wait(&b->_b_left, &b->_b_waiters, cur, 0);
|
||||||
|
|
||||||
/* If we are the last to reach barrier, reset it and wake others */
|
/* If we are the last to reach barrier, reset it and wake others */
|
||||||
if (a_fetch_add(&b->__count, 1) == b->__limit) {
|
if (a_fetch_add(&b->_b_count, 1) == b->_b_limit) {
|
||||||
b->__left = b->__limit;
|
b->_b_left = b->_b_limit;
|
||||||
b->__count = 0;
|
b->_b_count = 0;
|
||||||
__wake(&b->__count, -1, 0);
|
__wake(&b->_b_count, -1, 0);
|
||||||
return PTHREAD_BARRIER_SERIAL_THREAD;
|
return PTHREAD_BARRIER_SERIAL_THREAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for our peers to reach the barrier */
|
/* Wait for our peers to reach the barrier */
|
||||||
while ((cur=b->__count))
|
while ((cur=b->_b_count))
|
||||||
__wait(&b->__count, 0, cur, 0);
|
__wait(&b->_b_count, 0, cur, 0);
|
||||||
|
|
||||||
/* If we're the last to wake up and barrier is awaiting reuse */
|
/* If we're the last to wake up and barrier is awaiting reuse */
|
||||||
if (a_fetch_add(&b->__left, -1) == 1 && b->__waiters)
|
if (a_fetch_add(&b->_b_left, -1) == 1 && b->_b_waiters)
|
||||||
__wake(&b->__left, -1, 0);
|
__wake(&b->_b_left, -1, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
int pthread_cond_broadcast(pthread_cond_t *c)
|
int pthread_cond_broadcast(pthread_cond_t *c)
|
||||||
{
|
{
|
||||||
c->__block = 0;
|
c->_c_block = 0;
|
||||||
__wake(&c->__block, -1, 0);
|
__wake(&c->_c_block, -1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
int pthread_cond_signal(pthread_cond_t *c)
|
int pthread_cond_signal(pthread_cond_t *c)
|
||||||
{
|
{
|
||||||
c->__block = 0;
|
c->_c_block = 0;
|
||||||
__wake(&c->__block, 1, 0);
|
__wake(&c->_c_block, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, const struct t
|
|||||||
CANCELPT(0);
|
CANCELPT(0);
|
||||||
|
|
||||||
pthread_cleanup_push(relock, m);
|
pthread_cleanup_push(relock, m);
|
||||||
c->__block = 1;
|
c->_c_block = 1;
|
||||||
if ((r=pthread_mutex_unlock(m))) return r;
|
if ((r=pthread_mutex_unlock(m))) return r;
|
||||||
|
|
||||||
CANCELPT(1);
|
CANCELPT(1);
|
||||||
e = __timedwait(&c->__block, 1, CLOCK_REALTIME, ts, 0);
|
e = __timedwait(&c->_c_block, 1, CLOCK_REALTIME, ts, 0);
|
||||||
CANCELPT(0);
|
CANCELPT(0);
|
||||||
|
|
||||||
pthread_cleanup_pop(0);
|
pthread_cleanup_pop(0);
|
||||||
|
@ -173,8 +173,8 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo
|
|||||||
if (!init && ++init) init_threads();
|
if (!init && ++init) init_threads();
|
||||||
|
|
||||||
if (!attr) attr = &default_attr;
|
if (!attr) attr = &default_attr;
|
||||||
guard = ROUND(attr->__guardsize + DEFAULT_GUARD_SIZE);
|
guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE);
|
||||||
size = guard + ROUND(attr->__stacksize + DEFAULT_STACK_SIZE);
|
size = guard + ROUND(attr->_a_stacksize + DEFAULT_STACK_SIZE);
|
||||||
size += __pthread_tsd_size;
|
size += __pthread_tsd_size;
|
||||||
map = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
|
map = mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0);
|
||||||
if (!map) return EAGAIN;
|
if (!map) return EAGAIN;
|
||||||
@ -190,7 +190,7 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo
|
|||||||
new->start_arg = arg;
|
new->start_arg = arg;
|
||||||
new->self = new;
|
new->self = new;
|
||||||
new->tsd = (void *)tsd;
|
new->tsd = (void *)tsd;
|
||||||
new->detached = attr->__detach;
|
new->detached = attr->_a_detach;
|
||||||
new->attr = *attr;
|
new->attr = *attr;
|
||||||
memcpy(new->tlsdesc, self->tlsdesc, sizeof new->tlsdesc);
|
memcpy(new->tlsdesc, self->tlsdesc, sizeof new->tlsdesc);
|
||||||
new->tlsdesc[1] = (uintptr_t)new;
|
new->tlsdesc[1] = (uintptr_t)new;
|
||||||
|
@ -4,6 +4,6 @@ int pthread_mutex_lock(pthread_mutex_t *m)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
while ((r=pthread_mutex_trylock(m)) == EBUSY)
|
while ((r=pthread_mutex_trylock(m)) == EBUSY)
|
||||||
__wait(&m->__lock, &m->__waiters, 1, 0);
|
__wait(&m->_m_lock, &m->_m_waiters, 1, 0);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *at)
|
|||||||
{
|
{
|
||||||
int r, w=0;
|
int r, w=0;
|
||||||
while ((r=pthread_mutex_trylock(m)) == EBUSY) {
|
while ((r=pthread_mutex_trylock(m)) == EBUSY) {
|
||||||
if (!w) a_inc(&m->__waiters), w++;
|
if (!w) a_inc(&m->_m_waiters), w++;
|
||||||
if (__timedwait(&m->__lock, 1, CLOCK_REALTIME, at, 0) == ETIMEDOUT) {
|
if (__timedwait(&m->_m_lock, 1, CLOCK_REALTIME, at, 0) == ETIMEDOUT) {
|
||||||
if (w) a_dec(&m->__waiters);
|
if (w) a_dec(&m->_m_waiters);
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w) a_dec(&m->__waiters);
|
if (w) a_dec(&m->_m_waiters);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -2,27 +2,27 @@
|
|||||||
|
|
||||||
int pthread_mutex_trylock(pthread_mutex_t *m)
|
int pthread_mutex_trylock(pthread_mutex_t *m)
|
||||||
{
|
{
|
||||||
if (m->__type == PTHREAD_MUTEX_RECURSIVE) {
|
if (m->_m_type == PTHREAD_MUTEX_RECURSIVE) {
|
||||||
pthread_t self = pthread_self();
|
pthread_t self = pthread_self();
|
||||||
if (m->__owner == self) {
|
if (m->_m_owner == self->tid) {
|
||||||
if ((unsigned)m->__lock >= INT_MAX) return EAGAIN;
|
if ((unsigned)m->_m_lock >= INT_MAX) return EAGAIN;
|
||||||
a_inc(&m->__lock);
|
a_inc(&m->_m_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (a_fetch_add(&m->__lock, 1)) {
|
if (a_fetch_add(&m->_m_lock, 1)) {
|
||||||
if (a_fetch_add(&m->__lock, -1)==1 && m->__waiters)
|
if (a_fetch_add(&m->_m_lock, -1)==1 && m->_m_waiters)
|
||||||
__wake(&m->__lock, 1, 0);
|
__wake(&m->_m_lock, 1, 0);
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
}
|
}
|
||||||
m->__owner = self;
|
m->_m_owner = self->tid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_xchg(&m->__lock, 1))
|
if (a_xchg(&m->_m_lock, 1))
|
||||||
if (m->__type == PTHREAD_MUTEX_ERRORCHECK
|
if (m->_m_type == PTHREAD_MUTEX_ERRORCHECK
|
||||||
&& m->__owner == pthread_self()) return EDEADLK;
|
&& m->_m_owner == pthread_self()->tid) return EDEADLK;
|
||||||
else return EBUSY;
|
else return EBUSY;
|
||||||
if (m->__type == PTHREAD_MUTEX_ERRORCHECK)
|
if (m->_m_type == PTHREAD_MUTEX_ERRORCHECK)
|
||||||
m->__owner = pthread_self();
|
m->_m_owner = pthread_self()->tid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
|
|
||||||
int pthread_mutex_unlock(pthread_mutex_t *m)
|
int pthread_mutex_unlock(pthread_mutex_t *m)
|
||||||
{
|
{
|
||||||
if (m->__type == PTHREAD_MUTEX_RECURSIVE) {
|
if (m->_m_type == PTHREAD_MUTEX_RECURSIVE) {
|
||||||
if (a_fetch_add(&m->__lock, -1)==1 && m->__waiters)
|
if (a_fetch_add(&m->_m_lock, -1)==1 && m->_m_waiters)
|
||||||
__wake(&m->__lock, 1, 0);
|
__wake(&m->_m_lock, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->__type == PTHREAD_MUTEX_ERRORCHECK
|
if (m->_m_type == PTHREAD_MUTEX_ERRORCHECK
|
||||||
&& m->__owner != pthread_self())
|
&& m->_m_owner != pthread_self()->tid)
|
||||||
return EPERM;
|
return EPERM;
|
||||||
|
|
||||||
m->__owner = 0;
|
m->_m_owner = 0;
|
||||||
m->__lock = 0;
|
m->_m_lock = 0;
|
||||||
if (m->__waiters) __wake(&m->__lock, 1, 0);
|
if (m->_m_waiters) __wake(&m->_m_lock, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
|
int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
while (pthread_rwlock_tryrdlock(rw))
|
while (pthread_rwlock_tryrdlock(rw))
|
||||||
__wait(&rw->__wrlock, &rw->__waiters, 1, 0);
|
__wait(&rw->_rw_wrlock, &rw->_rw_waiters, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@ int pthread_rwlock_timedrdlock(pthread_rwlock_t *rw, const struct timespec *at)
|
|||||||
{
|
{
|
||||||
int w=0;
|
int w=0;
|
||||||
while (pthread_rwlock_tryrdlock(rw)) {
|
while (pthread_rwlock_tryrdlock(rw)) {
|
||||||
if (!w) a_inc(&rw->__waiters), w++;
|
if (!w) a_inc(&rw->_rw_waiters), w++;
|
||||||
if (__timedwait(&rw->__wrlock, 1, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
|
if (__timedwait(&rw->_rw_wrlock, 1, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
|
||||||
if (w) a_dec(&rw->__waiters);
|
if (w) a_dec(&rw->_rw_waiters);
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w) a_dec(&rw->__waiters);
|
if (w) a_dec(&rw->_rw_waiters);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,14 @@ int pthread_rwlock_timedwrlock(pthread_rwlock_t *rw, const struct timespec *at)
|
|||||||
{
|
{
|
||||||
int nr, *p, w=0;
|
int nr, *p, w=0;
|
||||||
while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
|
while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
|
||||||
if (!w) a_inc(&rw->__waiters), w++;
|
if (!w) a_inc(&rw->_rw_waiters), w++;
|
||||||
if ((nr=rw->__readers)) p = &rw->__readers;
|
if ((nr=rw->_rw_readers)) p = &rw->_rw_readers;
|
||||||
else nr=1, p = &rw->__wrlock;
|
else nr=1, p = &rw->_rw_wrlock;
|
||||||
if (__timedwait(p, nr, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
|
if (__timedwait(p, nr, CLOCK_REALTIME, at, 0)==ETIMEDOUT) {
|
||||||
if (w) a_dec(&rw->__waiters);
|
if (w) a_dec(&rw->_rw_waiters);
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w) a_dec(&rw->__waiters);
|
if (w) a_dec(&rw->_rw_waiters);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
|
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
a_inc(&rw->__readers);
|
a_inc(&rw->_rw_readers);
|
||||||
if (rw->__wrlock) {
|
if (rw->_rw_wrlock) {
|
||||||
a_dec(&rw->__readers);
|
a_dec(&rw->_rw_readers);
|
||||||
if (rw->__waiters && !rw->__readers)
|
if (rw->_rw_waiters && !rw->_rw_readers)
|
||||||
__wake(&rw->__readers, 1, 0);
|
__wake(&rw->_rw_readers, 1, 0);
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
|
int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
if (a_xchg(&rw->__wrlock, 1))
|
if (a_xchg(&rw->_rw_wrlock, 1))
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
if (rw->__readers) {
|
if (rw->_rw_readers) {
|
||||||
a_store(&rw->__wrlock, 0);
|
a_store(&rw->_rw_wrlock, 0);
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
}
|
}
|
||||||
rw->__owner = pthread_self()->tid;
|
rw->_rw_owner = pthread_self()->tid;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
int pthread_rwlock_unlock(pthread_rwlock_t *rw)
|
int pthread_rwlock_unlock(pthread_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
struct pthread *self = pthread_self();
|
struct pthread *self = pthread_self();
|
||||||
if (rw->__owner == self->tid) {
|
if (rw->_rw_owner == self->tid) {
|
||||||
rw->__owner = 0;
|
rw->_rw_owner = 0;
|
||||||
a_store(&rw->__wrlock, 0);
|
a_store(&rw->_rw_wrlock, 0);
|
||||||
if (rw->__waiters)
|
if (rw->_rw_waiters)
|
||||||
__wake(&rw->__wrlock, -1, 0);
|
__wake(&rw->_rw_wrlock, -1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
a_dec(&rw->__readers);
|
a_dec(&rw->_rw_readers);
|
||||||
if (rw->__waiters && !rw->__readers)
|
if (rw->_rw_waiters && !rw->_rw_readers)
|
||||||
__wake(&rw->__readers, 1, 0);
|
__wake(&rw->_rw_readers, 1, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *rw)
|
|||||||
{
|
{
|
||||||
int nr;
|
int nr;
|
||||||
while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
|
while (pthread_rwlock_trywrlock(rw)==EAGAIN) {
|
||||||
if ((nr=rw->__readers))
|
if ((nr=rw->_rw_readers))
|
||||||
__wait(&rw->__readers, &rw->__waiters, nr, 0);
|
__wait(&rw->_rw_readers, &rw->_rw_waiters, nr, 0);
|
||||||
else
|
else
|
||||||
__wait(&rw->__wrlock, &rw->__waiters, 1, 0);
|
__wait(&rw->_rw_wrlock, &rw->_rw_waiters, 1, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user