This group contains platform-specific routines that implement internal behavior of this port. More...
Data Structures | |
| struct | thread_startup_t |
| Internal thread startup data structure. More... | |
Functions | |
| void | trigger_pendsv_if_needed () |
| Trigger thread switch if requested. | |
| int | system_call_entrypoint (unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, unsigned char syscall_id) |
| Entrypoint into system call machinery. | |
| void | thread_switch_handler (int signo) |
| This function handles the heavy lifting of thread switching. | |
| void | kernel_service_handler (int signo) |
| Handler for kernel service call. | |
| int | thread_startup_handler (void *arg) |
| Routine to jump-start guest thread host. | |
| void | cmrx_posix_register_syscalls (struct Syscall_Entry_t *added_syscalls) |
| Register syscall with kernel. | |
Variables | |
| static volatile bool | kernel_execute_thread_switch = false |
| Shall thread switch be performed? While kernel timer is called periodically, it doesn't perform thread switch inside the handler. | |
| static struct Syscall_Entry_t | syscalls [256] = { 0 } |
| List of registered syscalls. | |
| static unsigned | syscalls_count = 0 |
| Counter for known syscalls. | |
This group contains platform-specific routines that implement internal behavior of this port.
Each CMRX thread is backed by one Linux thread. CMRX kernel is using signals and blocking syscalls to enforce preemption on threads.
Internally the architecture of the port is similar to the ARM Cortex-M one. Kernel is using timers "interrupt" and "thread switch interrupt". These "interrupts" are serviced by kernel thread synchronously, so they never preempt each other. This makes sure that threads are never switched while inside syscall.
|
extern |
Internal routine to register application with kernel.
This routine is used by the static creation mechanism to register application with kernel. It will be called before the main() is executed. It puts application definition into list of known application definitions for the kernel to create this process upon kernel startup.
| process | process definition structure |
| void cmrx_posix_register_syscalls | ( | struct Syscall_Entry_t * | added_syscalls | ) |
Register syscall with kernel.
The call to this function is arranged by each block where syscalls are defined. It registers all syscalls provided in syscall registration request.
This function is called during constructor phase, before main was executed.
|
extern |
Internal routine to register thread with kernel.
This routine is used by the thread autostart mechanism to register thread with kernel. It will be called before the main() is executed. It puts thread definition into list of known thread definitions for the kernel to create this thread upon kernel startup.
| process | thread definition structure |
| void kernel_service_handler | ( | int | signo | ) |
Handler for kernel service call.
This handler handles kernel syscall execution. The fact that kernel syscalls are called via this handler makes sure that:
| int system_call_entrypoint | ( | unsigned long | arg0, |
| unsigned long | arg1, | ||
| unsigned long | arg2, | ||
| unsigned long | arg3, | ||
| unsigned long | arg4, | ||
| unsigned long | arg5, | ||
| unsigned char | syscall_id | ||
| ) |
Entrypoint into system call machinery.
This function will fill thread-private buffer for system call data and will dispatch the system call handler to be called.
| int thread_startup_handler | ( | void * | arg | ) |
Routine to jump-start guest thread host.
This routine will configure the Linux thread to act as a host for CMRX thread. We don't want ' This is a Linux thread that hosts guest thread. We don't want these threads to process timer signals. These are basically ever only sensitive to SIGUSR1 which is used to force preemption.
Allow reception of SIGALRM, SIGUSR1 (PendSV) and SIGURG (SVCHandler) signals in CMRX thread hosting threads
| void thread_switch_handler | ( | int | signo | ) |
This function handles the heavy lifting of thread switching.
Another thread is woken-up by unblocking it, then this thread is suspended.
| void trigger_pendsv_if_needed | ( | ) |
Trigger thread switch if requested.
Initiate thread switch sequence if it was requested.
Triggers thread switch interrupt if requested and clears the flag.
| thread_stopped | true if thread is already stopped (e.g. due to entering system call) |
|
static |
Shall thread switch be performed? While kernel timer is called periodically, it doesn't perform thread switch inside the handler.
Rather it schedules thread switch interrupt which is then executed synchronously by the "kernel" thread. This flag holds information if this thread switch should be requested or not. Due to the semantics of CMRX it is possible that this flag will be activated and then deactivated before thread switch happens (e.g. because interrupt caused thread wakeup before thread managed to be scheduled out of CPU).
|
static |
Structure that holds information on process definitions.
|
static |
Structure that holds information on autostarted threads.
|
static |
Counter for known process definitions.
|
static |
List of registered syscalls.
This list contains syscall definitions that were registered with kernel. The registration happens automatically if REGISTER_SYSCALLS macro was used.
|
static |
Counter for known syscalls.
This counter holds amount of syscalls known to the kernel.
|
static |
Counter for autostarted threads.