diff --git a/ports/src/virtualbox/target.mk b/ports/src/virtualbox/target.mk index afc65a6bb..9154e8013 100644 --- a/ports/src/virtualbox/target.mk +++ b/ports/src/virtualbox/target.mk @@ -5,7 +5,7 @@ include $(REP_DIR)/lib/mk/virtualbox-common.inc TARGET = virtualbox SRC_CC = main.cc cxx_dummies.cc devices.cc drivers.cc dummies.cc libc.cc \ logger.cc mm.cc pdm.cc pgm.cc rt.cc sup.cc iommio.cc ioport.cc \ - hwaccm.cc + hwaccm.cc thread.cc LIBS += base LIBS += config_args @@ -16,6 +16,7 @@ LIBS += virtualbox-bios virtualbox-recompiler virtualbox-runtime \ virtualbox-hwaccl virtualbox-dis INC_DIR += $(call select_from_repositories,src/lib/libc) +INC_DIR += $(call select_from_repositories,src/lib/pthread) INC_DIR += $(VBOX_DIR)/Runtime/include INC_DIR += $(VBOX_DIR)/Frontends/VBoxBFE diff --git a/ports/src/virtualbox/thread.cc b/ports/src/virtualbox/thread.cc new file mode 100644 index 000000000..b6bdb6702 --- /dev/null +++ b/ports/src/virtualbox/thread.cc @@ -0,0 +1,61 @@ +/* + * \brief Virtualbox adjusted pthread_create implementation + * \author Alexander Boettcher + * \date 2014-04-09 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is distributed under the terms of the GNU General Public License + * version 2. + */ + +/* Genode */ +#include +#include +#include + +/* Genode libc pthread binding */ +#include "thread.h" + +/* libc */ +#include +#include + +/* vbox */ +#include + +extern "C" { + + int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg) + { + PRTTHREADINT rtthread = reinterpret_cast(arg); + + Assert(rtthread); + + size_t stack_size = Genode::Native_config::context_virtual_size() - + sizeof(Genode::Native_utcb) - 2 * (1UL << 12); + + if (rtthread->cbStack < stack_size) + stack_size = rtthread->cbStack; + else + PWRN("requested stack for thread '%s' of %zu Bytes is too large, " + "limit to %zu Bytes", rtthread->szName, rtthread->cbStack, + stack_size); + + pthread_t thread_obj = new (Genode::env()->heap()) + pthread(attr ? *attr : 0, start_routine, + arg, stack_size, rtthread->szName, nullptr); + + if (!thread_obj) + return EAGAIN; + + *thread = thread_obj; + + thread_obj->start(); + + return 0; + } +}