libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
/*
|
|
|
|
* \brief Libc kernel for main and pthreads user contexts
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \author Emery Hemingway
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2016-01-22
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2016-2019 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* libc-internal includes */
|
|
|
|
#include <internal/kernel.h>
|
|
|
|
|
|
|
|
Libc::Kernel * Libc::Kernel::_kernel_ptr;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main context execution was suspended (on fork)
|
|
|
|
*
|
|
|
|
* This function is executed in the context of the initial thread.
|
|
|
|
*/
|
|
|
|
static void suspended_callback()
|
|
|
|
{
|
|
|
|
Libc::Kernel::kernel().entrypoint_suspended();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Resume main context execution (after fork)
|
|
|
|
*
|
|
|
|
* This function is executed in the context of the initial thread.
|
|
|
|
*/
|
|
|
|
static void resumed_callback()
|
|
|
|
{
|
|
|
|
Libc::Kernel::kernel().entrypoint_resumed();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t Libc::Kernel::_user_stack_size()
|
|
|
|
{
|
|
|
|
size_t size = Component::stack_size();
|
|
|
|
if (!_cloned)
|
|
|
|
return size;
|
|
|
|
|
|
|
|
_libc_env.libc_config().with_sub_node("stack", [&] (Xml_node stack) {
|
|
|
|
size = stack.attribute_value("size", 0UL); });
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Libc::Kernel::schedule_suspend(void(*original_suspended_callback) ())
|
|
|
|
{
|
|
|
|
if (_state != USER) {
|
2019-09-19 20:37:17 +02:00
|
|
|
error(__PRETTY_FUNCTION__, " called from non-user context");
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We hook into suspend-resume callback chain to destruct and
|
|
|
|
* reconstruct parts of the kernel from the context of the initial
|
|
|
|
* thread, i.e., without holding any object locks.
|
|
|
|
*/
|
|
|
|
_original_suspended_callback = original_suspended_callback;
|
|
|
|
_env.ep().schedule_suspend(suspended_callback, resumed_callback);
|
|
|
|
|
|
|
|
if (!_setjmp(_user_context)) {
|
|
|
|
_valid_user_context = true;
|
|
|
|
_suspend_scheduled = true;
|
|
|
|
_switch_to_kernel();
|
|
|
|
} else {
|
|
|
|
_valid_user_context = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Libc::Kernel::reset_malloc_heap()
|
|
|
|
{
|
|
|
|
_malloc_ram.construct(_heap, _env.ram());
|
|
|
|
|
|
|
|
_cloned_heap_ranges.for_each([&] (Registered<Cloned_malloc_heap_range> &r) {
|
|
|
|
destroy(_heap, &r); });
|
|
|
|
|
|
|
|
Heap &raw_malloc_heap = *_malloc_heap;
|
2019-09-19 20:37:17 +02:00
|
|
|
construct_at<Heap>(&raw_malloc_heap, *_malloc_ram, _env.rm());
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
reinit_malloc(raw_malloc_heap);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Libc::Kernel::_init_file_descriptors()
|
|
|
|
{
|
2019-09-19 20:37:17 +02:00
|
|
|
auto init_fd = [&] (Xml_node const &node, char const *attr,
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
int libc_fd, unsigned flags)
|
|
|
|
{
|
|
|
|
if (!node.has_attribute(attr))
|
|
|
|
return;
|
|
|
|
|
2019-09-19 20:37:17 +02:00
|
|
|
typedef String<Vfs::MAX_PATH_LEN> Path;
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
Path const path = node.attribute_value(attr, Path());
|
|
|
|
|
|
|
|
struct stat out_stat { };
|
|
|
|
if (stat(path.string(), &out_stat) != 0)
|
|
|
|
return;
|
|
|
|
|
2019-09-19 20:37:17 +02:00
|
|
|
File_descriptor *fd = _vfs.open(path.string(), flags, libc_fd);
|
2019-11-03 11:53:13 +01:00
|
|
|
if (!fd)
|
|
|
|
return;
|
|
|
|
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
if (fd->libc_fd != libc_fd) {
|
2019-09-19 20:37:17 +02:00
|
|
|
error("could not allocate fd ",libc_fd," for ",path,", "
|
|
|
|
"got fd ",fd->libc_fd);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
_vfs.close(fd);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We need to manually register the path. Normally this is done
|
|
|
|
* by '_open'. But we call the local 'open' function directly
|
|
|
|
* because we want to explicitly specify the libc fd ID.
|
|
|
|
*/
|
|
|
|
if (fd->fd_path)
|
2019-09-19 20:37:17 +02:00
|
|
|
warning("may leak former FD path memory");
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
{
|
|
|
|
char *dst = (char *)_heap.alloc(path.length());
|
|
|
|
Genode::strncpy(dst, path.string(), path.length());
|
|
|
|
fd->fd_path = dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
::off_t const seek = node.attribute_value("seek", 0ULL);
|
|
|
|
if (seek)
|
|
|
|
_vfs.lseek(fd, seek, SEEK_SET);
|
|
|
|
};
|
|
|
|
|
|
|
|
if (_vfs.root_dir_has_dirents()) {
|
|
|
|
|
|
|
|
Xml_node const node = _libc_env.libc_config();
|
|
|
|
|
2019-09-19 20:37:17 +02:00
|
|
|
typedef String<Vfs::MAX_PATH_LEN> Path;
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
if (node.has_attribute("cwd"))
|
|
|
|
chdir(node.attribute_value("cwd", Path()).string());
|
|
|
|
|
|
|
|
init_fd(node, "stdin", 0, O_RDONLY);
|
|
|
|
init_fd(node, "stdout", 1, O_WRONLY);
|
|
|
|
init_fd(node, "stderr", 2, O_WRONLY);
|
|
|
|
|
|
|
|
node.for_each_sub_node("fd", [&] (Xml_node fd) {
|
|
|
|
|
|
|
|
unsigned const id = fd.attribute_value("id", 0U);
|
|
|
|
|
|
|
|
bool const rd = fd.attribute_value("readable", false);
|
|
|
|
bool const wr = fd.attribute_value("writeable", false);
|
|
|
|
|
|
|
|
unsigned const flags = rd ? (wr ? O_RDWR : O_RDONLY)
|
|
|
|
: (wr ? O_WRONLY : 0);
|
|
|
|
|
|
|
|
if (!fd.has_attribute("path"))
|
|
|
|
warning("Invalid <fd> node, 'path' attribute is missing");
|
|
|
|
|
|
|
|
init_fd(fd, "path", id, flags);
|
|
|
|
});
|
|
|
|
|
|
|
|
/* prevent use of IDs of stdin, stdout, and stderr for other files */
|
|
|
|
for (unsigned fd = 0; fd <= 2; fd++)
|
2019-09-19 20:37:17 +02:00
|
|
|
file_descriptor_allocator()->preserve(fd);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
}
|
2019-10-11 15:23:22 +02:00
|
|
|
|
2019-10-30 21:19:11 +01:00
|
|
|
/**
|
|
|
|
* Call 'fn' with root directory and path to ioctl pseudo file as arguments
|
|
|
|
*
|
|
|
|
* If no matching ioctl pseudo file exists, 'fn' is not called.
|
|
|
|
*/
|
|
|
|
auto with_ioctl_path = [&] (File_descriptor const *fd, char const *file, auto fn)
|
|
|
|
{
|
|
|
|
if (!fd || !fd->fd_path)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Absolute_path const ioctl_dir = Vfs_plugin::ioctl_dir(*fd);
|
|
|
|
Absolute_path path = ioctl_dir;
|
|
|
|
path.append_element(file);
|
|
|
|
|
|
|
|
_vfs.with_root_dir([&] (Directory &root_dir) {
|
|
|
|
if (root_dir.file_exists(path.string()))
|
|
|
|
fn(root_dir, path.string()); });
|
|
|
|
};
|
|
|
|
|
2019-10-11 15:23:22 +02:00
|
|
|
/*
|
2019-10-30 21:19:11 +01:00
|
|
|
* Watch stdout's 'info' pseudo file to detect terminal-resize events
|
2019-10-11 15:23:22 +02:00
|
|
|
*/
|
|
|
|
File_descriptor const * const stdout_fd =
|
|
|
|
file_descriptor_allocator()->find_by_libc_fd(STDOUT_FILENO);
|
|
|
|
|
2019-10-30 21:19:11 +01:00
|
|
|
with_ioctl_path(stdout_fd, "info", [&] (Directory &root_dir, char const *path) {
|
|
|
|
_terminal_resize_handler.construct(root_dir, path, *this,
|
|
|
|
&Kernel::_handle_terminal_resize); });
|
2019-10-11 15:23:22 +02:00
|
|
|
|
2019-10-30 21:19:11 +01:00
|
|
|
/*
|
|
|
|
* Watch stdin's 'interrupts' pseudo file to detect control-c events
|
|
|
|
*/
|
|
|
|
File_descriptor const * const stdin_fd =
|
|
|
|
file_descriptor_allocator()->find_by_libc_fd(STDIN_FILENO);
|
|
|
|
|
|
|
|
with_ioctl_path(stdin_fd, "interrupts", [&] (Directory &root_dir, char const *path) {
|
|
|
|
_user_interrupt_handler.construct(root_dir, path,
|
|
|
|
*this, &Kernel::_handle_user_interrupt); });
|
2019-10-11 15:23:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Libc::Kernel::_handle_terminal_resize()
|
|
|
|
{
|
|
|
|
_signal.charge(SIGWINCH);
|
|
|
|
_resume_main();
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-30 21:19:11 +01:00
|
|
|
void Libc::Kernel::_handle_user_interrupt()
|
|
|
|
{
|
|
|
|
_signal.charge(SIGINT);
|
|
|
|
_resume_main();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
void Libc::Kernel::_clone_state_from_parent()
|
|
|
|
{
|
|
|
|
struct Range { void *at; size_t size; };
|
|
|
|
|
|
|
|
auto range_attr = [&] (Xml_node node)
|
|
|
|
{
|
|
|
|
return Range {
|
|
|
|
.at = (void *)node.attribute_value("at", 0UL),
|
|
|
|
.size = node.attribute_value("size", 0UL)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate local memory for the backing store of the application heap,
|
|
|
|
* mirrored from the parent.
|
|
|
|
*
|
|
|
|
* This step must precede the creation of the 'Clone_connection' because
|
|
|
|
* the shared-memory buffer of the clone session may otherwise potentially
|
|
|
|
* interfere with such a heap region.
|
|
|
|
*/
|
|
|
|
_libc_env.libc_config().for_each_sub_node("heap", [&] (Xml_node node) {
|
|
|
|
Range const range = range_attr(node);
|
|
|
|
new (_heap)
|
|
|
|
Registered<Cloned_malloc_heap_range>(_cloned_heap_ranges,
|
|
|
|
_env.ram(), _env.rm(),
|
|
|
|
range.at, range.size); });
|
|
|
|
|
2019-11-03 11:53:13 +01:00
|
|
|
_clone_connection.construct(_env);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
/* fetch heap content */
|
|
|
|
_cloned_heap_ranges.for_each([&] (Cloned_malloc_heap_range &heap_range) {
|
2019-11-03 11:53:13 +01:00
|
|
|
heap_range.import_content(*_clone_connection); });
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
/* fetch user contex of the parent's application */
|
2019-11-03 11:53:13 +01:00
|
|
|
_clone_connection->memory_content(&_user_context, sizeof(_user_context));
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
_valid_user_context = true;
|
|
|
|
|
|
|
|
_libc_env.libc_config().for_each_sub_node([&] (Xml_node node) {
|
|
|
|
|
|
|
|
auto copy_from_parent = [&] (Range range)
|
|
|
|
{
|
2019-11-03 11:53:13 +01:00
|
|
|
_clone_connection->memory_content(range.at, range.size);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* clone application stack */
|
|
|
|
if (node.type() == "stack")
|
|
|
|
copy_from_parent(range_attr(node));
|
|
|
|
|
|
|
|
/* clone RW segment of a shared library or the binary */
|
|
|
|
if (node.type() == "rw") {
|
|
|
|
typedef String<64> Name;
|
|
|
|
Name const name = node.attribute_value("name", Name());
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The blacklisted segments are initialized via the
|
|
|
|
* regular startup of the child.
|
|
|
|
*/
|
|
|
|
bool const blacklisted = (name == "ld.lib.so")
|
|
|
|
|| (name == "libc.lib.so")
|
|
|
|
|| (name == "libm.lib.so")
|
|
|
|
|| (name == "posix.lib.so")
|
|
|
|
|| (strcmp(name.string(), "vfs", 3) == 0);
|
|
|
|
if (!blacklisted)
|
|
|
|
copy_from_parent(range_attr(node));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/* import application-heap state from parent */
|
2019-11-03 11:53:13 +01:00
|
|
|
_clone_connection->object_content(_malloc_heap);
|
|
|
|
init_malloc_cloned(*_clone_connection);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern void (*libc_select_notify)();
|
|
|
|
|
|
|
|
|
|
|
|
void Libc::Kernel::handle_io_progress()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* TODO: make VFS I/O completion checks during
|
|
|
|
* kernel time to avoid flapping between stacks
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (_io_ready) {
|
|
|
|
_io_ready = false;
|
|
|
|
|
|
|
|
/* some contexts may have been deblocked from select() */
|
|
|
|
if (libc_select_notify)
|
|
|
|
libc_select_notify();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* resume all as any VFS context may have
|
|
|
|
* been deblocked from blocking I/O
|
|
|
|
*/
|
|
|
|
Kernel::resume_all();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-19 20:37:17 +02:00
|
|
|
void Libc::execute_in_application_context(Application_code &app_code)
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* The libc execution model builds on the main entrypoint, which handles
|
|
|
|
* all relevant signals (e.g., timing and VFS). Additional component
|
|
|
|
* entrypoints or pthreads should never call with_libc() but we catch this
|
|
|
|
* here and just execute the application code directly.
|
|
|
|
*/
|
|
|
|
if (!Kernel::kernel().main_context()) {
|
|
|
|
app_code.execute();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool nested = false;
|
|
|
|
|
|
|
|
if (nested) {
|
|
|
|
|
|
|
|
if (Kernel::kernel().main_suspended()) {
|
|
|
|
Kernel::kernel().nested_execution(app_code);
|
|
|
|
} else {
|
|
|
|
app_code.execute();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
nested = true;
|
|
|
|
Kernel::kernel().run(app_code);
|
|
|
|
nested = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
|
|
|
|
:
|
|
|
|
_env(env), _heap(heap)
|
|
|
|
{
|
|
|
|
init_pthread_support(env, *this, *this);
|
|
|
|
|
|
|
|
_env.ep().register_io_progress_handler(*this);
|
|
|
|
|
|
|
|
if (_cloned) {
|
|
|
|
_clone_state_from_parent();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
_malloc_heap.construct(*_malloc_ram, _env.rm());
|
|
|
|
init_malloc(*_malloc_heap);
|
|
|
|
}
|
|
|
|
|
2019-10-30 23:08:34 +01:00
|
|
|
init_fork(_env, _libc_env, _heap, *_malloc_heap, _pid, *this, *this, _signal, *this);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
init_execve(_env, _heap, _user_stack, *this);
|
|
|
|
init_plugin(*this);
|
|
|
|
init_sleep(*this);
|
|
|
|
init_vfs_plugin(*this);
|
2019-09-20 16:59:47 +02:00
|
|
|
init_time(*this, _rtc_path, *this);
|
2019-10-29 10:52:49 +01:00
|
|
|
init_select(*this, *this, *this, _signal);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
init_socket_fs(*this);
|
2019-09-20 16:26:52 +02:00
|
|
|
init_passwd(_passwd_config());
|
2019-10-11 15:23:22 +02:00
|
|
|
init_signal(_signal);
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
|
|
|
|
_init_file_descriptors();
|
|
|
|
|
|
|
|
_kernel_ptr = this;
|
2019-11-03 11:53:13 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Acknowledge the completion of 'fork' to the parent
|
|
|
|
*
|
|
|
|
* This must be done after '_init_file_descriptors' to ensure that pipe FDs
|
|
|
|
* of the parent are opened at the child before the parent continues.
|
|
|
|
* Otherwise, the parent would potentially proceed with closing the pipe
|
|
|
|
* FDs before the child has a chance to open them. In this situation, the
|
|
|
|
* pipe reference counter may reach an intermediate value of zero,
|
|
|
|
* triggering the destruction of the pipe.
|
|
|
|
*/
|
|
|
|
if (_cloned)
|
|
|
|
_clone_connection.destruct();
|
libc: split task.cc into multiple files
This patch is the first step of re-organizing the internal structure of
the libc. The original version involved many direct calls of global
functions (often with side effects) across compilation units, which
made the control flow (e.g., the initialization sequence) hard to
follow.
The new version replaces those ad-hoc interactions with dedicated
interfaces (like suspend.h, resume.h, select.h, current_time.h). The
underlying facilities are provided by the central Libc::Kernel and
selectively propagated to the various compilation units. The latter is
done by a sequence of 'init_*' calls, which eventually will be replaced
by constructor calls.
The addition of new headers increases the chance for name clashes with
existing (public) headers. To disambiguate libc-internal header files
from public headers, this patch moves the former into a new 'internal/'
subdirectory. This makes the include directives easier to follow and the
libc's source-tree structure more tidy.
There are still a few legacies left, which cannot easily be removed
right now (e.g., because noux relies on them). However, the patch moves
those bad apples to legacy.h and legacy.cc, which highlights the
deprecation of those functions.
Issue #3497
2019-09-18 20:19:10 +02:00
|
|
|
}
|