virthread: Introduce virRWLockInitPreferWriter

We already have virRWLockInit. But this uses pthread defaults
which prefer reader to initialize the RW lock. This may lead to
writer starvation. Therefore we need to have the counterpart that
prefers writers. Now, according to the
pthread_rwlockattr_setkind_np() man page setting
PTHREAD_RWLOCK_PREFER_WRITER_NP attribute is no-op. Therefore we
need to use PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
attribute. So much for good enum value names.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Michal Privoznik 2017-07-19 12:54:23 +02:00
parent 64bebb2ba4
commit 328bd24443
3 changed files with 37 additions and 0 deletions

View File

@ -2730,6 +2730,7 @@ virMutexUnlock;
virOnce;
virRWLockDestroy;
virRWLockInit;
virRWLockInitPreferWriter;
virRWLockRead;
virRWLockUnlock;
virRWLockWrite;

View File

@ -95,6 +95,15 @@ void virMutexUnlock(virMutexPtr m)
}
/**
* virRWLockInit:
* @m: rwlock to init
*
* Initializes RW lock using pthread default attributes (which
* is PTHREAD_RWLOCK_PREFER_READER_NP).
*
* Returns 0 on success, -1 otherwise.
*/
int virRWLockInit(virRWLockPtr m)
{
int ret;
@ -106,6 +115,32 @@ int virRWLockInit(virRWLockPtr m)
return 0;
}
/**
* virRWLockInitPreferWriter:
* @m: rwlock to init
*
* Initializes RW lock which prefers writers over readers.
*
* Returns 0 on success, -1 otherwise.
*/
int virRWLockInitPreferWriter(virRWLockPtr m)
{
int ret;
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
ret = pthread_rwlock_init(&m->lock, &attr);
pthread_rwlockattr_destroy(&attr);
if (ret != 0) {
errno = ret;
return -1;
}
return 0;
}
void virRWLockDestroy(virRWLockPtr m)
{
pthread_rwlock_destroy(&m->lock);

View File

@ -136,6 +136,7 @@ void virMutexUnlock(virMutexPtr m);
int virRWLockInit(virRWLockPtr m) ATTRIBUTE_RETURN_CHECK;
int virRWLockInitPreferWriter(virRWLockPtr m) ATTRIBUTE_RETURN_CHECK;
void virRWLockDestroy(virRWLockPtr m);
void virRWLockRead(virRWLockPtr m);