"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Dia e - Understanding contexts in C

Dia e - Understanding contexts in C

Published on 2024-10-31
Browse:276

Dia e - Entendendo contextos em 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.

Context switching for operating systems

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 



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 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".

Release Statement This article is reproduced at: https://dev.to/matheusgb/dia-21-e-21-entendendo-contextos-em-c-2imm If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

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