Files CCore/src/task/TaskContext.cpp
This part provides an implementation of the task context functions. These functions are declared in the XCore header TaskCore.h. Each task has an associated block of memory, this block is used to preserve the task context during a task switch. Task context includes CPU register values and some global variables values. When a task is detached from the CPU, these values are preserved in the task context. When a task is regain the CPU, the task context is used to restore the CPU registers and global variables, included in the task context.
/* class Task::Internal */ class Task::Internal { .... // context -- implemented in platform static void ContextInit(void *context,void *stack,ulen stack_len,void *task); static void * GetContext(); static ulen GetContextLen(); static void SwitchContext_int(void *context); static void SwitchContext_task(void *context); .... };
ContextInit() fills the memory to be a valid task context. This function is used to spawn a new task. In order to do so a task context must be allocated, a task stack must be allocated, the allocated task context must be initialized. context is the allocated task context, stack is the allocated task stack, stack_len is the task stack length, task is a value to be passed to the task entry function. The task execution is started from the function Task::Internal::EntryTask() and task is passed to this function.
GetContext() returns the context of the current task. This function must be used under the IntLock protection to be useful.
GetContextLen() returns the task context length. This value is constant on the particular platform.
SwitchContext_int() is called in the interrupt context to switch to the task with the given task context. If this function is called in the interrupt context, then after the interrupt processing is finished the correspondent task will regain CPU. This function can be called multiple times during the single interrupt context processing.
SwitchContext_task() is called in the task context to switch to the task with the given context. It must be called under the IntLock protection. The current task is suspended, its context is updated. When this task is regain CPU, it is continued after the call of the SwitchContext_task(). From the current task perspective the task switch is looked as the function call.
The STD implementation is
/* TaskContext.cpp */ #include <CCore/inc/task/TaskCore.h> #include <__std_init.h> namespace CCore { /* class Task::Internal */ extern "C" void __std_Entry(void *task) { Task::Internal::EntryTask(task); } void Task::Internal::ContextInit(void *context,void *stack,ulen stack_len,void *task) { __std_context_init(context,stack,stack_len,__std_Entry,task); } void * Task::Internal::GetContext() { return __std_context; } ulen Task::Internal::GetContextLen() { return __std_context_len(); } void Task::Internal::SwitchContext_int(void *context) { __std_context=context; } void Task::Internal::SwitchContext_task(void *context) { __std_switch(context); } } // namespace CCore