o Assertions to catch that stuff that shouldn't happen is not happening.
o In the rwlock code: move a duplicated check inside an if..else to after the if...else clause. o When initializing a static rwlock move the initialization check inside the lock. o In thr_setschedparam.c: When breaking out of the trylock...retry if busy loop make sure to reset the mtx pointer to null if the mutex is nolonger in a queue.
This commit is contained in:
parent
c29f084c76
commit
1d060bde99
@ -840,6 +840,8 @@ void
|
||||
readjust_priorities(struct pthread *pthread, struct pthread_mutex *mtx)
|
||||
{
|
||||
if ((pthread->flags & PTHREAD_FLAGS_IN_MUTEXQ) != 0) {
|
||||
PTHREAD_ASSERT(mtx != NULL,
|
||||
"mutex is NULL when it should not be");
|
||||
mutex_queue_remove(mtx, pthread);
|
||||
mutex_queue_enq(mtx, pthread);
|
||||
PTHREAD_LOCK(mtx->m_owner);
|
||||
|
@ -264,19 +264,15 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
goto out;
|
||||
}
|
||||
if (prwlock->state > 0) {
|
||||
PTHREAD_ASSERT(rh->rh_wrcount == 0,
|
||||
"write count on a readlock should be zero!");
|
||||
rh->rh_rdcount--;
|
||||
if (rh->rh_rdcount == 0) {
|
||||
LIST_REMOVE(rh, rh_link);
|
||||
free(rh);
|
||||
}
|
||||
if (--prwlock->state == 0 && prwlock->blocked_writers)
|
||||
ret = pthread_cond_signal(&prwlock->write_signal);
|
||||
} else if (prwlock->state < 0) {
|
||||
PTHREAD_ASSERT(rh->rh_rdcount == 0,
|
||||
"read count on a writelock should be zero!");
|
||||
rh->rh_wrcount--;
|
||||
if (rh->rh_wrcount == 0) {
|
||||
LIST_REMOVE(rh, rh_link);
|
||||
free(rh);
|
||||
}
|
||||
prwlock->state = 0;
|
||||
if (prwlock->blocked_writers)
|
||||
ret = pthread_cond_signal(&prwlock->write_signal);
|
||||
@ -290,6 +286,10 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
ret = EPERM;
|
||||
goto out;
|
||||
}
|
||||
if (rh->rh_wrcount == 0 && rh->rh_rdcount == 0) {
|
||||
LIST_REMOVE(rh, rh_link);
|
||||
free(rh);
|
||||
}
|
||||
|
||||
out:
|
||||
/* see the comment on this in rwlock_rdlock_common */
|
||||
@ -360,8 +360,10 @@ rwlock_wrlock_common(pthread_rwlock_t *rwlock, int nonblocking,
|
||||
*/
|
||||
if (curthread->rwlockList != NULL) {
|
||||
LIST_FOREACH(rh, curthread->rwlockList, rh_link) {
|
||||
if (rh->rh_rwlock == prwlock &&
|
||||
(rh->rh_rdcount > 0 || rh->rh_wrcount > 0)) {
|
||||
if (rh->rh_rwlock == prwlock) {
|
||||
PTHREAD_ASSERT((rh->rh_rdcount > 0 ||
|
||||
rh->rh_wrcount > 0),
|
||||
"Invalid 0 R/RW count!");
|
||||
pthread_mutex_unlock(&prwlock->lock);
|
||||
return (EDEADLK);
|
||||
break;
|
||||
@ -462,16 +464,10 @@ rwlock_init_static(struct pthread_rwlock **rwlock)
|
||||
{
|
||||
int error;
|
||||
|
||||
/*
|
||||
* The initial check is done without locks to not
|
||||
* pessimize the common path.
|
||||
*/
|
||||
error = 0;
|
||||
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER) {
|
||||
UMTX_LOCK(&init_lock);
|
||||
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
||||
error = _pthread_rwlock_init(rwlock, NULL);
|
||||
UMTX_UNLOCK(&init_lock);
|
||||
}
|
||||
UMTX_LOCK(&init_lock);
|
||||
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
||||
error = _pthread_rwlock_init(rwlock, NULL);
|
||||
UMTX_UNLOCK(&init_lock);
|
||||
return (error);
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ _pthread_setschedparam(pthread_t pthread, int policy,
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
mtx = NULL;
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
Loading…
Reference in New Issue
Block a user