Home >Backend Development >C++ >Dia e - Understanding contexts in C
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; i < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPing, &ContextPong); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPing, &ContextMain); } /*****************************************************/ void BodyPong(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; i < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPong, &ContextPing); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPong, &ContextMain); } /*****************************************************/
In 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: fim
With 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 Ping and Pong context, 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".
The above is the detailed content of Dia e - Understanding contexts in C. For more information, please follow other related articles on the PHP Chinese website!