Hello,
currently it is possible to write-starve the read-write lock.
It is also the default behavior in glibc and musl libc pthreads.
I am dealing with a situation in my project which would "benefit"
from writer prioritized rwlocks, but I hacked around this with a
"halting" mutex that stops the readers from entering the critical
section. (in my use case, the rwlocks are very often writer-starved)
Just curious if you would be interested in this, or against such
modification. Below is a diff that trivially fixes the starvation.
If people are not against, I would like to open a PR with this,
or possibly something more sophisticated in the future.
Thanks, take care.
--
mc
diff --git a/uspace/lib/c/include/fibril_synch.h
b/uspace/lib/c/include/fibril_synch.h
index fc32aa13d..905f484e1 100644
--- a/uspace/lib/c/include/fibril_synch.h
+++ b/uspace/lib/c/include/fibril_synch.h
@@ -99,6 +99,7 @@ typedef struct {
fibril_owner_info_t oi; /**< Keep this the first thing. */
unsigned int writers;
unsigned int readers;
+ unsigned int writers_in_queue;
list_t waiters;
} fibril_rwlock_t;
diff --git a/uspace/lib/c/generic/thread/fibril_synch.c
b/uspace/lib/c/generic/thread/fibril_synch.c
index 2326d001a..fcb01c97c 100644
--- a/uspace/lib/c/generic/thread/fibril_synch.c
+++ b/uspace/lib/c/generic/thread/fibril_synch.c
@@ -236,6 +236,7 @@ void fibril_rwlock_initialize(fibril_rwlock_t *frw)
frw->oi.owned_by = NULL;
frw->writers = 0;
frw->readers = 0;
+ frw->writers_in_queue = 0;
list_initialize(&frw->waiters);
}
@@ -245,7 +246,7 @@ void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
futex_lock(&fibril_synch_futex);
- if (!frw->writers) {
+ if (!frw->writers && frw->writers_in_queue == 0) {
/* Consider the first reader the owner. */
if (frw->readers++ == 0)
frw->oi.owned_by = f;
@@ -282,6 +283,7 @@ void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
awaiter_t wdata = AWAITER_INIT;
list_append(&wdata.link, &frw->waiters);
+ frw->writers_in_queue++;
check_for_deadlock(&frw->oi);
f->waits_for = &frw->oi;
@@ -331,6 +333,7 @@ static void _fibril_rwlock_common_unlock(fibril_rwlock_t
*frw)
if (frw->readers)
break;
frw->writers++;
+ frw->writers_in_queue--;
} else {
frw->readers++;
}
_______________________________________________
HelenOS-devel mailing list
[email protected]
http://lists.modry.cz/listinfo/helenos-devel