Skip to content

Commit

Permalink
Merge pull request #32 from badgeteam/mutex
Browse files Browse the repository at this point in the history
Support for not using timeouts on mutexes.
  • Loading branch information
robotman2412 authored Aug 26, 2023
2 parents a8d2c7c + a5fdc4d commit e24f319
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ void mutex_init_shared(badge_err_t *ec, mutex_t *mutex);
// Clean up the mutex.
void mutex_destroy(badge_err_t *ec, mutex_t *mutex);
// Try to acquire `mutex` within `max_wait_us` microseconds.
// If `max_wait_us` is too long or negative, do not use the timeout.
// Returns true if the mutex was successully acquired.
bool mutex_acquire(badge_err_t *ec, mutex_t *mutex, timestamp_us_t max_wait_us);
// Release `mutex`, if it was initially acquired by this thread.
// Returns true if the mutex was successfully released.
bool mutex_release(badge_err_t *ec, mutex_t *mutex);
// Try to acquire a share in `mutex` within `max_wait_us` microseconds.
// If `max_wait_us` is too long or negative, do not use the timeout.
// Returns true if the share was successfully acquired.
bool mutex_acquire_shared(badge_err_t *ec, mutex_t *mutex, timestamp_us_t max_wait_us);
// Release `mutex`, if it was initially acquired by this thread.
Expand Down
7 changes: 7 additions & 0 deletions include/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
#include <stddef.h>
#include <stdint.h>

#define FREQUENCY_HZ_MIN INT32_MIN
#define FREQUENCY_HZ_MAX INT32_MAX
#define TIMESTAMP_US_MIN INT64_MIN
#define TIMESTAMP_US_MAX INT64_MAX
#define TIMER_VALUE_MIN INT64_MIN
#define TIMER_VALUE_MAX INT64_MAX

typedef int32_t frequency_hz_t;
typedef int64_t timestamp_us_t;
typedef int64_t timer_value_t;
Expand Down
18 changes: 15 additions & 3 deletions src/mutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@ bool mutex_acquire(badge_err_t *ec, mutex_t *mutex, timestamp_us_t timeout) {
badge_err_set(ec, ELOC_UNKNOWN, ECAUSE_ILLEGAL);
return false;
}
timeout += time_us();
// Compute timeout.
timestamp_us_t now = time_us();
if (timeout < 0 || now + timeout < now) {
timeout = TIMESTAMP_US_MAX;
} else {
timeout += now;
}
// Await the shared portion to reach 0 and then lock.
if (await_swap_atomic_int(&mutex->shares, timeout, 0, EXCLUSIVE_MAGIC, memory_order_acquire)) {
// If that succeeds, the mutex was acquired.
Expand All @@ -121,7 +127,7 @@ bool mutex_release(badge_err_t *ec, mutex_t *mutex) {
badge_err_set(ec, ELOC_UNKNOWN, ECAUSE_ILLEGAL);
return false;
}
if (await_swap_atomic_int(&mutex->shares, time_us() + 10000000, EXCLUSIVE_MAGIC, 0, memory_order_release)) {
if (await_swap_atomic_int(&mutex->shares, TIMESTAMP_US_MAX, EXCLUSIVE_MAGIC, 0, memory_order_release)) {
// Successful release.
badge_err_set_ok(ec);
return true;
Expand All @@ -143,7 +149,13 @@ bool mutex_acquire_shared(badge_err_t *ec, mutex_t *mutex, timestamp_us_t timeou
badge_err_set(ec, ELOC_UNKNOWN, ECAUSE_ILLEGAL);
return false;
}
timeout += time_us();
// Compute timeout.
timestamp_us_t now = time_us();
if (timeout < 0 || now + timeout < now) {
timeout = TIMESTAMP_US_MAX;
} else {
timeout += now;
}
// Take a share.
if (thresh_add_atomic_int(&mutex->shares, timeout, EXCLUSIVE_MAGIC, memory_order_acquire)) {
// If that succeeds, the mutex was successfully acquired.
Expand Down

0 comments on commit e24f319

Please sign in to comment.