Add pthread_rwlockattr_setkind_np and pthread_rwlockattr_getkind_np, the
functions set or get pthread_rwlock type, current supported types are: PTHREAD_RWLOCK_PREFER_READER_NP, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, PTHREAD_RWLOCK_PREFER_WRITER_NP, default is PTHREAD_RWLOCK_PREFER_WRITER_NONCECURSIVE_NP, this maintains binary compatible with old code.
This commit is contained in:
parent
e25daafbb6
commit
a6b9b59e04
@ -135,6 +135,15 @@ enum pthread_mutextype {
|
||||
|
||||
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
|
||||
|
||||
enum pthread_rwlocktype_np
|
||||
{
|
||||
PTHREAD_RWLOCK_PREFER_READER_NP,
|
||||
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
|
||||
PTHREAD_RWLOCK_PREFER_WRITER_NP,
|
||||
PTHREAD_RWLOCK_DEFAULT_NP =
|
||||
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
|
||||
};
|
||||
|
||||
struct _pthread_cleanup_info {
|
||||
__uintptr_t pthread_cleanup_pad[8];
|
||||
};
|
||||
@ -233,11 +242,14 @@ int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t *);
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *);
|
||||
int pthread_rwlockattr_init(pthread_rwlockattr_t *);
|
||||
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
|
||||
int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *,
|
||||
int *);
|
||||
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *,
|
||||
int *);
|
||||
int pthread_rwlockattr_init(pthread_rwlockattr_t *);
|
||||
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int);
|
||||
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
|
||||
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
|
||||
pthread_t pthread_self(void);
|
||||
int pthread_setspecific(pthread_key_t, const void *);
|
||||
|
||||
|
@ -318,7 +318,9 @@ FBSDprivate_1.0 {
|
||||
_pthread_rwlock_wrlock;
|
||||
_pthread_rwlockattr_destroy;
|
||||
_pthread_rwlockattr_getpshared;
|
||||
_pthread_rwlockattr_getkind_np;
|
||||
_pthread_rwlockattr_init;
|
||||
_pthread_rwlockattr_setkind_np;
|
||||
_pthread_rwlockattr_setpshared;
|
||||
_pthread_self;
|
||||
_pthread_set_name_np;
|
||||
@ -403,4 +405,6 @@ FBSD_1.2 {
|
||||
openat;
|
||||
setcontext;
|
||||
swapcontext;
|
||||
pthread_rwlockattr_getkind_np;
|
||||
pthread_rwlockattr_setkind_np;
|
||||
};
|
||||
|
@ -285,11 +285,14 @@ struct pthread_prio {
|
||||
|
||||
struct pthread_rwlockattr {
|
||||
int pshared;
|
||||
int kind;
|
||||
};
|
||||
|
||||
struct pthread_rwlock {
|
||||
struct urwlock lock;
|
||||
struct pthread *owner;
|
||||
int recurse;
|
||||
int kind;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -63,13 +63,19 @@ __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
|
||||
*/
|
||||
|
||||
static int
|
||||
rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
|
||||
rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
||||
{
|
||||
pthread_rwlock_t prwlock;
|
||||
|
||||
prwlock = (pthread_rwlock_t)calloc(1, sizeof(struct pthread_rwlock));
|
||||
if (prwlock == NULL)
|
||||
return (ENOMEM);
|
||||
if (attr != NULL)
|
||||
prwlock->kind = (*attr)->kind;
|
||||
else
|
||||
prwlock->kind = PTHREAD_RWLOCK_DEFAULT_NP;
|
||||
if (prwlock->kind == PTHREAD_RWLOCK_PREFER_READER_NP)
|
||||
prwlock->lock.rw_flags |= URWLOCK_PREFER_READER;
|
||||
*rwlock = prwlock;
|
||||
return (0);
|
||||
}
|
||||
@ -112,7 +118,7 @@ init_static(struct pthread *thread, pthread_rwlock_t *rwlock)
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
||||
_pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
||||
{
|
||||
*rwlock = NULL;
|
||||
return (rwlock_init(rwlock, attr));
|
||||
@ -260,6 +266,14 @@ rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
|
||||
|
||||
CHECK_AND_INIT_RWLOCK
|
||||
|
||||
if (__predict_false(prwlock->owner == curthread)) {
|
||||
if (__predict_false(
|
||||
prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
|
||||
prwlock->recurse++;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX said the validity of the abstimeout parameter need
|
||||
* not be checked if the lock can be immediately acquired.
|
||||
@ -335,6 +349,13 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
if (state & URWLOCK_WRITE_OWNER) {
|
||||
if (__predict_false(prwlock->owner != curthread))
|
||||
return (EPERM);
|
||||
if (__predict_false(
|
||||
prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
|
||||
if (prwlock->recurse > 0) {
|
||||
prwlock->recurse--;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
prwlock->owner = NULL;
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,10 @@
|
||||
|
||||
__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy);
|
||||
__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared);
|
||||
__weak_reference(_pthread_rwlockattr_getkind_np, pthread_rwlockattr_getkind_np);
|
||||
__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init);
|
||||
__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared);
|
||||
__weak_reference(_pthread_rwlockattr_setkind_np, pthread_rwlockattr_setkind_np);
|
||||
|
||||
int
|
||||
_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr)
|
||||
@ -98,3 +100,21 @@ _pthread_rwlockattr_setpshared(pthread_rwlockattr_t *rwlockattr, int pshared)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int kind)
|
||||
{
|
||||
if (kind != PTHREAD_RWLOCK_PREFER_READER_NP ||
|
||||
kind != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP ||
|
||||
kind != PTHREAD_RWLOCK_PREFER_WRITER_NP) {
|
||||
return (EINVAL);
|
||||
}
|
||||
(*attr)->kind = kind;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *attr, int *kind)
|
||||
{
|
||||
*kind = (*attr)->kind;
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user