I need threads to report a data structure living on the heap to a controlling thread (star topology). I wanted to not use locks for this but to do this by atomically swapping the pointer to this data structure. So I have a set and get method for the report.
static atomic_uintptr_t aptr = ATOMIC_VAR_INIT((uintptr_t)NULL);
void set_report(void *newreport)
{
// swap the report pointer atomically
uintptr_t prev = atomic_exchange( &aptr, (uintptr_t)newreport);
// if prev is not NULL we need to destroy it
if ( prev != (uintptr_t)NULL )
{
// destroy the memory it is pointing to
free((void *)prev); // there seems to be no way of avoiding a compiler warning here
// about casting to a non-matching type :S
}
}
uintptr_t get_report()
{
// swap the report pointer atomically with NULL
uintptr_t report = atomic_exchange( &aptr, (uintptr_t)NULL);
// we now own report so the caller must destroy when finished with it
// unless it's null of course
return report;
}
I can use the code like this:
int *bla = (int*)calloc(1, sizeof(int));
*bla = 3;
set_report((void *)bla);
int *v = (int *)(void *)get_report();
I can hardly find any references or documentation about using the atomics with pointers so I have some questions about this code:
- Is this the right way to go when doing pointer swaps atomically in C
- From what I read I need to use uintptr_t when using the atomic methods for pointers (gcc stdatomic.h). But I can't get around the warnings about casting to non matching type. Should I just ignore those?
- Does 'aptr' need to be declared as volatile?