mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 20:42:56 +01:00
Merge final fixes from internal repositories
This commit is contained in:
committed by
Christian Helmuth
parent
6ce4e47c1c
commit
d1891e8a27
6
base-linux/src/base/env/rm_session_mmap.cc
vendored
6
base-linux/src/base/env/rm_session_mmap.cc
vendored
@@ -19,7 +19,7 @@
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static size_t dataspace_size(Dataspace_capability ds)
|
||||
static Genode::size_t dataspace_size(Dataspace_capability ds)
|
||||
{
|
||||
if (ds.valid())
|
||||
return Dataspace_client(ds).size();
|
||||
@@ -42,8 +42,8 @@ static bool is_sub_rm_session(Dataspace_capability ds)
|
||||
}
|
||||
|
||||
|
||||
static void *map_local(Dataspace_capability ds, size_t size, addr_t offset,
|
||||
bool use_local_addr, addr_t local_addr)
|
||||
static void *map_local(Dataspace_capability ds, Genode::size_t size,
|
||||
addr_t offset, bool use_local_addr, addr_t local_addr)
|
||||
{
|
||||
Linux_dataspace::Filename fname = Linux_dataspace_client(ds).fname();
|
||||
fname.buf[sizeof(fname.buf) - 1] = 0;
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
TARGET = core
|
||||
REQUIRES = linux
|
||||
LIBS = cxx ipc heap core_printf process lock raw_server syscall rpath
|
||||
TARGET = core
|
||||
REQUIRES = linux
|
||||
LIBS = cxx ipc heap core_printf process lock raw_server syscall rpath
|
||||
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
|
||||
SRC_CC = main.cc \
|
||||
platform.cc \
|
||||
platform_thread.cc \
|
||||
ram_session_component.cc \
|
||||
ram_session_support.cc \
|
||||
rom_session_component.cc \
|
||||
cpu_session_component.cc \
|
||||
pd_session_component.cc \
|
||||
io_mem_session_component.cc \
|
||||
io_port_session_component.cc \
|
||||
signal_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
thread.cc \
|
||||
thread_linux.cc \
|
||||
context_area.cc \
|
||||
debug.cc
|
||||
SRC_CC = main.cc \
|
||||
platform.cc \
|
||||
platform_thread.cc \
|
||||
ram_session_component.cc \
|
||||
ram_session_support.cc \
|
||||
rom_session_component.cc \
|
||||
cpu_session_component.cc \
|
||||
pd_session_component.cc \
|
||||
io_mem_session_component.cc \
|
||||
io_port_session_component.cc \
|
||||
signal_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
thread.cc \
|
||||
thread_linux.cc \
|
||||
context_area.cc \
|
||||
debug.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(GEN_CORE_DIR)/include \
|
||||
$(REP_DIR)/src/platform \
|
||||
/usr/include
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(GEN_CORE_DIR)/include \
|
||||
$(REP_DIR)/src/platform
|
||||
|
||||
HOST_INC_DIR += /usr/include
|
||||
|
||||
vpath main.cc $(GEN_CORE_DIR)
|
||||
vpath thread.cc $(BASE_DIR)/src/base/thread
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
__attribute__((weak)) char **lx_environ = (char **)0;
|
||||
|
||||
|
||||
static void main_thread_bootstrap()
|
||||
static inline void main_thread_bootstrap()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@ extern char **lx_environ;
|
||||
*/
|
||||
__attribute__((constructor(101))) void lx_hybrid_init()
|
||||
{
|
||||
main_thread_bootstrap();
|
||||
lx_environ = environ;
|
||||
}
|
||||
|
||||
@@ -77,6 +76,7 @@ __attribute__((constructor(101))) void lx_hybrid_init()
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <pthread.h>
|
||||
@@ -149,7 +149,7 @@ namespace Genode {
|
||||
static void empty_signal_handler(int) { }
|
||||
|
||||
|
||||
static void *thread_start(void *arg)
|
||||
static void adopt_thread(Thread_meta_data *meta_data)
|
||||
{
|
||||
/*
|
||||
* Set signal handler such that canceled system calls get not
|
||||
@@ -158,7 +158,7 @@ static void *thread_start(void *arg)
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
|
||||
/* assign 'Thread_meta_data' pointer to TLS entry */
|
||||
pthread_setspecific(tls_key(), arg);
|
||||
pthread_setspecific(tls_key(), meta_data);
|
||||
|
||||
/* enable immediate cancellation when calling 'pthread_cancel' */
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
|
||||
@@ -166,9 +166,17 @@ static void *thread_start(void *arg)
|
||||
/*
|
||||
* Initialize thread meta data
|
||||
*/
|
||||
Native_thread &native_thread = meta_data->thread_base->tid();
|
||||
native_thread.tid = lx_gettid();
|
||||
native_thread.pid = lx_getpid();
|
||||
}
|
||||
|
||||
|
||||
static void *thread_start(void *arg)
|
||||
{
|
||||
Thread_meta_data *meta_data = (Thread_meta_data *)arg;
|
||||
meta_data->thread_base->tid().tid = lx_gettid();
|
||||
meta_data->thread_base->tid().pid = lx_getpid();
|
||||
|
||||
adopt_thread(meta_data);
|
||||
|
||||
/* unblock 'Thread_base' constructor */
|
||||
meta_data->construct_lock.unlock();
|
||||
@@ -181,13 +189,52 @@ static void *thread_start(void *arg)
|
||||
}
|
||||
|
||||
|
||||
extern "C" void *malloc(::size_t size);
|
||||
|
||||
|
||||
Thread_base *Thread_base::myself()
|
||||
{
|
||||
void *tls = pthread_getspecific(tls_key());
|
||||
void * const tls = pthread_getspecific(tls_key());
|
||||
|
||||
bool const is_main_thread = (tls == 0);
|
||||
if (tls != 0)
|
||||
return ((Thread_meta_data *)tls)->thread_base;
|
||||
|
||||
return is_main_thread ? 0 : ((Thread_meta_data *)tls)->thread_base;
|
||||
bool const is_main_thread = (lx_getpid() == lx_gettid());
|
||||
if (is_main_thread)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The function was called from a thread created by other means than
|
||||
* Genode's thread API. This may happen if a native Linux library creates
|
||||
* threads via the pthread library. If such a thread calls Genode code,
|
||||
* which then tries to perform IPC, the program fails because there exists
|
||||
* no 'Thread_base' object. We recover from this unfortunate situation by
|
||||
* creating a dummy 'Thread_base' object and associate it with the calling
|
||||
* thread.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create dummy 'Thread_base' object but suppress the execution of its
|
||||
* constructor. If we called the constructor, we would create a new Genode
|
||||
* thread, which is not what we want. For the allocation, we use glibc
|
||||
* malloc because 'Genode::env()->heap()->alloc()' uses IPC.
|
||||
*
|
||||
* XXX Both the 'Thread_base' and 'Threadm_meta_data' objects are never
|
||||
* freed.
|
||||
*/
|
||||
Thread_base *thread = (Thread_base *)malloc(sizeof(Thread_base));
|
||||
memset(thread, 0, sizeof(*thread));
|
||||
Thread_meta_data *meta_data = new Thread_meta_data(thread);
|
||||
|
||||
/*
|
||||
* Initialize 'Thread_base::_tid' using the default constructor of
|
||||
* 'Native_thread'. This marks the client and server sockets as
|
||||
* uninitialized and prompts the IPC framework to create those as needed.
|
||||
*/
|
||||
meta_data->thread_base->tid() = Native_thread();
|
||||
adopt_thread(meta_data);
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
@@ -203,14 +250,14 @@ void Thread_base::start()
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
: _list_element(this)
|
||||
{
|
||||
_tid.meta_data = new Thread_meta_data(this);
|
||||
_tid.meta_data = new (env()->heap()) Thread_meta_data(this);
|
||||
|
||||
int const ret = pthread_create(&_tid.meta_data->pt, 0, thread_start,
|
||||
_tid.meta_data);
|
||||
if (ret) {
|
||||
PERR("pthread_create failed (returned %d, errno=%d)",
|
||||
ret, errno);
|
||||
delete _tid.meta_data;
|
||||
destroy(env()->heap(), _tid.meta_data);
|
||||
throw Context_alloc_failed();
|
||||
}
|
||||
|
||||
@@ -241,6 +288,6 @@ Thread_base::~Thread_base()
|
||||
ret, errno);
|
||||
}
|
||||
|
||||
delete _tid.meta_data;
|
||||
destroy(env()->heap(), _tid.meta_data);
|
||||
_tid.meta_data = 0;
|
||||
}
|
||||
|
||||
62
base-linux/src/test/lx_hybrid_pthread_ipc/main.cc
Normal file
62
base-linux/src/test/lx_hybrid_pthread_ipc/main.cc
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* \brief Test for performing IPC from a pthread created outside of Genode
|
||||
* \author Norman Feske
|
||||
* \date 2011-12-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011 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/thread.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
static Genode::Lock *main_wait_lock()
|
||||
{
|
||||
static Genode::Lock inst(Genode::Lock::LOCKED);
|
||||
return &inst;
|
||||
}
|
||||
|
||||
|
||||
static void *pthread_entry(void *)
|
||||
{
|
||||
PINF("first message");
|
||||
|
||||
/*
|
||||
* Without the lazy initialization of 'Thread_base' objects for threads
|
||||
* created w/o Genode's Thread API, the printing of the first message will
|
||||
* never return because the IPC reply could not be delivered.
|
||||
*
|
||||
* With the on-demand creation of 'Thread_base' objects, the second message
|
||||
* will appear in the LOG output.
|
||||
*/
|
||||
|
||||
PINF("second message");
|
||||
|
||||
main_wait_lock()->unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
Genode::printf("--- pthread IPC test ---\n");
|
||||
|
||||
/* create thread w/o Genode's thread API */
|
||||
pthread_t pth;
|
||||
pthread_create(&pth, 0, pthread_entry, 0);
|
||||
|
||||
/* wait until 'pthread_entry' finished */
|
||||
main_wait_lock()->lock();
|
||||
|
||||
Genode::printf("--- finished pthread IPC test ---\n");
|
||||
return 0;
|
||||
}
|
||||
3
base-linux/src/test/lx_hybrid_pthread_ipc/target.mk
Normal file
3
base-linux/src/test/lx_hybrid_pthread_ipc/target.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
TARGET = test-lx_hybrid_pthread_ipc
|
||||
SRC_CC = main.c
|
||||
LIBS = env cxx thread lx_hybrid
|
||||
Reference in New Issue
Block a user