diff --git a/base-linux/include/base/platform_env.h b/base-linux/include/base/platform_env.h
index 54a02b64c1..de5e0975f9 100644
--- a/base-linux/include/base/platform_env.h
+++ b/base-linux/include/base/platform_env.h
@@ -27,7 +27,7 @@
#include
#include
#include
-#include
+#include
#include
namespace Genode {
@@ -341,7 +341,7 @@ namespace Genode {
Ram_session_capability _ram_session_cap;
Expanding_ram_session_client _ram_session_client;
Cpu_session_capability _cpu_session_cap;
- Cpu_session_client _cpu_session_client;
+ Linux_cpu_session_client _cpu_session_client;
Rm_session_mmap _rm_session_mmap;
Pd_session_client _pd_session_client;
Heap _heap;
@@ -357,7 +357,7 @@ namespace Genode {
_ram_session_cap(static_cap_cast(parent()->session("Env::ram_session", ""))),
_ram_session_client(_ram_session_cap),
_cpu_session_cap(static_cap_cast(parent()->session("Env::cpu_session", ""))),
- _cpu_session_client(_cpu_session_cap),
+ _cpu_session_client(static_cap_cast(parent()->session("Env::cpu_session", ""))),
_rm_session_mmap(false),
_pd_session_client(static_cap_cast(parent()->session("Env::pd_session", ""))),
_heap(&_ram_session_client, &_rm_session_mmap)
@@ -386,9 +386,9 @@ namespace Genode {
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
Rm_session *rm_session() { return &_rm_session_mmap; }
Heap *heap() { return &_heap; }
- Cpu_session *cpu_session() { return &_cpu_session_client; }
+ Linux_cpu_session *cpu_session() { return &_cpu_session_client; }
Cpu_session_capability cpu_session_cap() { return _cpu_session_cap; }
- Pd_session *pd_session() { return 0; }
+ Pd_session *pd_session() { return &_pd_session_client; }
};
}
diff --git a/base-linux/include/linux_cpu_session/client.h b/base-linux/include/linux_cpu_session/client.h
new file mode 100644
index 0000000000..d3f3f7920f
--- /dev/null
+++ b/base-linux/include/linux_cpu_session/client.h
@@ -0,0 +1,82 @@
+/*
+ * \brief Client-side CPU session interface
+ * \author Norman Feske
+ * \date 2012-08-09
+ */
+
+/*
+ * Copyright (C) 2006-2012 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.
+ */
+
+#ifndef _INCLUDE__LINUX_CPU_SESSION__CLIENT_H_
+#define _INCLUDE__LINUX_CPU_SESSION__CLIENT_H_
+
+#include
+#include
+
+namespace Genode {
+
+ struct Linux_cpu_session_client : Rpc_client
+ {
+ explicit Linux_cpu_session_client(Capability session)
+ : Rpc_client(session) { }
+
+ Thread_capability create_thread(Name const &name, addr_t utcb = 0) {
+ return call(name, utcb); }
+
+ Ram_dataspace_capability utcb(Thread_capability thread) {
+ return call(thread); }
+
+ void kill_thread(Thread_capability thread) {
+ call(thread); }
+
+ int set_pager(Thread_capability thread, Pager_capability pager) {
+ return call(thread, pager); }
+
+ int start(Thread_capability thread, addr_t ip, addr_t sp) {
+ return call(thread, ip, sp); }
+
+ void pause(Thread_capability thread) {
+ call(thread); }
+
+ void resume(Thread_capability thread) {
+ call(thread); }
+
+ void cancel_blocking(Thread_capability thread) {
+ call(thread); }
+
+ int state(Thread_capability thread, Thread_state *dst_state) {
+ return call(thread, dst_state); }
+
+ void exception_handler(Thread_capability thread, Signal_context_capability handler) {
+ call(thread, handler); }
+
+ void single_step(Thread_capability thread, bool enable) {
+ call(thread, enable); }
+
+ unsigned num_cpus() const {
+ return call(); }
+
+ void affinity(Thread_capability thread, unsigned cpu) {
+ call(thread, cpu); }
+
+
+ /*****************************
+ * Linux-specific extension **
+ *****************************/
+
+ void thread_id(Thread_capability thread, int pid, int tid) {
+ call(thread, pid, tid); }
+
+ Untyped_capability server_sd(Thread_capability thread) {
+ return call(thread); }
+
+ Untyped_capability client_sd(Thread_capability thread) {
+ return call(thread); }
+ };
+}
+
+#endif /* _INCLUDE__CPU_SESSION__CLIENT_H_ */
diff --git a/base-linux/include/linux_cpu_session/linux_cpu_session.h b/base-linux/include/linux_cpu_session/linux_cpu_session.h
new file mode 100644
index 0000000000..653350d18f
--- /dev/null
+++ b/base-linux/include/linux_cpu_session/linux_cpu_session.h
@@ -0,0 +1,70 @@
+/*
+ * \brief Linux-specific extension of the CPU session interface
+ * \author Norman Feske
+ * \date 2012-08-09
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _INCLUDE__LINUX_CPU_SESSION__LINUX_CPU_SESSION_H_
+#define _INCLUDE__LINUX_CPU_SESSION__LINUX_CPU_SESSION_H_
+
+#include
+
+namespace Genode {
+
+ struct Linux_cpu_session : Cpu_session
+ {
+ virtual ~Linux_cpu_session() { }
+
+ /**
+ * Register Linux PID and TID of the specified thread
+ */
+ virtual void thread_id(Thread_capability, int pid, int tid) = 0;
+
+ /*
+ * If a thread plays the role of an entrypoint, core creates a bound
+ * socket pair for the thread and passes both makes the socket
+ * descriptors of both ends available to the owner of the thread's
+ * CPU session via the 'server_sd' and 'client_sd' function.
+ */
+
+ /**
+ * Request server-side socket descriptor
+ *
+ * The socket descriptor returned by this function is meant to be used
+ * exclusively by the server for receiving incoming requests. It should
+ * never leave the server process.
+ */
+ virtual Untyped_capability server_sd(Thread_capability thread) = 0;
+
+ /**
+ * Request client-side socket descriptor
+ *
+ * The returned socket descriptor enables a client to send messages to
+ * the thread. It is already connected to the 'server_sd' descriptor.
+ * In contrast to 'server_sd', the 'client_sd' is expected to be passed
+ * around via capability delegations.
+ */
+ virtual Untyped_capability client_sd(Thread_capability thread) = 0;
+
+
+ /*********************
+ ** RPC declaration **
+ *********************/
+
+ GENODE_RPC(Rpc_thread_id, void, thread_id, Thread_capability, int, int);
+ GENODE_RPC(Rpc_server_sd, Untyped_capability, server_sd, Thread_capability);
+ GENODE_RPC(Rpc_client_sd, Untyped_capability, client_sd, Thread_capability);
+
+ GENODE_RPC_INTERFACE_INHERIT(Cpu_session,
+ Rpc_thread_id, Rpc_server_sd, Rpc_client_sd);
+ };
+}
+
+#endif /* _INCLUDE__LINUX_CPU_SESSION__LINUX_CPU_SESSION_H_ */
diff --git a/base-linux/src/base/env/platform_env.cc b/base-linux/src/base/env/platform_env.cc
index 4b0f588574..54df826436 100644
--- a/base-linux/src/base/env/platform_env.cc
+++ b/base-linux/src/base/env/platform_env.cc
@@ -13,6 +13,7 @@
#include
#include
+#include
using namespace Genode;
@@ -95,3 +96,36 @@ unsigned long Platform_env::_get_env_ulong(const char *key)
return 0;
}
+
+
+/*****************************
+ ** Support for IPC library **
+ *****************************/
+
+namespace Genode {
+
+ Native_connection_state server_socket_pair()
+ {
+ /*
+ * Obtain access to Linux-specific extension of the CPU session
+ * interface. We can cast to the specific type because the Linux
+ * version of 'Platform_env' is hosting a 'Linux_cpu_client' object.
+ */
+ Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session());
+
+ if (!cpu) {
+ PERR("could not obtain Linux extension to CPU session interface");
+ struct Could_not_access_linux_cpu_session { };
+ throw Could_not_access_linux_cpu_session();
+ }
+
+ Native_connection_state ncs;
+
+ Thread_base *thread = Thread_base::myself();
+ if (thread) {
+ ncs.server_sd = cpu->server_sd(thread->cap()).dst().socket;
+ ncs.client_sd = cpu->client_sd(thread->cap()).dst().socket;
+ }
+ return ncs;
+ }
+}
diff --git a/base-linux/src/base/ipc/ipc.cc b/base-linux/src/base/ipc/ipc.cc
index 8c3e037e7d..ba1e01a0c3 100644
--- a/base-linux/src/base/ipc/ipc.cc
+++ b/base-linux/src/base/ipc/ipc.cc
@@ -31,13 +31,10 @@
#include
#include
#include
+#include
+#include
/* Linux includes */
-#include
-#include
-#include
-#include
-
#include
#include
@@ -219,6 +216,20 @@ void Ipc_server::_reply_wait()
}
+namespace Genode {
+
+ /*
+ * Helper for obtaining a bound and connected socket pair
+ *
+ * For core, the implementation is just a wrapper around
+ * 'lx_server_socket_pair()'. For all other processes, the implementation
+ * requests the socket pair from the Env::CPU session interface using a
+ * Linux-specific interface extension.
+ */
+ Native_connection_state server_socket_pair();
+}
+
+
Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
:
Ipc_istream(rcv_msg),
@@ -238,10 +249,10 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
throw Ipc_server_multiple_instance();
}
- _rcv_cs = lx_server_socket_pair(Thread_base::myself());
-
- if (thread)
+ if (thread) {
+ _rcv_cs = server_socket_pair();
thread->tid().is_ipc_server = true;
+ }
/* override capability initialization performed by 'Ipc_istream' */
*static_cast(this) =
diff --git a/base-linux/src/base/thread/thread_linux.cc b/base-linux/src/base/thread/thread_linux.cc
index e02f579092..5625c3b5f9 100644
--- a/base-linux/src/base/thread/thread_linux.cc
+++ b/base-linux/src/base/thread/thread_linux.cc
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
/* Linux syscall bindings */
#include
@@ -50,7 +51,10 @@ static void thread_start(void *)
}
-void Thread_base::_init_platform_thread() { }
+void Thread_base::_init_platform_thread()
+{
+ _thread_cap = env()->cpu_session()->create_thread(_context->name);
+}
void Thread_base::_deinit_platform_thread()
@@ -103,14 +107,10 @@ void Thread_base::start()
_tid.tid = lx_create_thread(thread_start, thread_sp, this);
_tid.pid = lx_getpid();
- /*
- * Inform core about the new thread by calling create_thread and encoding
- * the thread's PID in the thread-name argument.
- */
- char name_and_pid[Cpu_session::THREAD_NAME_LEN + 2*16];
- snprintf(name_and_pid, sizeof(name_and_pid), "%s:0x%x:0x%x",
- _context->name, _tid.tid, _tid.pid);
- _thread_cap = env()->cpu_session()->create_thread(name_and_pid);
+ /* inform core about the new thread and process ID of the new thread */
+ Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session());
+ if (cpu)
+ cpu->thread_id(_thread_cap, _tid.pid, _tid.tid);
}
diff --git a/base-linux/src/core/cpu_session_extension.cc b/base-linux/src/core/cpu_session_extension.cc
new file mode 100644
index 0000000000..22f8d21552
--- /dev/null
+++ b/base-linux/src/core/cpu_session_extension.cc
@@ -0,0 +1,52 @@
+/*
+ * \brief Linux-specific extension of the CPU session implementation
+ * \author Norman Feske
+ * \date 2012-08-09
+ */
+
+/* core includes */
+#include
+
+/* Linux includes */
+#include
+
+using namespace Genode;
+
+
+void Cpu_session_component::thread_id(Thread_capability thread_cap, int pid, int tid)
+{
+ Lock::Guard lock_guard(_thread_list_lock);
+
+ Cpu_thread_component *thread = _lookup_thread(thread_cap);
+ if (!thread) return;
+
+ thread->platform_thread()->thread_id(pid, tid);
+}
+
+
+Untyped_capability Cpu_session_component::server_sd(Thread_capability thread_cap)
+{
+ Lock::Guard lock_guard(_thread_list_lock);
+
+ Cpu_thread_component *thread = _lookup_thread(thread_cap);
+ if (!thread) return Untyped_capability();
+
+ enum { DUMMY_LOCAL_NAME = 0 };
+ typedef Native_capability::Dst Dst;
+ return Untyped_capability(Dst(thread->platform_thread()->server_sd()),
+ DUMMY_LOCAL_NAME);
+}
+
+
+Untyped_capability Cpu_session_component::client_sd(Thread_capability thread_cap)
+{
+ Lock::Guard lock_guard(_thread_list_lock);
+
+ Cpu_thread_component *thread = _lookup_thread(thread_cap);
+ if (!thread) return Untyped_capability();
+
+ enum { DUMMY_LOCAL_NAME = 0 };
+ typedef Native_capability::Dst Dst;
+ return Untyped_capability(Dst(thread->platform_thread()->client_sd()),
+ DUMMY_LOCAL_NAME);
+}
diff --git a/base-linux/src/core/include/cpu_session_component.h b/base-linux/src/core/include/cpu_session_component.h
new file mode 100644
index 0000000000..03c533006e
--- /dev/null
+++ b/base-linux/src/core/include/cpu_session_component.h
@@ -0,0 +1,152 @@
+/*
+ * \brief Core-specific instance of the CPU session/thread interfaces
+ * \author Christian Helmuth
+ * \author Norman Feske
+ * \date 2006-07-17
+ */
+
+/*
+ * Copyright (C) 2006-2012 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.
+ */
+
+#ifndef _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_
+#define _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* core includes */
+#include
+#include
+
+namespace Genode {
+
+ /**
+ * RPC interface of CPU thread
+ *
+ * We make 'Cpu_thread' a RPC object only to be able to lookup CPU threads
+ * from thread capabilities supplied as arguments to CPU-session functions.
+ * A CPU thread does not provide an actual RPC interface.
+ */
+ struct Cpu_thread
+ {
+ GENODE_RPC_INTERFACE();
+ };
+
+
+ class Cpu_thread_component : public Rpc_object,
+ public List::Element
+ {
+ private:
+
+ Platform_thread _platform_thread;
+
+ bool _bound; /* pd binding flag */
+
+ public:
+
+ Cpu_thread_component(const char *name, unsigned priority,
+ addr_t utcb)
+ : _platform_thread(name, priority, utcb), _bound(false) { }
+
+
+ /************************
+ ** Accessor functions **
+ ************************/
+
+ inline Platform_thread * platform_thread() { return &_platform_thread; }
+ inline bool bound() const { return _bound; }
+ inline void bound(bool b) { _bound = b; }
+ };
+
+
+ class Cpu_session_component : public Rpc_object
+ {
+ private:
+
+ Rpc_entrypoint *_thread_ep;
+ Pager_entrypoint *_pager_ep;
+ Allocator_guard _md_alloc; /* guarded meta-data allocator */
+ Cpu_thread_allocator _thread_alloc; /* meta-data allocator */
+ Lock _thread_alloc_lock; /* protect allocator access */
+ List _thread_list;
+ Lock _thread_list_lock; /* protect thread list */
+ unsigned _priority; /* priority of threads
+ created with this
+ session */
+
+ /**
+ * Lookup thread in CPU session by its capability
+ *
+ * \retval NULL thread capability is invalid or
+ * does not belong to the CPU session
+ */
+ Cpu_thread_component *_lookup_thread(Thread_capability thread) {
+ return dynamic_cast
+ (_thread_ep->obj_by_cap(thread)); }
+
+ /**
+ * Raw thread-killing functionality
+ *
+ * This function is called from the 'kill_thread' function and
+ * the destructor. Each these functions grab the list lock
+ * by themselves and call this function to perform the actual
+ * killing.
+ */
+ void _unsynchronized_kill_thread(Cpu_thread_component *thread);
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Cpu_session_component(Rpc_entrypoint *thread_ep,
+ Pager_entrypoint *pager_ep,
+ Allocator *md_alloc, const char *args);
+
+ /**
+ * Destructor
+ */
+ ~Cpu_session_component();
+
+
+ /***************************
+ ** CPU session interface **
+ ***************************/
+
+ Thread_capability create_thread(Name const &, addr_t utcb);
+ Ram_dataspace_capability utcb(Thread_capability thread);
+ void kill_thread(Thread_capability);
+ Thread_capability first();
+ Thread_capability next(Thread_capability);
+ int set_pager(Thread_capability, Pager_capability);
+ int start(Thread_capability, addr_t, addr_t);
+ void pause(Thread_capability thread_cap);
+ void resume(Thread_capability thread_cap);
+ void cancel_blocking(Thread_capability);
+ int name(Thread_capability, char *, size_t);
+ int state(Thread_capability, Thread_state *);
+ void exception_handler(Thread_capability, Signal_context_capability);
+ unsigned num_cpus() const;
+ void affinity(Thread_capability, unsigned);
+
+
+ /*******************************
+ ** Linux-specific extensions **
+ *******************************/
+
+ void thread_id(Thread_capability, int, int);
+ Untyped_capability server_sd(Thread_capability);
+ Untyped_capability client_sd(Thread_capability);
+ };
+}
+
+#endif /* _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_ */
diff --git a/base-linux/src/core/include/platform_thread.h b/base-linux/src/core/include/platform_thread.h
index ab9e10e25b..f729934ce8 100644
--- a/base-linux/src/core/include/platform_thread.h
+++ b/base-linux/src/core/include/platform_thread.h
@@ -29,6 +29,11 @@ namespace Genode {
unsigned long _pid;
char _name[32];
+ /**
+ * Unix-domain socket pair bound to the thread
+ */
+ Native_connection_state _ncs;
+
public:
/**
@@ -60,6 +65,24 @@ namespace Genode {
int state(Thread_state *state_dst) { return 0; }
const char *name() { return _name; }
void affinity(unsigned) { }
+
+ /**
+ * Register process ID and thread ID of thread
+ */
+ void thread_id(int pid, int tid) { _pid = pid, _tid = tid; }
+
+ /**
+ * Return client-side socket descriptor
+ *
+ * For more information, please refer to the comments in
+ * 'linux_cpu_session/linux_cpu_session.h'.
+ */
+ int client_sd();
+
+ /**
+ * Return server-side socket descriptor
+ */
+ int server_sd();
};
}
diff --git a/base-linux/src/core/platform.cc b/base-linux/src/core/platform.cc
index 5e3f8ca57e..cd4e7ff20d 100644
--- a/base-linux/src/core/platform.cc
+++ b/base-linux/src/core/platform.cc
@@ -19,6 +19,7 @@
#include "core_env.h"
/* Linux includes */
+#include
#include
#include
@@ -60,3 +61,17 @@ void Core_parent::exit(int exit_value)
{
lx_exit_group(exit_value);
}
+
+
+/*****************************
+ ** Support for IPC library **
+ *****************************/
+
+namespace Genode {
+
+ Native_connection_state server_socket_pair()
+ {
+ return lx_server_socket_pair(Thread_base::myself()->tid().tid);
+ }
+}
+
diff --git a/base-linux/src/core/platform_thread.cc b/base-linux/src/core/platform_thread.cc
index 1807aac0fe..a4c61ecbb5 100644
--- a/base-linux/src/core/platform_thread.cc
+++ b/base-linux/src/core/platform_thread.cc
@@ -21,6 +21,7 @@
/* Linux syscall helper */
#include
+#include
using namespace Genode;
@@ -29,41 +30,9 @@ typedef Token Tid_token;
Platform_thread::Platform_thread(const char *name, unsigned, addr_t)
+: _tid(-1), _pid(-1)
{
- /* search for thread-id portion of thread name */
- Tid_token tok(name);
- while (tok.type() != Tid_token::END && tok[0] != ':')
- tok = tok.next();
-
- /* tok points at the colon separator, next token is the id */
- tok = tok.next();
-
- if (tok.type() == Tid_token::END) {
- PWRN("Invalid format of thread name.");
- return;
- }
-
- /* convert string to thread id */
- ascii_to(tok.start(), &_tid);
-
- /* search for process-id portion of thread name */
- while (tok.type() != Tid_token::END && tok[0] != ':')
- tok = tok.next();
-
- /* tok points at the colon separator, next token is the id */
- tok = tok.next();
-
- if (tok.type() == Tid_token::END) {
- PWRN("Invalid format of thread name.");
- return;
- }
-
- /* convert string to process id */
- ascii_to(tok.start(), &_pid);
-
- /* initialize private members */
- size_t name_len = tok.start() - name;
- strncpy(_name, name, min(sizeof(_name), name_len));
+ strncpy(_name, name, min(sizeof(_name), strlen(name)));
}
@@ -84,3 +53,20 @@ void Platform_thread::resume()
{
PDBG("not implemented");
}
+
+
+int Platform_thread::client_sd()
+{
+ /* construct socket pair on first call */
+ if (_ncs.client_sd == -1)
+ _ncs = lx_server_socket_pair(_tid);
+
+ return _ncs.client_sd;
+}
+
+
+int Platform_thread::server_sd()
+{
+ client_sd();
+ return _ncs.server_sd;
+}
diff --git a/base-linux/src/core/target.mk b/base-linux/src/core/target.mk
index 13a7feb0d4..9a972a3117 100644
--- a/base-linux/src/core/target.mk
+++ b/base-linux/src/core/target.mk
@@ -12,6 +12,7 @@ SRC_CC = main.cc \
ram_session_support.cc \
rom_session_component.cc \
cpu_session_component.cc \
+ cpu_session_extension.cc \
cpu_session_support.cc \
pd_session_component.cc \
io_mem_session_component.cc \
diff --git a/base-linux/src/platform/linux_socket.h b/base-linux/src/platform/linux_socket.h
index 735eaf6f61..99086cd1a6 100644
--- a/base-linux/src/platform/linux_socket.h
+++ b/base-linux/src/platform/linux_socket.h
@@ -24,6 +24,13 @@
#include
#include
+/* Linux includes */
+#include
+#include
+#include
+#include
+
+/* Genode bindings to Linux kernel */
#include
#include
@@ -342,7 +349,7 @@ class Connect_failed { };
* \throw Bind_failed
* \throw Connect_failed
*/
-static Genode::Native_connection_state lx_server_socket_pair(Genode::Thread_base *thread)
+static inline Genode::Native_connection_state lx_server_socket_pair(long thread_id)
{
Genode::Native_connection_state ncs;
@@ -350,10 +357,10 @@ static Genode::Native_connection_state lx_server_socket_pair(Genode::Thread_base
* Main thread uses 'Ipc_server' for 'sleep_forever()' only. No need for
* binding.
*/
- if (!thread)
+ if (thread_id == -1)
return ncs;
- Uds_addr addr(thread->tid().tid);
+ Uds_addr addr(thread_id);
/*
* Create server-side socket
@@ -391,6 +398,12 @@ static Genode::Native_connection_state lx_server_socket_pair(Genode::Thread_base
int const tid = lookup_tid_by_client_socket(ncs.client_sd);
Genode::ep_sd_registry()->associate(ncs.client_sd, tid);
+ /*
+ * Wipe Unix domain socket from the file system. It will live as long as
+ * there exist references to it in the form of file descriptors.
+ */
+ lx_unlink(addr.sun_path);
+
return ncs;
}
@@ -398,9 +411,9 @@ static Genode::Native_connection_state lx_server_socket_pair(Genode::Thread_base
/**
* Utility: Send request to server and wait for reply
*/
-static void lx_call(int dst_sd,
- Genode::Msgbuf_base &send_msgbuf, size_t send_msg_len,
- Genode::Msgbuf_base &recv_msgbuf)
+static inline void lx_call(int dst_sd,
+ Genode::Msgbuf_base &send_msgbuf, size_t send_msg_len,
+ Genode::Msgbuf_base &recv_msgbuf)
{
int ret;
Message send_msg(send_msgbuf.buf, send_msg_len);
@@ -426,7 +439,8 @@ static void lx_call(int dst_sd,
ret = lx_sendmsg(dst_sd, send_msg.msg(), 0);
if (ret < 0) {
- PRAW("lx_sendmsg failed with %d in lx_call()", ret);
+ PRAW("[%d] lx_sendmsg to sd %d failed with %d in lx_call()",
+ lx_getpid(), dst_sd, ret);
throw Genode::Ipc_error();
}
@@ -437,7 +451,7 @@ static void lx_call(int dst_sd,
ret = lx_recvmsg(reply_channel[LOCAL_SOCKET], recv_msg.msg(), 0);
if (ret < 0) {
- PRAW("lx_recvmsg failed with %d in lx_call()", ret);
+ PRAW("[%d] lx_recvmsg failed with %d in lx_call()", lx_getpid(), ret);
throw Genode::Ipc_error();
}
@@ -454,8 +468,8 @@ static void lx_call(int dst_sd,
*
* \return socket descriptor of reply capability
*/
-static int lx_wait(Genode::Native_connection_state &cs,
- Genode::Msgbuf_base &recv_msgbuf)
+static inline int lx_wait(Genode::Native_connection_state &cs,
+ Genode::Msgbuf_base &recv_msgbuf)
{
Message msg(recv_msgbuf.buf, recv_msgbuf.size());
@@ -478,9 +492,9 @@ static int lx_wait(Genode::Native_connection_state &cs,
/**
* Utility: Send reply to client
*/
-static void lx_reply(int reply_socket,
- Genode::Msgbuf_base &send_msgbuf,
- size_t msg_len)
+static inline void lx_reply(int reply_socket,
+ Genode::Msgbuf_base &send_msgbuf,
+ size_t msg_len)
{
Message msg(send_msgbuf.buf, msg_len);
diff --git a/base-linux/src/platform/lx_hybrid.cc b/base-linux/src/platform/lx_hybrid.cc
index 02c1d326a1..d761795e7d 100644
--- a/base-linux/src/platform/lx_hybrid.cc
+++ b/base-linux/src/platform/lx_hybrid.cc
@@ -14,6 +14,7 @@
#include
#include
#include <_main_helper.h>
+#include
extern "C" int raw_write_str(const char *str);
@@ -59,6 +60,7 @@ __attribute__((constructor(101))) void lx_hybrid_init()
char **genode_argv = 0;
int genode_argc = 1;
+
/************
** Thread **
************/
@@ -159,6 +161,23 @@ namespace Genode {
static void empty_signal_handler(int) { }
+/**
+ * Return Linux-specific extension of the Env::CPU session interface
+ */
+Linux_cpu_session *cpu_session()
+{
+ Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session());
+
+ if (!cpu) {
+ PERR("could not obtain Linux extension to CPU session interface");
+ struct Could_not_access_linux_cpu_session { };
+ throw Could_not_access_linux_cpu_session();
+ }
+
+ return cpu;
+}
+
+
static void adopt_thread(Thread_meta_data *meta_data)
{
/*
@@ -277,6 +296,17 @@ Thread_base::Thread_base(const char *name, size_t stack_size)
}
_tid.meta_data->construct_lock.lock();
+
+ Linux_cpu_session *cpu = dynamic_cast(env()->cpu_session());
+
+ if (!cpu) {
+ PERR("could not obtain Linux extension to CPU session interface");
+ struct Could_not_access_linux_cpu_session { };
+ throw Could_not_access_linux_cpu_session();
+ }
+
+ _thread_cap = cpu_session()->create_thread(name);
+ cpu_session()->thread_id(_thread_cap, _tid.pid, _tid.tid);
}
@@ -305,4 +335,7 @@ Thread_base::~Thread_base()
destroy(env()->heap(), _tid.meta_data);
_tid.meta_data = 0;
+
+ /* inform core about the killed thread */
+ cpu_session()->kill_thread(_thread_cap);
}
diff --git a/base/src/base/thread/thread.cc b/base/src/base/thread/thread.cc
index bcb6665e86..d8fa548605 100644
--- a/base/src/base/thread/thread.cc
+++ b/base/src/base/thread/thread.cc
@@ -143,10 +143,8 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
ds_cap = env_context_area_ram_session()->alloc(ds_size);
addr_t attach_addr = ds_addr - Native_config::context_area_virtual_base();
env_context_area_rm_session()->attach_at(ds_cap, attach_addr, ds_size);
-
- } catch (Ram_session::Alloc_failed) {
- throw Stack_alloc_failed();
}
+ catch (Ram_session::Alloc_failed) { throw Stack_alloc_failed(); }
/*
* Now the thread context is backed by memory, so it is safe to access its