76 lines
1.5 KiB
C
76 lines
1.5 KiB
C
#include <rt/assert.h>
|
|
#include <rt/log.h>
|
|
#include <rt/mutex.h>
|
|
#include <rt/sem.h>
|
|
#include <rt/task.h>
|
|
#include <rt/trap.h>
|
|
|
|
static RT_MUTEX(mutex);
|
|
static unsigned x = 0;
|
|
|
|
#define NUM_TASKS 3
|
|
#define ITERATIONS 10000U
|
|
|
|
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))
|
|
{
|
|
rt_assert(x == (ITERATIONS * NUM_TASKS), "x has the wrong value");
|
|
rt_trap();
|
|
}
|
|
}
|
|
|
|
static void increment_lock(void)
|
|
{
|
|
rt_task_drop_privilege();
|
|
for (unsigned i = 0; i < ITERATIONS; ++i)
|
|
{
|
|
rt_mutex_lock(&mutex);
|
|
++x;
|
|
rt_mutex_unlock(&mutex);
|
|
}
|
|
trap_last();
|
|
}
|
|
|
|
static void increment_trylock(void)
|
|
{
|
|
rt_task_drop_privilege();
|
|
for (unsigned i = 0; i < ITERATIONS; ++i)
|
|
{
|
|
while (!rt_mutex_trylock(&mutex))
|
|
{
|
|
rt_task_sleep(1);
|
|
}
|
|
++x;
|
|
rt_mutex_unlock(&mutex);
|
|
}
|
|
trap_last();
|
|
}
|
|
|
|
static void increment_timedlock(void)
|
|
{
|
|
rt_task_drop_privilege();
|
|
for (unsigned i = 0; i < ITERATIONS; ++i)
|
|
{
|
|
while (!rt_mutex_timedlock(&mutex, 1))
|
|
{
|
|
}
|
|
++x;
|
|
rt_mutex_unlock(&mutex);
|
|
}
|
|
trap_last();
|
|
}
|
|
|
|
static void timeout(void)
|
|
{
|
|
rt_task_sleep(1000);
|
|
rt_assert(false, "timed out");
|
|
}
|
|
|
|
RT_TASK(increment_lock, RT_STACK_MIN, 1);
|
|
RT_TASK(increment_trylock, RT_STACK_MIN, 1);
|
|
RT_TASK(increment_timedlock, RT_STACK_MIN, 1);
|
|
RT_TASK(timeout, RT_STACK_MIN, 2);
|