53 lines
1.2 KiB
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);
|