rt/examples/fair.c

53 lines
1.2 KiB
C

#include <rt/assert.h>
#include <rt/mutex.h>
#include <rt/task.h>
#include <rt/trap.h>
#define NUM_TASKS 4
#define ITERATIONS 100U
static RT_MUTEX(mutex);
static uint32_t x[NUM_TASKS];
static uint32_t max_value;
static void trap_last(void)
{
static RT_SEM(trap_sem, NUM_TASKS - 1);
// Only the last task to finish will call rt_trap.
if (!rt_sem_trywait(&trap_sem))
{
for (uintptr_t task_index = 0; task_index < NUM_TASKS; ++task_index)
{
rt_assert(x[task_index] == ITERATIONS, "a task did not run enough");
}
rt_trap();
}
}
static void task(uintptr_t task_index)
{
rt_task_drop_privilege();
for (unsigned i = 0; i < ITERATIONS; ++i)
{
rt_mutex_lock(&mutex);
const uint32_t my_x = ++x[task_index];
rt_assert(max_value <= my_x, "the mutex is unfair");
max_value = my_x;
rt_task_sleep(1);
rt_mutex_unlock(&mutex);
}
trap_last();
}
static void timeout(void)
{
rt_task_sleep(1000);
rt_assert(false, "timed out");
}
RT_TASK_ARG(task, 0, RT_STACK_MIN * 2, 1);
RT_TASK_ARG(task, 1, RT_STACK_MIN * 2, 1);
RT_TASK_ARG(task, 2, RT_STACK_MIN * 2, 1);
RT_TASK_ARG(task, 3, RT_STACK_MIN * 2, 1);
RT_TASK(timeout, RT_STACK_MIN, 0);