rt/cxx/examples/mutex.cpp

75 lines
1.5 KiB
C++

#include <rt/mutex.hpp>
#include <rt/sem.hpp>
#include <rt/task.hpp>
#include <rt/trap.hpp>
#include <rt/assert.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 (!trap_sem.trywait())
{
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::lock_guard lock(mutex);
++x;
}
trap_last();
}
static void increment_trylock(void)
{
rt::task::drop_privilege();
for (unsigned i = 0; i < ITERATIONS; ++i)
{
while (!mutex.trylock())
{
rt::task::sleep(1);
}
rt::lock_guard lock(mutex, rt::adopt_lock);
++x;
}
trap_last();
}
static void increment_timedlock(void)
{
rt::task::drop_privilege();
for (unsigned i = 0; i < ITERATIONS; ++i)
{
while (!mutex.timedlock(1))
{
}
rt::lock_guard lock(mutex, rt::adopt_lock);
++x;
}
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);