Skip to content

Commit

Permalink
lib/uklock: Remove the rwlock_{upgrade,downgrade} functions
Browse files Browse the repository at this point in the history
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 <marco@unikraft.io>
Reviewed-by: Andrei Tatar <andrei@unikraft.io>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1090
  • Loading branch information
mschlumpp authored and razvand committed Oct 3, 2023
1 parent c0fe2aa commit 975aa92
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 75 deletions.
18 changes: 0 additions & 18 deletions lib/uklock/include/uk/rwlock.h
Expand Up @@ -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
}
Expand Down
57 changes: 0 additions & 57 deletions lib/uklock/rwlock.c
Expand Up @@ -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);
}

0 comments on commit 975aa92

Please sign in to comment.