2012-05-30 18:13:09 +00:00
|
|
|
/**
|
|
|
|
* \brief Platform specific parts of the thread API
|
|
|
|
* \author Martin Stein
|
|
|
|
* \date 2012-02-12
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2012-2013 Genode Labs GmbH
|
2012-05-30 18:13:09 +00:00
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
|
2013-11-19 14:13:24 +00:00
|
|
|
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*****************
|
|
|
|
** Thread_base **
|
|
|
|
*****************/
|
|
|
|
|
2013-11-19 14:13:24 +00:00
|
|
|
void Thread_base::_init_platform_thread() { }
|
|
|
|
|
|
|
|
|
2012-05-30 18:13:09 +00:00
|
|
|
Native_utcb * Thread_base::utcb()
|
|
|
|
{
|
2013-11-19 14:13:24 +00:00
|
|
|
if (this) { return &_context->utcb; }
|
2013-11-23 01:30:24 +00:00
|
|
|
return main_thread_utcb();
|
2012-05-30 18:13:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Thread_base::_thread_start()
|
|
|
|
{
|
|
|
|
Thread_base::myself()->_thread_bootstrap();
|
|
|
|
Thread_base::myself()->entry();
|
2012-11-16 12:53:37 +00:00
|
|
|
Thread_base::myself()->_join_lock.unlock();
|
2012-05-30 18:13:09 +00:00
|
|
|
Genode::sleep_forever();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Thread_base::_deinit_platform_thread()
|
2012-10-09 13:41:40 +00:00
|
|
|
{
|
2013-11-19 14:13:24 +00:00
|
|
|
/* detach userland thread-context */
|
2012-10-09 13:41:40 +00: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);
|
|
|
|
|
2013-11-19 14:13:24 +00:00
|
|
|
/* destroy server object */
|
2012-10-09 13:41:40 +00:00
|
|
|
env()->cpu_session()->kill_thread(_thread_cap);
|
2013-09-18 21:40:38 +00:00
|
|
|
if (_pager_cap.valid()) {
|
|
|
|
env()->rm_session()->remove_client(_pager_cap);
|
|
|
|
}
|
2012-10-09 13:41:40 +00:00
|
|
|
}
|
2012-05-30 18:13:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
void Thread_base::start()
|
|
|
|
{
|
2013-11-19 14:13:24 +00:00
|
|
|
/* create server object */
|
2012-05-30 18:13:09 +00:00
|
|
|
char buf[48];
|
|
|
|
name(buf, sizeof(buf));
|
|
|
|
Cpu_session * cpu = env()->cpu_session();
|
|
|
|
_thread_cap = cpu->create_thread(buf, (addr_t)&_context->utcb);
|
|
|
|
|
|
|
|
/* assign thread to protection domain */
|
|
|
|
env()->pd_session()->bind_thread(_thread_cap);
|
|
|
|
|
2013-11-19 14:13:24 +00:00
|
|
|
/* create pager object and assign it to the thread */
|
2013-01-18 08:38:19 +00:00
|
|
|
_pager_cap = env()->rm_session()->add_client(_thread_cap);
|
|
|
|
env()->cpu_session()->set_pager(_thread_cap, _pager_cap);
|
2012-05-30 18:13:09 +00:00
|
|
|
|
2013-11-19 14:13:24 +00:00
|
|
|
/* attach userland thread-context */
|
2012-05-30 18:13:09 +00:00
|
|
|
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) +
|
2012-08-29 12:42:56 +00:00
|
|
|
Native_config::context_virtual_size() - size -
|
|
|
|
Native_config::context_area_virtual_base();
|
2012-05-30 18:13:09 +00:00
|
|
|
env_context_area_rm_session()->attach_at(ds, dst, size);
|
|
|
|
} catch (...) {
|
2013-11-19 14:13:24 +00:00
|
|
|
PERR("failed to attach userland thread-context");
|
2012-05-30 18:13:09 +00:00
|
|
|
sleep_forever();
|
|
|
|
}
|
|
|
|
/* start thread with its initial IP and aligned SP */
|
|
|
|
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
|
|
|
thread_sp &= ~0xf;
|
|
|
|
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-18 21:40:38 +00:00
|
|
|
void Thread_base::cancel_blocking()
|
|
|
|
{
|
|
|
|
env()->cpu_session()->cancel_blocking(_thread_cap);
|
|
|
|
}
|