fbe9d26c47
Previously, the trace control of a thread was initialized in its constructor (which is generic for all components). This has the disadvantage that the CPU-session-pointer member of the thread might not be valid at this point. And it cannot be replaced by using the "deprecated_env" CPU session neither as constructing the deprecated environment in causes troubles in Core. But as the trace control shouldn't be needed in Core anyway, the initialization can be moved to the Thread::start implementation of non-core components. This code already takes care of the CPU session pointer. Fixes #2901
88 lines
1.8 KiB
C++
88 lines
1.8 KiB
C++
/*
|
|
* \brief Implementation of the Thread API
|
|
* \author Norman Feske
|
|
* \date 2010-01-19
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2010-2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/thread.h>
|
|
#include <base/log.h>
|
|
#include <base/sleep.h>
|
|
#include <base/env.h>
|
|
#include <cpu_thread/client.h>
|
|
|
|
/* base-internal includes */
|
|
#include <base/internal/stack.h>
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
/**
|
|
* Entry point entered by new threads
|
|
*/
|
|
void Thread::_thread_start()
|
|
{
|
|
Thread::myself()->_thread_bootstrap();
|
|
|
|
/* catch any exception at this point and try to print an error message */
|
|
try {
|
|
Thread::myself()->entry();
|
|
} catch (...) {
|
|
try {
|
|
raw("Thread '", Thread::myself()->name().string(),
|
|
"' died because of an uncaught exception");
|
|
} catch (...) {
|
|
/* die in a noisy way */
|
|
*(unsigned long *)0 = 0xdead;
|
|
}
|
|
throw;
|
|
}
|
|
|
|
Thread::myself()->_join_lock.unlock();
|
|
|
|
/* sleep silently */
|
|
Genode::sleep_forever();
|
|
}
|
|
|
|
|
|
/************
|
|
** Thread **
|
|
************/
|
|
|
|
void Thread::_deinit_platform_thread()
|
|
{
|
|
if (!_cpu_session)
|
|
_cpu_session = env_deprecated()->cpu_session();
|
|
|
|
_cpu_session->kill_thread(_thread_cap);
|
|
}
|
|
|
|
|
|
void Thread::start()
|
|
{
|
|
_init_cpu_session_and_trace_control();
|
|
|
|
/* create thread at core */
|
|
addr_t const utcb = (addr_t)&_stack->utcb();
|
|
_thread_cap = _cpu_session->create_thread(env_deprecated()->pd_session_cap(), name(),
|
|
_affinity, Weight(), utcb);
|
|
if (!_thread_cap.valid())
|
|
throw Cpu_session::Thread_creation_failed();
|
|
|
|
/* start execution at initial instruction pointer and stack pointer */
|
|
Cpu_thread_client(_thread_cap).start((addr_t)_thread_start, _stack->top());
|
|
}
|
|
|
|
|
|
void Thread::cancel_blocking()
|
|
{
|
|
Cpu_thread_client(_thread_cap).cancel_blocking();
|
|
}
|