In C, context is the current execution state of a program, including registers (small storage areas within the CPU, used to store data and instructions during program execution), variables and the flow of instructions, crucial for switching tasks.
The main function is to allow multitasking. This ensures that the system can switch between processes efficiently.
The contexts.c file was made available here. It is a demonstration of how contexts work.
Right at the top of this file, we notice the import of the ucontext.h library. It allows you to manipulate the execution context.
In the excerpt below we see that 3 contexts are created, and these 3 contexts will have memory allocated the size of STACKSIZE.
#define STACKSIZE 64 * 1024 /* tamanho de pilha das threads */ ucontext_t ContextPing, ContextPong, ContextMain;
And soon after, the Ping and Pong functions that will be executed in their respective contexts:
void BodyPing(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; iIn the main function, malloc is used to reserve the stacks, where they are later assigned with uc_stack.ss_sp to the context, and swapcontext is used to switch between them.
int main(int argc, char *argv[]) { char *stack; printf("main: inicio\n"); getcontext(&ContextPing); stack = malloc(STACKSIZE); if (stack) { ContextPing.uc_stack.ss_sp = stack; ContextPing.uc_stack.ss_size = STACKSIZE; ContextPing.uc_stack.ss_flags = 0; ContextPing.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPing, (void *)(*BodyPing), 1, " Ping"); getcontext(&ContextPong); stack = malloc(STACKSIZE); if (stack) { ContextPong.uc_stack.ss_sp = stack; ContextPong.uc_stack.ss_size = STACKSIZE; ContextPong.uc_stack.ss_flags = 0; ContextPong.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPong, (void *)(*BodyPong), 1, " Pong"); swapcontext(&ContextMain, &ContextPing); swapcontext(&ContextMain, &ContextPong); printf("main: fim\n"); exit(0); }Output of the executed program:
main: inicio Ping: inicio Ping: 0 Pong: inicio Pong: 0 Ping: 1 Pong: 1 Ping: 2 Pong: 2 Ping: 3 Pong: 3 Ping: fim Pong: fim main: fimWith this, we can see that even when changing the contexts, the values that "flow" through the function are maintained, an example in this case is the for index.
You may have noticed that there is a malloc for the context of Ping and Pong, but we see that there is a context for main too, why isn't there a malloc for it?
ContextMain does not need a separate stack because it operates on the main thread's stack, while Ping and Pong contexts have their own dynamically allocated stacks.
If I create a context and don't allocate memory for it, when we use swap, it goes to the program's main stack.
This code is from Professor Maziero, found in the developed sub-project of PingPongOS "Trocas de Contexto".
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3