vsync / spinlock / hemlock.h
Hemlock by Dice and Kogan.
Groups: Fair locks
Example:
#include <vsync/spinlock/hemlock.h>
#include <vsync/common/assert.h>
#include <pthread.h>
#include <stdio.h>
#define N 12
#define MAX_THREADS N
#define EXPECTED_VAL N
hemlock_t g_lock_a = HEMLOCK_INIT();
hemlock_t g_lock_b = HEMLOCK_INIT();
hem_node_t g_nodes[N];
vuint32_t g_x = 0;
vuint32_t g_y = 0;
void *
run(void *args)
{
vsize_t tid = (vsize_t)args;
// the same thread context object can be used with multiple instances of
// hemlock
hemlock_acquire(&g_lock_a, &g_nodes[tid]);
hemlock_acquire(&g_lock_b, &g_nodes[tid]);
g_x++;
g_y++;
hemlock_release(&g_lock_b, &g_nodes[tid]);
hemlock_release(&g_lock_a, &g_nodes[tid]);
(void)args;
return NULL;
}
int
main(void)
{
pthread_t threads[N];
// use this function as an alternative to HEMLOCK_INIT
hemlock_init(&g_lock_a);
hemlock_init(&g_lock_b);
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;
}
References:
Dice and Kogan - Hemlock : Compact and Scalable Mutual Exclusion
Macros
| Macro | Description |
|---|---|
| HEMLOCK_INIT | Initializer of hemlock_t. |
Macro HEMLOCK_INIT
HEMLOCK_INIT()
Initializer of hemlock_t.
Functions
| Function | Description |
|---|---|
| hemlock_init | Initializes the given lock object l. |
| hemlock_tryacquire | Tries to acquire the Hemlock. |
| hemlock_acquire | Acquires the Hemlock. |
| hemlock_release | Releases the Hemlock. |
| hemlock_has_waiters | Returns whether there is a thread waiting to acquire the Hemlock. |
Function hemlock_init
static void hemlock_init(hemlock_t *l)
Initializes the given lock object l.
Parameters:
l: address of hemlock_t object.
Function hemlock_tryacquire
static int hemlock_tryacquire(hemlock_t *l, hem_node_t *node)
Tries to acquire the Hemlock.
Parameters:
l: address of hemlock_t object.node: address of hem_node_t object. Associated with the calling thread/core.
Returns: 1 on success, 0 on failure
Function hemlock_acquire
static void hemlock_acquire(hemlock_t *l, hem_node_t *node)
Acquires the Hemlock.
Parameters:
l: address of hemlock_t object.node: address of hem_node_t object. Associated with the calling thread/core.
Function hemlock_release
static void hemlock_release(hemlock_t *l, hem_node_t *node)
Releases the Hemlock.
Parameters:
l: address of hemlock_t object.node: address of hem_node_t object. Associated with the calling thread/core.
Function hemlock_has_waiters
static int hemlock_has_waiters(hemlock_t *l, hem_node_t *node)
Returns whether there is a thread waiting to acquire the Hemlock.
This function should only be called by the current owner of the lock.
Parameters:
l: address of hemlock_t object.node: address of hem_node_t object. Associated with the calling thread/core.