Skip to content

Instantly share code, notes, and snippets.

@matteobertozzi
Created March 19, 2013 13:17
Show Gist options
  • Select an option

  • Save matteobertozzi/5196025 to your computer and use it in GitHub Desktop.

Select an option

Save matteobertozzi/5196025 to your computer and use it in GitHub Desktop.
Read/Write lock
struct rwlock {
volatile uint32_t state;
};
static void __rwlock_init (struct rwlock *lock) {
lock->state = 0;
}
static void __read_lock (struct rwlock *lock) {
unsigned int new_state;
unsigned int expected;
do {
expected = lock->state & 0xffff; /* I expect no write lock */
new_state = expected + 1; /* Add me as reader */
} while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}
static void __read_unlock (struct rwlock *lock) {
unsigned int new_state;
unsigned int expected;
do {
expected = lock->state; /* I expect a write lock and other readers */
new_state = expected - 1; /* Drop me as reader */
} while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}
static void __write_lock (struct rwlock *lock) {
unsigned int new_state;
unsigned int expected;
do {
expected = lock->state & 0xffff; /* I expect some 0+ readers */
new_state = (1 << 16) | expected; /* I want to lock the other writers */
} while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
/* Wait pending reads */
while ((lock->state & 0xffff) > 0) /* cpu_relax(); */;
}
static void __write_unlock (struct rwlock *lock) {
unsigned int new_state;
unsigned int expected;
do {
expected = 1 << 16; /* I expect to be the only writer */
new_state = 0; /* reset: no writers/no readers */
} while (!__sync_bool_compare_and_swap(&(lock->state), expected, new_state));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment