From 328bd24443d2a345a5832ee48ebba0208f8036ea Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Wed, 19 Jul 2017 12:54:23 +0200 Subject: [PATCH] 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 Reviewed-by: Pavel Hrdina --- src/libvirt_private.syms | 1 + src/util/virthread.c | 35 +++++++++++++++++++++++++++++++++++ src/util/virthread.h | 1 + 3 files changed, 37 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b6569e2430..e58b5ebe32 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2730,6 +2730,7 @@ virMutexUnlock; virOnce; virRWLockDestroy; virRWLockInit; +virRWLockInitPreferWriter; virRWLockRead; virRWLockUnlock; virRWLockWrite; diff --git a/src/util/virthread.c b/src/util/virthread.c index 6c495158f5..a8dd72f8ba 100644 --- a/src/util/virthread.c +++ b/src/util/virthread.c @@ -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); diff --git a/src/util/virthread.h b/src/util/virthread.h index e466d9bf01..18b785af23 100644 --- a/src/util/virthread.h +++ b/src/util/virthread.h @@ -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);