50 lines
1.0 KiB
C
50 lines
1.0 KiB
C
#include <rt/assert.h>
|
|
#include <rt/atomic.h>
|
|
#include <rt/log.h>
|
|
#include <rt/once.h>
|
|
#include <rt/sem.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();
|
|
}
|
|
|
|
#define STACK_SIZE (RT_STACK_MIN * 2)
|
|
|
|
RT_TASK(oncer, STACK_SIZE, 0);
|
|
RT_TASK(oncer_reset, STACK_SIZE, 0);
|