This program is a hazard pointers implementation based on:
< Lock-Free Data Structures with Hazard Pointers >
While the concept is coming from the paper, the actually implementation may differ.
The correctness of this program hasn't been verified rigorously.
Create the protect list, which stores the hazard pointers. Every thread using the same hazard pointers should share the same hp_pr_t.
Create the hp_t, which comprises an existing protect list(hazard pointers) and an empty retired list. The retired list is local to each writer thread, therefore all writer threads should call hp_init. The caller can define the deallocating function.
Access the pointer and store it in protect list(hazard pointers). The ptr must be the address of the variable you want to load.
The return value hp_addr_t is an address of the hazard pointer, by dereferencing to access the value.
Release the hazard pointer. Pass the hp_addr_t returned by hp_pr_load.
Example:
hp_addr_t ptr_addr = hp_pr_load(pr, &data);
int *ptr = atomic_load(ptr_addr);
// do something
printf("%d\n", *ptr);
hp_pr_release(pr, ptr_addr);
Add the ptr to the retired list and try to deallocate it.
Try to release the pointers in the retired list. The return value is the number of pointers that can't be deallocated. Before the writer thread returns, it should use this function to ensure that there aren't remaining pointers in the retired list.
Example:
void *writer(void *arg)
{
void **argv = (void **) arg;
hp_pr_t *pr = argv[0];
hp_t *hp = hp_init(pr, free);
/* do something */
/* retire something */
while (hp_scan(hp))
;
free(hp);
}
Return the number of hazard pointers.
Deallocate the protect list in pr and hp_pr_t itself.