parent
ca2871e2e4
commit
8102b78d22
|
@ -333,6 +333,97 @@ static void test_create_as_many_threads(Env &env)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************
|
||||||
|
** Using Locks in creative ways *
|
||||||
|
*********************************/
|
||||||
|
|
||||||
|
struct Lock_helper : Thread
|
||||||
|
{
|
||||||
|
enum { STACK_SIZE = 0x1000 };
|
||||||
|
|
||||||
|
Lock &lock;
|
||||||
|
bool &lock_is_free;
|
||||||
|
bool unlock;
|
||||||
|
|
||||||
|
Lock_helper(Env &env, const char * name, Cpu_session &cpu, Lock &lock,
|
||||||
|
bool &lock_is_free, bool unlock = false)
|
||||||
|
:
|
||||||
|
Thread(env, name, STACK_SIZE, Thread::Location(), Thread::Weight(),
|
||||||
|
cpu),
|
||||||
|
lock(lock), lock_is_free(lock_is_free), unlock(unlock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void entry()
|
||||||
|
{
|
||||||
|
log(" thread '", name(), "' started");
|
||||||
|
|
||||||
|
if (unlock)
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
if (!lock_is_free) {
|
||||||
|
log(" thread '", name(), "' got lock but somebody else is within"
|
||||||
|
" critical section !?");
|
||||||
|
throw -22;
|
||||||
|
}
|
||||||
|
|
||||||
|
log(" thread '", name(), "' done");
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_locks(Genode::Env &env)
|
||||||
|
{
|
||||||
|
Lock lock (Lock::LOCKED);
|
||||||
|
|
||||||
|
bool lock_is_free = true;
|
||||||
|
|
||||||
|
Cpu_connection cpu_m(env, "prio middle", Cpu_session::PRIORITY_LIMIT / 4);
|
||||||
|
Cpu_connection cpu_l(env, "prio low", Cpu_session::PRIORITY_LIMIT / 2);
|
||||||
|
|
||||||
|
enum { SYNC_STARTUP = true };
|
||||||
|
|
||||||
|
Lock_helper l1(env, "lock_low1", cpu_l, lock, lock_is_free);
|
||||||
|
Lock_helper l2(env, "lock_low2", cpu_l, lock, lock_is_free);
|
||||||
|
Lock_helper l3(env, "lock_low3", cpu_l, lock, lock_is_free);
|
||||||
|
Lock_helper l4(env, "lock_low4", cpu_l, lock, lock_is_free, SYNC_STARTUP);
|
||||||
|
|
||||||
|
l1.start();
|
||||||
|
l2.start();
|
||||||
|
l3.start();
|
||||||
|
l4.start();
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
log(" thread '", Thread::myself()->name(), "' - I'm the lock holder - "
|
||||||
|
"take lock again");
|
||||||
|
|
||||||
|
/* we are within the critical section - lock is not free */
|
||||||
|
lock_is_free = false;
|
||||||
|
|
||||||
|
/* start another low prio thread to wake current thread when it blocks */
|
||||||
|
Lock_helper l5(env, "lock_low5", cpu_l, lock, lock_is_free, SYNC_STARTUP);
|
||||||
|
l5.start();
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
log(" I'm the lock holder - still alive");
|
||||||
|
lock_is_free = true;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
/* check that really all threads come back ! */
|
||||||
|
l1.join();
|
||||||
|
l2.join();
|
||||||
|
l3.join();
|
||||||
|
l4.join();
|
||||||
|
l5.join();
|
||||||
|
|
||||||
|
log("running '", __func__, "' done");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Component::construct(Env &env)
|
void Component::construct(Env &env)
|
||||||
{
|
{
|
||||||
log("--- thread test started ---");
|
log("--- thread test started ---");
|
||||||
|
@ -344,6 +435,7 @@ void Component::construct(Env &env)
|
||||||
test_stack_alignment(env);
|
test_stack_alignment(env);
|
||||||
test_main_thread();
|
test_main_thread();
|
||||||
test_cpu_session(env);
|
test_cpu_session(env);
|
||||||
|
test_locks(env);
|
||||||
|
|
||||||
if (config.xml().has_sub_node("pause_resume"))
|
if (config.xml().has_sub_node("pause_resume"))
|
||||||
test_pause_resume(env);
|
test_pause_resume(env);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user