![]() |
The ROme OpTimistic Simulator
2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
|
x86 ULT support header More...
Go to the source code of this file.
Data Structures | |
struct | __exec_context_t |
This structure describes the CPU context of a User-Level Thread. More... | |
Macros | |
#define | set_jmp(env) |
#define | long_jmp(env, val) _long_jmp(env, val) |
Typedefs | |
typedef struct __exec_context_t | exec_context_t |
This structure describes the CPU context of a User-Level Thread. | |
Functions | |
long long | _set_jmp (exec_context_t *env) |
void | _long_jmp (exec_context_t *env, long long val) |
void | context_create (exec_context_t *creat, void(*fn)(void *), void *args, void *stack, size_t stack_size) |
x86 ULT support header
This header defines all the facilities to implement User-Level Threads on x86.
The core of the implementation is found in jmp.S which is written in assembly. jmp.S is undocumented here, but looking at its source will give an explanation of all the functions and how they behave.
This file is part of ROOT-Sim (ROme OpTimistic Simulator).
ROOT-Sim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; only version 3 of the License applies.
ROOT-Sim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with ROOT-Sim; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Definition in file jmp.h.
#define long_jmp | ( | env, | |
val | |||
) | _long_jmp(env, val) |
This macro is a wrapper for _long_jmp(). There is no special care to be taken when calling _long_jmp(), so this macro is offered only to make uniform the usage of the api.
env | A pointer to an exec_context_t structure keeping a CPU context to restore. |
val | This is the value returned by set_jmp() when the context specified in env is restored. |
#define set_jmp | ( | env | ) |
This macro is a wrapper for _set_jmp(), which is the custom implementation of the standard setjmp used in ROOT-Sim. The goal of the wrapper is the following. _set_jmp() requires one parameter, which is the pointer to an exec_context_t where to store the current context. Since the custom implementation is such that all registers should be saved in the context, not only callee-save as in the standard implementation, simply calling _set_jmp() clobbers a register which is later not possible to save. This macro pushes the RDI register, used to keep the first parameter of function calls according to SysV ABI, before calling into _set_jmp(). _set_jmp() expects this to happen, as it will find the original value of RDI to save on the stack frame of the caller. This is why it is not possible to directly call _set_jmp() from the code, but this macro must be explicitly used.
The semantics of this macro are the same as the called _set_jmp().
env | A pointer to an exec_context_t structure where to store the current execution contenxt. |
void _long_jmp | ( | exec_context_t * | env, |
long long | val | ||
) |
_long_jmp() is a function implemented in assembly in jmp.S which restores the whole CPU state (both general purpose registers and FPU registers and state) from the buffer pointed by env
.
This function cannot be directly called (it's poisoned). Use the macro long_jmp instead.
env | A pointer to an exec_context_t structure where to store the current CPU state |
val | This is the value which is returned from _set_jmp() when that function returns after that the context in env has been restored. |
long long _set_jmp | ( | exec_context_t * | env | ) |
_set_jmp() is a function implemented in assembly in jmp.S which saves the whole CPU state (both general purpose registers and FPU registers and state) into the buffer pointed by env
.
The semantic of this function is the same as the surrounding macro set_jmp, which should be used instead. Indeed, calling this function will definitely produce a wrong CPU state, because at least the RDI register cannot be saved when directly calling it, due to register clobbering for parameter passing.
Therefore, this function cannot be directly called (it's poisoned).
env | A pointer to an exec_context_t structure where to store the current CPU state |
void context_create | ( | exec_context_t * | creat, |
void(*)(void *) | fn, | ||
void * | args, | ||
void * | stack, | ||
size_t | stack_size | ||
) |
This function creates a new User-Level Thread by instantiating a new valid context in env
. After that this function returns, the context in env
can be safely passed to long_jmp. The execution will then start from the routine passed in fn
.
creat | A pointer to an exec_context_t structure where the context for the new ULT should be initialized. |
fn | A function pointer which will be the entry point of the ULT once it is first scheduled using long_jmp. |
args | Arguments to be passed to fn once the context is activated. |
stack | A pointer to a memory area to be used as stack. This memory area must be aligned to 16 bytes on x86. |
stack_size | the size of the memory area pointed by stack . |