Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_rwlock.c
Show All 35 Lines | |||||
#include "namespace.h" | #include "namespace.h" | ||||
#include <pthread.h> | #include <pthread.h> | ||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
#include "thr_private.h" | #include "thr_private.h" | ||||
_Static_assert(sizeof(struct pthread_rwlock) <= PAGE_SIZE, | _Static_assert(sizeof(struct pthread_rwlock) <= PAGE_SIZE, | ||||
"pthread_rwlock is too large for off-page"); | "pthread_rwlock is too large for off-page"); | ||||
__weak_reference(_pthread_rwlock_destroy, pthread_rwlock_destroy); | __weak_reference(_thr_rwlock_destroy, pthread_rwlock_destroy); | ||||
__weak_reference(_pthread_rwlock_init, pthread_rwlock_init); | __weak_reference(_thr_rwlock_destroy, _pthread_rwlock_destroy); | ||||
__weak_reference(_pthread_rwlock_rdlock, pthread_rwlock_rdlock); | __weak_reference(_thr_rwlock_init, pthread_rwlock_init); | ||||
__weak_reference(_thr_rwlock_init, _pthread_rwlock_init); | |||||
__weak_reference(_Tthr_rwlock_rdlock, pthread_rwlock_rdlock); | |||||
__weak_reference(_Tthr_rwlock_rdlock, _pthread_rwlock_rdlock); | |||||
__weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); | __weak_reference(_pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock); | ||||
__weak_reference(_pthread_rwlock_tryrdlock, pthread_rwlock_tryrdlock); | __weak_reference(_Tthr_rwlock_tryrdlock, pthread_rwlock_tryrdlock); | ||||
__weak_reference(_pthread_rwlock_trywrlock, pthread_rwlock_trywrlock); | __weak_reference(_Tthr_rwlock_tryrdlock, _pthread_rwlock_tryrdlock); | ||||
__weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); | __weak_reference(_Tthr_rwlock_trywrlock, pthread_rwlock_trywrlock); | ||||
__weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); | __weak_reference(_Tthr_rwlock_trywrlock, _pthread_rwlock_trywrlock); | ||||
__weak_reference(_Tthr_rwlock_unlock, pthread_rwlock_unlock); | |||||
__weak_reference(_Tthr_rwlock_unlock, _pthread_rwlock_unlock); | |||||
__weak_reference(_Tthr_rwlock_wrlock, pthread_rwlock_wrlock); | |||||
__weak_reference(_Tthr_rwlock_wrlock, _pthread_rwlock_wrlock); | |||||
__weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); | __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); | ||||
static int init_static(struct pthread *thread, pthread_rwlock_t *rwlock); | static int init_static(struct pthread *thread, pthread_rwlock_t *rwlock); | ||||
static int init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out); | static int init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out); | ||||
static int __always_inline | static int __always_inline | ||||
check_and_init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out) | check_and_init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (prwlock == NULL) | ||||
return (EFAULT); | return (EFAULT); | ||||
prwlock->lock.rw_flags |= USYNC_PROCESS_SHARED; | prwlock->lock.rw_flags |= USYNC_PROCESS_SHARED; | ||||
*rwlock = THR_PSHARED_PTR; | *rwlock = THR_PSHARED_PTR; | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_destroy (pthread_rwlock_t *rwlock) | _thr_rwlock_destroy(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
pthread_rwlock_t prwlock; | pthread_rwlock_t prwlock; | ||||
int ret; | int ret; | ||||
prwlock = *rwlock; | prwlock = *rwlock; | ||||
if (prwlock == THR_RWLOCK_INITIALIZER) | if (prwlock == THR_RWLOCK_INITIALIZER) | ||||
ret = 0; | ret = 0; | ||||
else if (prwlock == THR_RWLOCK_DESTROYED) | else if (prwlock == THR_RWLOCK_DESTROYED) | ||||
Show All 23 Lines | else | ||||
ret = 0; | ret = 0; | ||||
THR_LOCK_RELEASE(thread, &_rwlock_static_lock); | THR_LOCK_RELEASE(thread, &_rwlock_static_lock); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) | _thr_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) | ||||
{ | { | ||||
*rwlock = NULL; | *rwlock = NULL; | ||||
return (rwlock_init(rwlock, attr)); | return (rwlock_init(rwlock, attr)); | ||||
} | } | ||||
static int | static int | ||||
rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime) | rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime) | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | for (;;) { | ||||
} | } | ||||
} | } | ||||
if (ret == 0) | if (ret == 0) | ||||
curthread->rdlock_count++; | curthread->rdlock_count++; | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) | _Tthr_rwlock_rdlock(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
return (rwlock_rdlock_common(rwlock, NULL)); | return (rwlock_rdlock_common(rwlock, NULL)); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict rwlock, | _pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict rwlock, | ||||
const struct timespec * __restrict abstime) | const struct timespec * __restrict abstime) | ||||
{ | { | ||||
return (rwlock_rdlock_common(rwlock, abstime)); | return (rwlock_rdlock_common(rwlock, abstime)); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) | _Tthr_rwlock_tryrdlock(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
struct pthread *curthread = _get_curthread(); | struct pthread *curthread = _get_curthread(); | ||||
pthread_rwlock_t prwlock; | pthread_rwlock_t prwlock; | ||||
int flags; | int flags; | ||||
int ret; | int ret; | ||||
ret = check_and_init_rwlock(rwlock, &prwlock); | ret = check_and_init_rwlock(rwlock, &prwlock); | ||||
if (ret != 0) | if (ret != 0) | ||||
Show All 19 Lines | _Tthr_rwlock_tryrdlock(pthread_rwlock_t *rwlock) | ||||
ret = _thr_rwlock_tryrdlock(&prwlock->lock, flags); | ret = _thr_rwlock_tryrdlock(&prwlock->lock, flags); | ||||
if (ret == 0) | if (ret == 0) | ||||
curthread->rdlock_count++; | curthread->rdlock_count++; | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) | _Tthr_rwlock_trywrlock(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
struct pthread *curthread = _get_curthread(); | struct pthread *curthread = _get_curthread(); | ||||
pthread_rwlock_t prwlock; | pthread_rwlock_t prwlock; | ||||
int ret; | int ret; | ||||
ret = check_and_init_rwlock(rwlock, &prwlock); | ret = check_and_init_rwlock(rwlock, &prwlock); | ||||
if (ret != 0) | if (ret != 0) | ||||
return (ret); | return (ret); | ||||
ret = _thr_rwlock_trywrlock(&prwlock->lock); | ret = _thr_rwlock_trywrlock(&prwlock->lock); | ||||
if (ret == 0) | if (ret == 0) | ||||
prwlock->owner = TID(curthread); | prwlock->owner = TID(curthread); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static int | static int | ||||
rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) | rwlock_wrlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime) | ||||
{ | { | ||||
struct pthread *curthread = _get_curthread(); | struct pthread *curthread = _get_curthread(); | ||||
pthread_rwlock_t prwlock; | pthread_rwlock_t prwlock; | ||||
int ret; | int ret; | ||||
ret = check_and_init_rwlock(rwlock, &prwlock); | ret = check_and_init_rwlock(rwlock, &prwlock); | ||||
if (ret != 0) | if (ret != 0) | ||||
return (ret); | return (ret); | ||||
Show All 29 Lines | if (_thr_rwlock_trywrlock(&prwlock->lock) == 0) { | ||||
prwlock->owner = TID(curthread); | prwlock->owner = TID(curthread); | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) | _Tthr_rwlock_wrlock(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
return (rwlock_wrlock_common (rwlock, NULL)); | return (rwlock_wrlock_common (rwlock, NULL)); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict rwlock, | _pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict rwlock, | ||||
const struct timespec * __restrict abstime) | const struct timespec * __restrict abstime) | ||||
{ | { | ||||
return (rwlock_wrlock_common (rwlock, abstime)); | return (rwlock_wrlock_common (rwlock, abstime)); | ||||
} | } | ||||
int | int | ||||
_pthread_rwlock_unlock(pthread_rwlock_t *rwlock) | _Tthr_rwlock_unlock(pthread_rwlock_t *rwlock) | ||||
{ | { | ||||
struct pthread *curthread = _get_curthread(); | struct pthread *curthread = _get_curthread(); | ||||
pthread_rwlock_t prwlock; | pthread_rwlock_t prwlock; | ||||
int ret; | int ret; | ||||
int32_t state; | int32_t state; | ||||
if (*rwlock == THR_PSHARED_PTR) { | if (*rwlock == THR_PSHARED_PTR) { | ||||
prwlock = __thr_pshared_offpage(rwlock, 0); | prwlock = __thr_pshared_offpage(rwlock, 0); | ||||
Show All 22 Lines |