The is an object used by the scheduler.
More...
#include <thread/thread.h>
|
| Thread () |
| Constructor Initializes the context using prepareContext with the highest aligned address of the reserved_stack_space array as stack pointer (top of stack). Furthermore, assign each thread a unique id using a global variable idCounter. You have to declare and initialize it properly.
|
|
void | go () |
| Activates the first thread on this CPU.
|
|
void | resume (Thread *next) |
| Switches from the currently running thread to the next one.
|
|
virtual void | action ()=0 |
| Method that contains the thread's program code.
|
|
|
const size_t | id |
| Unique ID of thread.
|
|
volatile bool | kill_flag |
| Marker for a dying thread.
|
|
The is an object used by the scheduler.
◆ Thread()
Constructor Initializes the context using prepareContext with the highest aligned address of the reserved_stack_space
array as stack pointer (top of stack). Furthermore, assign each thread a unique id using a global variable idCounter. You have to declare and initialize it properly.
- Note
- Remember: Stacks grow to the lower addresses on x86!
- Todo:
- Implement constructor
◆ kickoff()
void Thread::kickoff |
( |
Thread * |
object | ) |
|
|
staticprotected |
Function to start a thread.
For the first activation of a thread, we need a "return address" pointing to a function that will take care of calling C++ virtual methods. For this purpose, we use this kickoff()
function.
Activating kickoff
The thread initialization via prepareContext() not only initializes the Stack for the first thread change, but also pushes the address of kickoff()
as return address to the stack. Consequently, the first execution of context_switch() will start execution by returning to the beginning of kickoff()
.
This kickoff()
function simply calls the action() method on the thread passed as parameter and, thus, resolves the virtual C++ method.
- Note
- As this function is never actually called, but only executed by returning from the threads's initial stack, it may never return. Otherwise garbage values from the stack will be interpreted as return address and the system might crash.
- Parameters
-
object | Thread to be started |
- Todo:
- Implement Method
◆ go()
Activates the first thread on this CPU.
Calling the method starts the first thread on the calling CPU. From then on, Thread::resume() must be used all subsequent context switches.
- Todo:
- Implement Method
◆ resume()
void Thread::resume |
( |
Thread * |
next | ) |
|
Switches from the currently running thread to the next
one.
The values currently present in the non-scratch (callee-saved) registers will be stored on this thread's stack; the corresponding values belonging to next
thread will be loaded (from next
's stack).
- Parameters
-
next | Pointer to the next thread. |
- Todo:
- Implement Method
- Optional:
- To detect stack overflows you can check if the bottom of the stack still contains a predefined value (which was set in constructor).
◆ action()
virtual void Thread::action |
( |
| ) |
|
|
pure virtual |
Method that contains the thread's program code.
Derived classes are meant to override this method to provide meaningful code to be run in this thread.
Implemented in Application, and KeyboardApplication.
◆ STACK_SIZE
const size_t Thread::STACK_SIZE = 4096 |
|
static |
Stack size for each thread.
◆ reserved_stack_space
Memory reserved for the this threads stack.
◆ bottom_of_stack
uint32_t* Thread::bottom_of_stack = nullptr |
|
private |
Pointer to the bottom of the (kernel) stack which should contain a canary value – or we most likely have a stack overflow.
◆ stackpointer
Current stack pointer of thread for context switch.
◆ id
◆ kill_flag
volatile bool Thread::kill_flag |
Marker for a dying thread.
The documentation for this class was generated from the following files: