mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +00:00
Introduce 'spec' subdirectories to outline aspects
Instead of holding SPEC-variable dependent files and directories inline within the repository structure, move them into 'spec' subdirectories at the corresponding levels, e.g.: repos/base/include/spec repos/base/mk/spec repos/base/lib/mk/spec repos/base/src/core/spec ... Moreover, this commit removes the 'platform' directories. That term was used in an overloaded sense. All SPEC-relative 'platform' directories are now named 'spec'. Other files, like for instance those related to the kernel/architecture specific startup library, where moved from 'platform' directories to explicit, more meaningful places like e.g.: 'src/lib/startup'. Fix #1673
This commit is contained in:
committed by
Christian Helmuth
parent
6cdb823187
commit
ed52d5a211
136
repos/base/src/lib/startup/init_main_thread.cc
Normal file
136
repos/base/src/lib/startup/init_main_thread.cc
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* \brief Setup the thread environment of a programs first thread
|
||||
* \author Christian Helmuth
|
||||
* \author Christian Prochaska
|
||||
* \author Martin Stein
|
||||
* \date 2013-12-04
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 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 <util/construct_at.h>
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
addr_t init_main_thread_result;
|
||||
|
||||
extern void init_exception_handling();
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
void prepare_init_main_thread();
|
||||
|
||||
enum { MAIN_THREAD_STACK_SIZE = 16UL * 1024 * sizeof(Genode::addr_t) };
|
||||
|
||||
/**
|
||||
* Satisfy crt0.s in static programs, LDSO overrides this symbol
|
||||
*/
|
||||
extern "C" void init_rtld() __attribute__((weak));
|
||||
void init_rtld() { }
|
||||
|
||||
/**
|
||||
* The first thread in a program
|
||||
*/
|
||||
class Main_thread : public Thread<MAIN_THREAD_STACK_SIZE>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param reinit wether this is called for reinitialization
|
||||
*/
|
||||
Main_thread(bool reinit)
|
||||
:
|
||||
Thread("main", reinit ? REINITIALIZED_MAIN : MAIN)
|
||||
{ }
|
||||
|
||||
/**********************
|
||||
** Thread interface **
|
||||
**********************/
|
||||
|
||||
void entry() { }
|
||||
};
|
||||
|
||||
|
||||
Main_thread * main_thread()
|
||||
{
|
||||
static Main_thread s(false);
|
||||
return &s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a thread object for the main thread
|
||||
*
|
||||
* \return stack pointer of the new environment via init_main_thread_result
|
||||
*
|
||||
* This function must be called only once per program and before the _main
|
||||
* function. It can be called as soon as a temporary environment provides
|
||||
* some stack space and inter-process communication. At this stage, global
|
||||
* static objects are not registered for implicit destruction at program exit.
|
||||
*/
|
||||
extern "C" void init_main_thread()
|
||||
{
|
||||
/* do platform specific preparation */
|
||||
prepare_init_main_thread();
|
||||
|
||||
/*
|
||||
* Explicitly setup program environment at this point to ensure that its
|
||||
* destructor won't be registered for the atexit routine.
|
||||
*/
|
||||
(void*)env();
|
||||
|
||||
/* initialize exception handling */
|
||||
init_exception_handling();
|
||||
|
||||
/*
|
||||
* We create the thread-context area as early as possible to prevent other
|
||||
* mappings from occupying the predefined virtual-memory region.
|
||||
*/
|
||||
env_context_area_rm_session();
|
||||
|
||||
/*
|
||||
* Trigger first exception. This step has two purposes.
|
||||
* First, it enables us to detect problems related to exception handling as
|
||||
* early as possible. If there are problems with the C++ support library,
|
||||
* it is much easier to debug them at this early stage. Otherwise problems
|
||||
* with half-working exception handling cause subtle failures that are hard
|
||||
* to interpret.
|
||||
*
|
||||
* Second, the C++ support library allocates data structures lazily on the
|
||||
* first occurrence of an exception. This allocation traverses into
|
||||
* Genode's heap and, in some corner cases, consumes several KB of stack.
|
||||
* This is usually not a problem when the first exception is triggered from
|
||||
* the main thread but it becomes an issue when the first exception is
|
||||
* thrown from the context of a thread with a specially tailored (and
|
||||
* otherwise sufficient) stack size. By throwing an exception here, we
|
||||
* mitigate this issue by eagerly performing those allocations.
|
||||
*/
|
||||
try { throw 1; } catch (...) { }
|
||||
|
||||
/* create a thread object for the main thread */
|
||||
main_thread();
|
||||
|
||||
/**
|
||||
* The new stack pointer enables the caller to switch from its current
|
||||
* environment to the those that the thread object provides.
|
||||
*/
|
||||
addr_t sp = reinterpret_cast<addr_t>(main_thread()->stack_top());
|
||||
init_main_thread_result = sp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reinitialize main-thread object according to a reinitialized environment
|
||||
*/
|
||||
void reinit_main_thread() { construct_at<Main_thread>(main_thread(), true); }
|
Reference in New Issue
Block a user