/* * \brief Core-specific instance of the CPU session/thread interfaces * \author Christian Helmuth * \date 2006-07-17 */ /* * Copyright (C) 2006-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. */ #ifndef _CPU_SESSION_COMPONENT_H_ #define _CPU_SESSION_COMPONENT_H_ /* Genode includes */ #include #include #include #include #include #include #include #include #include /* GDB monitor includes */ #include "append_list.h" #include "genode_child_resources.h" namespace Gdb_monitor { using namespace Genode; class Cpu_session_component; class Cpu_thread_component; class Local_cpu_factory; typedef Local_service Cpu_service; } class Gdb_monitor::Cpu_session_component : public Rpc_object { private: Env &_env; Parent::Client _parent_client; Id_space::Element const _id_space_element { _parent_client, _env.id_space() }; Rpc_entrypoint &_ep; Allocator &_md_alloc; Pd_session_capability _core_pd; struct Expanding_parent_cpu_session : Cpu_session_client { Cpu_session_component &_component; Expanding_parent_cpu_session(Cpu_session_capability cap, Cpu_session_component &component) : Cpu_session_client(cap), _component(component) { } Thread_capability create_thread(Capability pd, Cpu_session::Name const &name, Affinity::Location affinity, Weight weight, addr_t utcb) override { enum { UPGRADE_ATTEMPTS = ~0U }; return Genode::retry( [&] () { return Genode::retry( [&] () { return Cpu_session_client::create_thread(pd, name, affinity, weight, utcb); }, [&] () { _component._env.upgrade(_component._id_space_element.id(), "cap_quota=3"); }, UPGRADE_ATTEMPTS); }, [&] () { _component._env.upgrade(_component._id_space_element.id(), "ram_quota=8K"); }, UPGRADE_ATTEMPTS); } }; Expanding_parent_cpu_session _parent_cpu_session; Entrypoint &_signal_ep; int const _new_thread_pipe_write_end; int const _breakpoint_len; unsigned char const *_breakpoint_data; Append_list _thread_list; bool _stop_new_threads = true; Lock _stop_new_threads_lock; Capability _native_cpu_cap; Capability _setup_native_cpu(); void _cleanup_native_cpu(); public: /** * Constructor */ Cpu_session_component(Env &env, Rpc_entrypoint &ep, Allocator &md_alloc, Pd_session_capability core_pd, Entrypoint &signal_ep, const char *args, Affinity const &affinity, int const new_thread_pipe_write_end, int const breakpoint_len, unsigned char const *breakpoint_data); /** * Destructor */ ~Cpu_session_component(); Cpu_session &parent_cpu_session(); Rpc_entrypoint &thread_ep(); Entrypoint &signal_ep(); Thread_capability thread_cap(unsigned long lwpid); unsigned long lwpid(Thread_capability thread_cap); Cpu_thread_component *lookup_cpu_thread(unsigned long lwpid); Cpu_thread_component *lookup_cpu_thread(Thread_capability thread_cap); int signal_pipe_read_fd(Thread_capability thread_cap); int send_signal(Thread_capability thread_cap, int signo); void handle_unresolved_page_fault(); void stop_new_threads(bool stop); bool stop_new_threads(); Lock &stop_new_threads_lock(); int handle_initial_breakpoint(unsigned long lwpid); void pause_all_threads(); void resume_all_threads(); Thread_capability first(); Thread_capability next(Thread_capability); /*************************** ** CPU session interface ** ***************************/ Thread_capability create_thread(Capability, Name const &, Affinity::Location, Weight, addr_t) override; void kill_thread(Thread_capability) override; void exception_sigh(Signal_context_capability handler) override; Affinity::Space affinity_space() const override; Dataspace_capability trace_control() override; int ref_account(Cpu_session_capability c) override; int transfer_quota(Cpu_session_capability c, size_t q) override; Quota quota() override; Capability native_cpu() override; }; class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory { private: Env &_env; Rpc_entrypoint &_ep; Allocator &_md_alloc; Pd_session_capability _core_pd; Entrypoint &_signal_ep; int const _new_thread_pipe_write_end; int const _breakpoint_len; unsigned char const *_breakpoint_data; Genode_child_resources *_genode_child_resources; public: Local_cpu_factory(Env &env, Rpc_entrypoint &ep, Allocator &md_alloc, Pd_session_capability core_pd, Entrypoint &signal_ep, int new_thread_pipe_write_end, int const breakpoint_len, unsigned char const *breakpoint_data, Genode_child_resources *genode_child_resources) : _env(env), _ep(ep), _md_alloc(md_alloc), _core_pd(core_pd), _signal_ep(signal_ep), _new_thread_pipe_write_end(new_thread_pipe_write_end), _breakpoint_len(breakpoint_len), _breakpoint_data(breakpoint_data), _genode_child_resources(genode_child_resources) { } /*********************** ** Factory interface ** ***********************/ Cpu_session_component &create(Args const &args, Affinity affinity) override { Cpu_session_component *cpu_session_component = new (_md_alloc) Cpu_session_component(_env, _ep, _md_alloc, _core_pd, _signal_ep, args.string(), affinity, _new_thread_pipe_write_end, _breakpoint_len, _breakpoint_data); _genode_child_resources->cpu_session_component(cpu_session_component); return *cpu_session_component; } void upgrade(Cpu_session_component &, Args const &) override { } void destroy(Cpu_session_component &session) override { Genode::destroy(_md_alloc, &session); } }; #endif /* _CPU_SESSION_COMPONENT_H_ */