genode/base-hw/src/base/thread_support.cc

92 lines
2.4 KiB
C++
Raw Normal View History

/**
* \brief Platform specific parts of the thread API
* \author Martin Stein
* \date 2012-02-12
*/
/*
2013-01-10 21:44:47 +01:00
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/thread.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/env.h>
using namespace Genode;
namespace Genode { Rm_session * env_context_area_rm_session(); }
/*****************
** Thread_base **
*****************/
Native_utcb * Thread_base::utcb()
{
if (this) { return &_context->utcb; }
return main_thread_utcb();
}
void Thread_base::_thread_start()
{
Thread_base::myself()->_thread_bootstrap();
Thread_base::myself()->entry();
Thread_base::myself()->_join_lock.unlock();
Genode::sleep_forever();
}
void Thread_base::_deinit_platform_thread()
2012-10-09 15:41:40 +02:00
{
/* detach userland thread-context */
2012-10-09 15:41:40 +02:00
size_t const size = sizeof(_context->utcb);
addr_t utcb = Context_allocator::addr_to_base(_context) +
Native_config::context_virtual_size() - size -
Native_config::context_area_virtual_base();
env_context_area_rm_session()->detach(utcb);
/* destroy server object */
2012-10-09 15:41:40 +02:00
env()->cpu_session()->kill_thread(_thread_cap);
if (_pager_cap.valid()) {
env()->rm_session()->remove_client(_pager_cap);
}
2012-10-09 15:41:40 +02:00
}
void Thread_base::start()
{
/* assign thread to protection domain */
env()->pd_session()->bind_thread(_thread_cap);
/* create pager object and assign it to the thread */
_pager_cap = env()->rm_session()->add_client(_thread_cap);
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
/* attach userland thread-context */
try {
Ram_dataspace_capability ds = env()->cpu_session()->utcb(_thread_cap);
size_t const size = sizeof(_context->utcb);
addr_t dst = Context_allocator::addr_to_base(_context) +
Native_config::context_virtual_size() - size -
Native_config::context_area_virtual_base();
env_context_area_rm_session()->attach_at(ds, dst, size);
} catch (...) {
PERR("failed to attach userland thread-context");
sleep_forever();
}
/* start thread with its initial IP and aligned SP */
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, _context->stack_top());
}
void Thread_base::cancel_blocking()
{
env()->cpu_session()->cancel_blocking(_thread_cap);
}