2014-04-09 13:24:55 +00:00
|
|
|
/*
|
|
|
|
* \brief Virtualbox adjusted pthread_create implementation
|
|
|
|
* \author Alexander Boettcher
|
|
|
|
* \date 2014-04-09
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2015-06-16 12:53:12 +00:00
|
|
|
* Copyright (C) 2014-2015 Genode Labs GmbH
|
2014-04-09 13:24:55 +00:00
|
|
|
*
|
|
|
|
* This file is distributed under the terms of the GNU General Public License
|
|
|
|
* version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
#include <base/log.h>
|
2014-04-09 13:24:55 +00:00
|
|
|
#include <base/thread.h>
|
|
|
|
#include <base/env.h>
|
2014-05-23 07:26:57 +00:00
|
|
|
#include <cpu_session/connection.h>
|
2014-04-09 13:24:55 +00:00
|
|
|
|
|
|
|
/* Genode libc pthread binding */
|
|
|
|
#include "thread.h"
|
|
|
|
|
2014-07-16 19:43:41 +00:00
|
|
|
#include "sup.h"
|
|
|
|
|
2014-04-09 13:24:55 +00:00
|
|
|
/* libc */
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <errno.h>
|
2015-07-24 16:38:34 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2014-04-09 13:24:55 +00:00
|
|
|
|
|
|
|
/* vbox */
|
|
|
|
#include <internal/thread.h>
|
|
|
|
|
2015-06-16 12:53:12 +00:00
|
|
|
static Genode::Cpu_connection * cpu_connection(RTTHREADTYPE type) {
|
2014-05-23 07:26:57 +00:00
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
static Cpu_connection * con[RTTHREADTYPE_END - 1];
|
|
|
|
static Lock lock;
|
|
|
|
|
|
|
|
Assert(type && type < RTTHREADTYPE_END);
|
|
|
|
|
|
|
|
Lock::Guard guard(lock);
|
|
|
|
|
|
|
|
if (con[type - 1])
|
|
|
|
return con[type - 1];
|
|
|
|
|
2014-12-12 10:27:07 +00:00
|
|
|
unsigned const VIRTUAL_GENODE_VBOX_LEVELS = 16;
|
|
|
|
static_assert (RTTHREADTYPE_END < VIRTUAL_GENODE_VBOX_LEVELS,
|
|
|
|
"prio levels exceeds VIRTUAL_GENODE_VBOX_LEVELS");
|
|
|
|
|
|
|
|
long const prio = (VIRTUAL_GENODE_VBOX_LEVELS - type) *
|
|
|
|
Cpu_session::PRIORITY_LIMIT / VIRTUAL_GENODE_VBOX_LEVELS;
|
2014-05-23 07:26:57 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
char * data = new (env()->heap()) char[16];
|
2014-05-23 07:26:57 +00:00
|
|
|
|
2015-07-24 16:38:34 +00:00
|
|
|
Genode::snprintf(data, 16, "vbox %u", type);
|
2014-05-23 07:26:57 +00:00
|
|
|
|
|
|
|
con[type - 1] = new (env()->heap()) Cpu_connection(data, prio);
|
|
|
|
|
|
|
|
return con[type - 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-16 12:53:12 +00:00
|
|
|
static int create_thread(pthread_t *thread, const pthread_attr_t *attr,
|
|
|
|
void *(*start_routine) (void *), void *arg)
|
2014-09-23 11:01:47 +00:00
|
|
|
{
|
|
|
|
PRTTHREADINT rtthread = reinterpret_cast<PRTTHREADINT>(arg);
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
Assert(rtthread);
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2016-03-08 15:59:43 +00:00
|
|
|
size_t const utcb_size = 4096;
|
|
|
|
|
2016-05-04 10:27:17 +00:00
|
|
|
size_t stack_size = Genode::Thread::stack_virtual_size() -
|
2016-03-08 15:59:43 +00:00
|
|
|
utcb_size - 2 * (1UL << 12);
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
if (rtthread->cbStack < stack_size)
|
|
|
|
stack_size = rtthread->cbStack;
|
|
|
|
else
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
Genode::warning("requested stack for "
|
|
|
|
"thread '", Genode::Cstring(rtthread->szName), "' "
|
|
|
|
"of ", rtthread->cbStack, " Bytes is too large, "
|
|
|
|
"limit to ", stack_size, " Bytes");
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
/* sanity check - emt and vcpu thread have to have same prio class */
|
2015-07-24 16:38:34 +00:00
|
|
|
if (strstr(rtthread->szName, "EMT") == rtthread->szName)
|
2014-09-23 11:01:47 +00:00
|
|
|
Assert(rtthread->enmType == RTTHREADTYPE_EMULATION);
|
2014-05-23 07:26:57 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
if (rtthread->enmType == RTTHREADTYPE_EMULATION) {
|
2015-07-24 16:38:34 +00:00
|
|
|
|
|
|
|
unsigned int cpu_id = 0;
|
|
|
|
sscanf(rtthread->szName, "EMT-%u", &cpu_id);
|
|
|
|
|
2015-06-16 12:53:12 +00:00
|
|
|
Genode::Cpu_session * cpu_session = cpu_connection(RTTHREADTYPE_EMULATION);
|
2015-07-24 16:38:34 +00:00
|
|
|
Genode::Affinity::Space space = cpu_session->affinity_space();
|
|
|
|
Genode::Affinity::Location location(space.location_of_index(cpu_id));
|
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
if (create_emt_vcpu(thread, stack_size, attr, start_routine, arg,
|
2015-07-24 16:38:34 +00:00
|
|
|
cpu_session, location, cpu_id))
|
2014-09-23 11:01:47 +00:00
|
|
|
return 0;
|
2015-06-16 12:53:12 +00:00
|
|
|
/*
|
|
|
|
* The virtualization layer had no need to setup the EMT
|
|
|
|
* specially, so create it as a ordinary pthread.
|
|
|
|
*/
|
2014-09-23 11:01:47 +00:00
|
|
|
}
|
2014-05-23 07:26:57 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
pthread_t thread_obj = new (Genode::env()->heap())
|
|
|
|
pthread(attr ? *attr : 0, start_routine,
|
|
|
|
arg, stack_size, rtthread->szName,
|
2016-04-20 19:12:57 +00:00
|
|
|
cpu_connection(rtthread->enmType),
|
|
|
|
Genode::Affinity::Location());
|
2014-04-24 08:55:09 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
if (!thread_obj)
|
|
|
|
return EAGAIN;
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
*thread = thread_obj;
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
thread_obj->start();
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2014-04-09 13:24:55 +00:00
|
|
|
|
2015-06-16 12:53:12 +00:00
|
|
|
extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
|
|
|
void *(*start_routine) (void *), void *arg)
|
|
|
|
{
|
2015-09-23 10:12:20 +00:00
|
|
|
/* cleanup threads which tried to self-destruct */
|
|
|
|
pthread_cleanup();
|
|
|
|
|
2015-06-16 12:53:12 +00:00
|
|
|
PRTTHREADINT rtthread = reinterpret_cast<PRTTHREADINT>(arg);
|
|
|
|
|
|
|
|
/* retry thread creation once after CPU session upgrade */
|
|
|
|
for (unsigned i = 0; i < 2; i++) {
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
try {
|
|
|
|
return create_thread(thread, attr, start_routine, arg);
|
|
|
|
} catch (Cpu_session::Out_of_metadata) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
log("Upgrading memory for creation of "
|
|
|
|
"thread '", Cstring(rtthread->szName), "'");
|
2015-06-16 12:53:12 +00:00
|
|
|
env()->parent()->upgrade(cpu_connection(rtthread->enmType)->cap(),
|
|
|
|
"ram_quota=4096");
|
|
|
|
} catch (...) { break; }
|
|
|
|
}
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
Genode::error("could not create vbox pthread - halt");
|
2015-06-16 12:53:12 +00:00
|
|
|
Genode::Lock lock(Genode::Lock::LOCKED);
|
|
|
|
lock.lock();
|
|
|
|
return EAGAIN;
|
|
|
|
}
|
|
|
|
|
2014-09-23 11:01:47 +00:00
|
|
|
extern "C" int pthread_attr_setdetachstate(pthread_attr_t *, int)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int pthread_attr_setstacksize(pthread_attr_t *, size_t)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int pthread_atfork(void (*)(void), void (*)(void), void (*)(void))
|
|
|
|
{
|
|
|
|
return 0;
|
2014-04-09 13:24:55 +00:00
|
|
|
}
|