From 975aa92797424ff203e2269426afc62232bdfc19 Mon Sep 17 00:00:00 2001 From: Marco Schlumpp Date: Tue, 12 Sep 2023 13:21:01 +0200 Subject: [PATCH] lib/uklock: Remove the rwlock_{upgrade,downgrade} functions In the current form they impose very strong synchronization requirements, making it impossible to implement a more efficient read-write lock design. Most rwlocks sidestep this by either using a weaker `try_upgrade` variant or having a separate `lock_upgradable` function (allowing multiple readers but only one upgradable lock/writer lock). This removes these two functions for now to prevent new code relying on these functions. This change is breaking because it already was part of the previous release. Signed-off-by: Marco Schlumpp Reviewed-by: Andrei Tatar Approved-by: Razvan Deaconescu GitHub-Closes: #1090 --- lib/uklock/include/uk/rwlock.h | 18 ----------- lib/uklock/rwlock.c | 57 ---------------------------------- 2 files changed, 75 deletions(-) diff --git a/lib/uklock/include/uk/rwlock.h b/lib/uklock/include/uk/rwlock.h index cd4cb3b298..0ceee2645d 100644 --- a/lib/uklock/include/uk/rwlock.h +++ b/lib/uklock/include/uk/rwlock.h @@ -90,24 +90,6 @@ void uk_rwlock_runlock(struct uk_rwlock *rwl); */ void uk_rwlock_wunlock(struct uk_rwlock *rwl); -/** - * Upgrade the given read lock to a write lock - * - * @param rwl - * Reader-writer lock to upgrade. The current thread must hold the lock - * for reading - */ -void uk_rwlock_upgrade(struct uk_rwlock *rwl); - -/** - * Downgrade the given write lock to a read lock - * - * @param rwl - * Reader-writer lock to downgrade. The current thread must hold the lock - * for writing - */ -void uk_rwlock_downgrade(struct uk_rwlock *rwl); - #ifdef __cplusplus } diff --git a/lib/uklock/rwlock.c b/lib/uklock/rwlock.c index 2db6a7836c..c28b251551 100644 --- a/lib/uklock/rwlock.c +++ b/lib/uklock/rwlock.c @@ -133,60 +133,3 @@ void uk_rwlock_wunlock(struct uk_rwlock *rwl) uk_waitq_wake_up_one(&rwl->exclusive); } -void uk_rwlock_upgrade(struct uk_rwlock *rwl) -{ - UK_ASSERT(rwl); - - uk_spin_lock(&rwl->sl); - if (rwl->nactive == 1) { - /* We are the only active reader. Just upgrade to writer */ - rwl->nactive = -1; - } else { - /* There are other readers. Wait until these have left */ - UK_ASSERT(rwl->nactive > 1); - - /* - * Indicate that we are waiting for write access and remove - * this thread from the active readers. - */ - rwl->npending_writes++; - rwl->nactive--; - - uk_waitq_wait_event_locked(&rwl->shared, - rwl->nactive == 0, - uk_spin_lock, - uk_spin_unlock, - &rwl->sl); - - UK_ASSERT(rwl->npending_writes > 0); - UK_ASSERT(rwl->nactive == 0); - - /* We are now the writer. Remove the satisfied request and mark - * the lock for write access. - */ - rwl->npending_writes--; - rwl->nactive = -1; - } - uk_spin_unlock(&rwl->sl); -} - -void uk_rwlock_downgrade(struct uk_rwlock *rwl) -{ - int wake_readers; - - UK_ASSERT(rwl); - - uk_spin_lock(&rwl->sl); - UK_ASSERT(rwl->nactive == -1); - - /* We are the writer. Downgrade the lock to read access by - * transforming to a reader. If there are other readers waiting, wake - * them up. - */ - rwl->nactive = 1; - wake_readers = (rwl->npending_reads > 0); - uk_spin_unlock(&rwl->sl); - - if (wake_readers) - uk_waitq_wake_up(&rwl->shared); -}