vsync / spinlock / rec_ticketlock.h
Recursive ticketlock implementation using recursive.h.
Groups: Fair locks, Reentrant
rec_ticketlock is a ticketlock that supports recursion, i.e., is reentrant.
see vsync/spinlock/ticketlock.h
Example:
#include <vsync/spinlock/rec_ticketlock.h>
#include <vsync/common/assert.h>
#include <pthread.h>
#include <stdio.h>
#define N 12
#define EXPECTED_VAL N
rec_ticketlock_t g_lock = REC_TICKETLOCK_INIT();
vuint32_t g_x = 0;
vuint32_t g_y = 0;
void *
run(void *args)
{
vuint32_t tid = (vuint32_t)(vsize_t)args;
// can be acquired multiple times without causing dead-lock
rec_ticketlock_acquire(&g_lock, tid);
rec_ticketlock_acquire(&g_lock, tid);
g_x++;
g_y++;
rec_ticketlock_release(&g_lock);
rec_ticketlock_release(&g_lock);
(void)args;
return NULL;
}
int
main(void)
{
pthread_t threads[N];
for (vsize_t i = 0; i < N; i++) {
pthread_create(&threads[i], NULL, run, (void *)i);
}
for (vsize_t i = 0; i < N; i++) {
pthread_join(threads[i], NULL);
}
ASSERT(g_x == EXPECTED_VAL);
ASSERT(g_x == g_y);
printf("Final value %u\n", g_x);
return 0;
}
Macros
| Macro | Description |
|---|---|
| REC_TICKETLOCK_INIT | Initializer of rec_ticketlock. |
Macro REC_TICKETLOCK_INIT
REC_TICKETLOCK_INIT()
Initializer of rec_ticketlock.
Functions
| Function | Description |
|---|---|
| rec_ticketlock_init | Initializes the recursive ticketlock. |
| rec_ticketlock_acquire | Acquires the recursive ticketlock. |
| rec_ticketlock_release | Releases the recursive ticketlock. |
| rec_ticketlock_tryacquire | Tries to acquire the recursive ticketlock. |
Function rec_ticketlock_init
static void rec_ticketlock_init(struct rec_ticketlock_s *l)
Initializes the recursive ticketlock.
Parameters:
l: address of rec_ticketlock_t object.
Note: alternatively use
REC_TICKETLOCK_INIT.
Function rec_ticketlock_acquire
static void rec_ticketlock_acquire(struct rec_ticketlock_s *l, vuint32_t id)
Acquires the recursive ticketlock.
This function can be called multiple times by the same thread, consecutively.
Parameters:
l: address of rec_ticketlock_t object.id: thread ID or core ID.
Function rec_ticketlock_release
static void rec_ticketlock_release(struct rec_ticketlock_s *l)
Releases the recursive ticketlock.
To fully release the lock, this function should be called the same number of times as the acquire was consecutively called by thread that currently owns the lock.
Parameters:
l: address of rec_ticketlock_t object.
Function rec_ticketlock_tryacquire
static vbool_t rec_ticketlock_tryacquire(struct rec_ticketlock_s *l, vuint32_t id)
Tries to acquire the recursive ticketlock.
This can be called multiple times by the same thread, consecutively.
Parameters:
l: address of rec_ticketlock_t object.id: thread ID or core ID.
Returns: true, if lock is acquired successfully.
Returns: false, if failed to acquire the lock.