genode/repos/ports/src/app/gdb_monitor/cpu_session_component.cc
Norman Feske a99989af40 Separation of thread operations from CPU session
This patch moves the thread operations from the 'Cpu_session'
to the 'Cpu_thread' interface.

A noteworthy semantic change is the meaning of the former
'exception_handler' function, which used to define both, the default
exception handler or a thread-specific signal handler. Now, the
'Cpu_session::exception_sigh' function defines the CPU-session-wide
default handler whereas the 'Cpu_thread::exception_sigh' function
defines the thread-specific one.

To retain the ability to create 'Child' objects without invoking a
capability, the child's initial thread must be created outside the
'Child::Process'. It is now represented by the 'Child::Initial_thread',
which is passed as argument to the 'Child' constructor.

Fixes #1939
2016-05-23 15:52:39 +02:00

250 lines
6.0 KiB
C++

/*
* \brief Implementation of the CPU session interface
* \author Christian Prochaska
* \date 2011-04-28
*/
/*
* Copyright (C) 2011-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/env.h>
#include <base/printf.h>
#include <cpu_session_component.h>
#include <util/list.h>
/* GDB monitor includes */
#include "config.h"
extern void genode_add_thread(unsigned long lwpid);
extern void genode_remove_thread(unsigned long lwpid);
using namespace Genode;
using namespace Gdb_monitor;
/* FIXME: use an allocator */
static unsigned long new_lwpid = GENODE_LWP_BASE;
Thread_info *Cpu_session_component::_thread_info(Thread_capability thread_cap)
{
Thread_info *thread_info = _thread_list.first();
while (thread_info) {
if (thread_info->thread_cap().local_name() == thread_cap.local_name()) {
return thread_info;
break;
}
thread_info = thread_info->next();
}
return 0;
}
unsigned long Cpu_session_component::lwpid(Thread_capability thread_cap)
{
return _thread_info(thread_cap)->lwpid();
}
Thread_capability Cpu_session_component::thread_cap(unsigned long lwpid)
{
Thread_info *thread_info = _thread_list.first();
while (thread_info) {
if (thread_info->lwpid() == lwpid) {
return thread_info->thread_cap();
}
thread_info = thread_info->next();
}
return Thread_capability();
}
Thread_capability
Cpu_session_component::create_thread(Capability<Pd_session> pd,
Name const &name,
Affinity::Location location,
Weight weight,
addr_t utcb)
{
Thread_capability thread_cap =
_parent_cpu_session.create_thread(pd, name, location, weight, utcb);
if (thread_cap.valid()) {
Thread_info *thread_info = new (env()->heap()) Thread_info(thread_cap, new_lwpid++);
_thread_list.append(thread_info);
}
return thread_cap;
}
//Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread)
//{
// return _parent_cpu_session.utcb(thread);
//}
void Cpu_session_component::kill_thread(Thread_capability thread_cap)
{
Thread_info *thread_info = _thread_info(thread_cap);
if (thread_info) {
_exception_signal_receiver->dissolve(thread_info);
genode_remove_thread(thread_info->lwpid());
_thread_list.remove(thread_info);
destroy(env()->heap(), thread_info);
}
_parent_cpu_session.kill_thread(thread_cap);
}
Thread_capability Cpu_session_component::first()
{
Thread_info *thread_info = _thread_list.first();
if (thread_info)
return thread_info->thread_cap();
else
return Thread_capability();
}
Thread_capability Cpu_session_component::next(Thread_capability thread_cap)
{
Thread_info *next_thread_info = _thread_info(thread_cap)->next();
if (next_thread_info)
return next_thread_info->thread_cap();
else
return Thread_capability();
}
//int Cpu_session_component::start(Thread_capability thread_cap,
// addr_t ip, addr_t sp)
//{
// Thread_info *thread_info = _thread_info(thread_cap);
//
// if (thread_info)
// exception_handler(thread_cap, _exception_signal_receiver->manage(thread_info));
//
// int result = _parent_cpu_session.start(thread_cap, ip, sp);
//
// if (thread_info) {
// /* pause the first thread */
// if (thread_info->lwpid() == GENODE_LWP_BASE)
// pause(thread_cap);
//
// genode_add_thread(thread_info->lwpid());
// }
//
// return result;
//}
//void Cpu_session_component::pause(Thread_capability thread_cap)
//{
// _parent_cpu_session.pause(thread_cap);
//}
//void Cpu_session_component::resume(Thread_capability thread_cap)
//{
// _parent_cpu_session.resume(thread_cap);
//}
//void Cpu_session_component::cancel_blocking(Thread_capability thread_cap)
//{
// _parent_cpu_session.cancel_blocking(thread_cap);
//}
//void Cpu_session_component::state(Thread_capability thread_cap,
// Thread_state const &state)
//{
// _parent_cpu_session.state(thread_cap, state);
//}
//Thread_state Cpu_session_component::state(Thread_capability thread_cap)
//{
// return _parent_cpu_session.state(thread_cap);
//}
void Cpu_session_component::exception_sigh(Signal_context_capability sigh_cap)
{
_parent_cpu_session.exception_sigh(sigh_cap);
}
//void Cpu_session_component::single_step(Thread_capability thread_cap, bool enable)
//{
// _parent_cpu_session.single_step(thread_cap, enable);
//}
Affinity::Space Cpu_session_component::affinity_space() const
{
return _parent_cpu_session.affinity_space();
}
//void Cpu_session_component::affinity(Thread_capability thread_cap,
// Affinity::Location location)
//{
// _parent_cpu_session.affinity(thread_cap, location);
//}
Dataspace_capability Cpu_session_component::trace_control()
{
return _parent_cpu_session.trace_control();
}
//unsigned Cpu_session_component::trace_control_index(Thread_capability thread)
//{
// return _parent_cpu_session.trace_control_index(thread);
//}
//Dataspace_capability Cpu_session_component::trace_buffer(Thread_capability thread)
//{
// return _parent_cpu_session.trace_buffer(thread);
//}
//Dataspace_capability Cpu_session_component::trace_policy(Thread_capability thread)
//{
// return _parent_cpu_session.trace_policy(thread);
//}
Capability<Cpu_session::Native_cpu> Cpu_session_component::native_cpu()
{
return _parent_cpu_session.native_cpu();
}
Cpu_session_component::Cpu_session_component(Signal_receiver *exception_signal_receiver, const char *args)
: _parent_cpu_session(env()->parent()->session<Cpu_session>(args)),
_exception_signal_receiver(exception_signal_receiver)
{
}
Cpu_session_component::~Cpu_session_component()
{
}
int Cpu_session_component::ref_account(Cpu_session_capability) { return -1; }
int Cpu_session_component::transfer_quota(Cpu_session_capability, size_t) { return -1; }
Cpu_session::Quota Cpu_session_component::quota() { return Quota(); }