vsync / bitmap / bitmap.h
A bitmap implementation.
Bitmap with basic functionality.
Example:
#include <vsync/bitmap/bitmap.h>
#include <vsync/common/assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define WRITER_COUNT 11U
#define N (WRITER_COUNT + 1)
#define BIT_COUNT (VUINT64_WIDTH * WRITER_COUNT)
vbitmap_t *g_bitmap;
void
reader(void)
{
vsize_t idx = 0;
vbitmap_iter_t iter = {0};
vsize_t signal_count = 0;
vsize_t expected = BIT_COUNT - WRITER_COUNT;
while (signal_count < expected) {
signal_count = 0;
vbitmap_iter_init(g_bitmap, &iter);
while (vbitmap_iter_next(&iter, &idx)) {
signal_count++;
}
printf("%zu bits were raised, expected %zu\n", signal_count, expected);
}
}
void
writer(vsize_t tid)
{
vbool_t set = false;
// each writer sets 64 bits
vsize_t from = tid * VUINT64_WIDTH;
vsize_t to = from + VUINT64_WIDTH - 1;
vbitmap_set_range(g_bitmap, from, to);
set = vbitmap_get(g_bitmap, from);
ASSERT(set == true);
vbitmap_clr_bit(g_bitmap, from);
set = vbitmap_get(g_bitmap, from);
ASSERT(set == false);
vbitmap_set_bit(g_bitmap, from);
set = vbitmap_get(g_bitmap, from);
ASSERT(set == true);
}
void *
run(void *args)
{
vsize_t tid = (vsize_t)(vuintptr_t)args;
if (tid == WRITER_COUNT) {
reader();
} else {
writer(tid);
}
return NULL;
}
int
main(void)
{
pthread_t threads[N];
vsize_t size = vbitmap_size(BIT_COUNT);
g_bitmap = malloc(size);
vbitmap_init(g_bitmap, BIT_COUNT, false);
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);
}
free(g_bitmap);
return 0;
}
References:
The interface is inspired by and similar to ck_bitmap
Functions
| Function | Description |
|---|---|
| vbitmap_size | Calculates the size of vbitmap_t object based on the given number of bits. |
| vbitmap_init | Initializes the given bitmap object. |
| vbitmap_clear | Clears all bits in the given bitmap. |
| vbitmap_get | Returns the value of the bit at index bit_idx. |
| vbitmap_set_bit | Sets the bit at index bit_idx. |
| vbitmap_set_range | Sets all bits with indexes that are in range [from:to]. |
| vbitmap_clr_range | Clears all bits with indexes that are in range [from:to]. |
| vbitmap_clr_bit | Clears the bit at index bit_idx. |
| vbitmap_iter_init | Initializes the given vbitmap_iter_t object. |
| vbitmap_iter_next | Iterates to the next set bit. |
Function vbitmap_size
static vsize_t vbitmap_size(vsize_t bit_count)
Calculates the size of vbitmap_t object based on the given number of bits.
Parameters:
bit_count: number of bits.
Returns: vsize_t size of vbitmap_t object needed to accommodate bit_count of bits.
Function vbitmap_init
static void vbitmap_init(vbitmap_t *bitmap, vsize_t bit_count, vbool_t set)
Initializes the given bitmap object.
All bits are unset initially.
Parameters:
bitmap: address of vbitmap_t object.bit_count: number of bits.set: true if all bits should be set, false otherwise.
Function vbitmap_clear
static void vbitmap_clear(vbitmap_t *bitmap)
Clears all bits in the given bitmap.
Parameters:
bitmap: address of vbitmap_t object.
Function vbitmap_get
static vbool_t vbitmap_get(vbitmap_t *bitmap, vsize_t bit_idx)
Returns the value of the bit at index bit_idx.
Parameters:
bitmap: address of vbitmap_t object.bit_idx: index of the bit to set.
Returns: true the bit is set.
Returns: false the bit is unset.
Function vbitmap_set_bit
static void vbitmap_set_bit(vbitmap_t *bitmap, vsize_t bit_idx)
Sets the bit at index bit_idx.
Parameters:
bitmap: address of vbitmap_t object.bit_idx: index of the bit to set.
Function vbitmap_set_range
static void vbitmap_set_range(vbitmap_t *bitmap, vsize_t from, vsize_t to)
Sets all bits with indexes that are in range [from:to].
Note: the range is inclusive both bits at index
fromand indextowill be set.
Parameters:
bitmap: address of vbitmap_t object.from: index of the LSB in the range.to: index of the MSB in the range.
Note: This function is not atomic. Bits inside the range might not be raised at once. Raising bits occur in multiple steps.
Function vbitmap_clr_range
static void vbitmap_clr_range(vbitmap_t *bitmap, vsize_t from, vsize_t to)
Clears all bits with indexes that are in range [from:to].
Note: the range is inclusive both bits at index
fromand indextowill be set.
Parameters:
bitmap: address of vbitmap_t object.from: index of the LSB in the range.to: index of the MSB in the range.
Note: This function is not atomic. Bits inside the range might not be cleared at once. Clearing bits occur in multiple steps.
Function vbitmap_clr_bit
static void vbitmap_clr_bit(vbitmap_t *bitmap, vsize_t bit_idx)
Clears the bit at index bit_idx.
Parameters:
bitmap: address of vbitmap_t object.bit_idx: index of the bit to unset.
Function vbitmap_iter_init
static void vbitmap_iter_init(vbitmap_t *bitmap, vbitmap_iter_t *iter)
Initializes the given vbitmap_iter_t object.
Parameters:
bitmap: address of vbitmap_t to iterate over.iter: address of vbitmap_iter_t object.
Function vbitmap_iter_next
static vbool_t vbitmap_iter_next(vbitmap_iter_t *iter, vsize_t *out_bit_idx)
Iterates to the next set bit.
Parameters:
iter: address of vbitmap_iter_t object.out_bit_idx: index of the next set bit.
Returns: true next set bit is found.
Returns: false no more set bits are found.
Precondition: call vbitmap_iter_init to initialize iter before first use.