I am trying to learn how context switching works and how to make your process switch context after receiving a particular signal. Here is my code
#include<stdio.h>
#include<stdlib.h>
#include<ucontext.h>
#include<signal.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
#define STACK_SIZE 4096
static ucontext_t thread1, thread2;
void thread1_fun() {
static int a = 1;
while (1) {
printf("calling thread1 for %d time\n", a);
sleep(5);
a > 20 ? a = 0 : a++;
}
}
void thread2_fun() {
static int a = 1;
while (1) {
printf("calling thread2 for %d time\n", a);
sleep(5);
a > 20 ? a = 0 : a++;
}
}
void sig_handler(int signal) {
static int curr_thread = 0;
printf("received signal %d\n", signal);
if (curr_thread == 1) {
curr_thread = 0;
printf("switching from thread1 to thread2\n");
setcontext(&thread1);
} else {
curr_thread = 1;
printf("switching from thread2 to thread1\n");
setcontext(&thread2);
}
}
int main() {
int i = 0;
struct sigaction act;
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGUSR1, &act, NULL);
/* sigaction(SIGTERM, &act, NULL); */
getcontext(&thread1);
thread1.uc_stack.ss_sp = malloc (STACK_SIZE);
thread1.uc_stack.ss_size = STACK_SIZE;
thread1.uc_stack.ss_flags = 0;
makecontext(&thread1, thread1_fun, 0);
getcontext(&thread2);
thread2.uc_stack.ss_sp = malloc (STACK_SIZE);
thread2.uc_stack.ss_size = STACK_SIZE;
thread2.uc_stack.ss_flags = 0;
makecontext(&thread2, thread2_fun, 0);
printf("%d\n", getpid());
while (1);
}
Now I give command 'kill -s SIGUSR1 ' from terminal. The process switches the context after receiving this signal but the problem is that it prints the 'calling thread for %d time' twice.
For example if thread1 prints 'calling thread1 for 3rd time' and goes to sleep and while thread1 is sleeping if I send signal to switch the context, thread2 starts executing, now if I again send signal to switch context then thread1 again prints 'calling thread1 for 3rd time'. Ideally it should come out of its sleep and increment the value of a, correct? Why is it printing same value twice?
Here is the output printed by code:
received signal 10
switching from thread2 to thread1
calling thread2 for 1 time
received signal 10
switching from thread1 to thread2
calling thread1 for 1 time
received signal 10
switching from thread2 to thread1
calling thread2 for 1 time
received signal 10
switching from thread1 to thread2
calling thread1 for 1 time
Please help me with this.