rt/examples/once.c

47 lines
985 B
C

#include <rt/assert.h>
#include <rt/atomic.h>
#include <rt/log.h>
#include <rt/once.h>
#include <rt/task.h>
#include <rt/trap.h>
#define ITERATIONS 10000UL
static RT_ONCE(once);
static RT_SEM(sem, 0);
static rt_atomic_ulong x = 0;
static void fn(void)
{
rt_logf("once: %s\n", rt_task_name());
rt_atomic_fetch_add(&x, 1, RT_ATOMIC_RELAXED);
}
static void oncer(void)
{
rt_task_drop_privilege();
for (unsigned long i = 0; i < ITERATIONS; ++i)
{
rt_once_call(&once, fn);
rt_sem_wait(&sem);
}
}
static void oncer_reset(void)
{
rt_task_drop_privilege();
for (unsigned long i = 0; i < ITERATIONS; ++i)
{
rt_once_call(&once, fn);
rt_atomic_store(&once.done, 0, RT_ATOMIC_RELEASE);
rt_sem_post(&sem);
}
rt_assert(rt_atomic_load(&x, RT_ATOMIC_RELAXED) == ITERATIONS,
"x was not incremented enough");
rt_trap();
}
RT_TASK(oncer, RT_STACK_MIN, 1);
RT_TASK(oncer_reset, RT_STACK_MIN, 1);