The simplest flow requires:
- Some memory for stack space
- Somewhere to store its context (i.e. the contents of the register, program counter, stack pointer, etc.).
In addition, you will need to implement a simple "kernel" that will be responsible for switching threads. And if you are trying to implement proactive threads, you also need a periodic interrupt source. eg. timer. In this case, you can execute the thread switching code in the timer interrupt.
Take a look at the setjmp () / longjmp () routines and the corresponding jmp_buf structure. This will give you easy access to the stack pointer so you can assign your own stack space, and will provide you with an easy way to grab the entire contents of the register to provide thread context.
Typically, the longjmp () function is a wrapper around the return from an interrupt command, which goes very well with the thread scheduling functionality of a timer interrupt. You will need to check the implementation of longjmp () and jmp_buf for your platform.
Try looking for streaming implementations on small microprocessors that usually don't have an OS. eg. Atmel AVR, or Microchip PIC. For example: discussion of AVRFreaks
source to share
For a decent threading library, you need:
- atomic operations to avoid races (to implement e.g. a mutex)
- support for some OS for scheduling and avoidance of waiting
- support for some OS to implement context switching
All three go beyond what C99 offers. Atomic operations are introduced in C11, so far C11 implementations do not seem to be ready, so they are usually implemented in assembler. For the next two years, you will have to rely on your OS.
source to share