Advertisement
moldovexc

Untitled

May 30th, 2023
608
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ucontext.h>
  4. #include <signal.h>
  5. #include <sys/time.h>
  6.  
  7. //tcb
  8. typedef struct task_t task_t;
  9. struct task_t {
  10.     ucontext_t context;
  11.     char task_char;
  12.     task_t *next;
  13. };
  14.  
  15. task_t TaskQueue;   //
  16. task_t *RunningTask;
  17. void addTask(task_t *new_task) {
  18.     new_task->next = NULL;
  19.  
  20.     if (TaskQueue.next == NULL) {
  21.         TaskQueue.next = new_task;
  22.     } else {
  23.         task_t *last_task = TaskQueue.next;
  24.         while (last_task->next != NULL) {
  25.             last_task = last_task->next;
  26.         }
  27.         last_task->next = new_task;
  28.     }
  29. }
  30. task_t* dequeue() {
  31.     if (TaskQueue.next == NULL) {
  32.         return NULL;
  33.     }
  34.  
  35.     task_t *next_task = TaskQueue.next;
  36.     TaskQueue.next = next_task->next;
  37.     next_task->next = NULL;
  38.  
  39.     return next_task;
  40. }
  41.  
  42. void signalHandler(int signum) {
  43.     task_t *next_task = dequeue();
  44.     if (next_task != NULL) {
  45.         addTask(RunningTask);
  46.         RunningTask = next_task;
  47.         swapcontext(&TaskQueue.context, &RunningTask->context);
  48.     }
  49. }
  50.  
  51. void init_timer(){
  52. struct sigaction sa;
  53.     sa.sa_handler = signalHandler;
  54.     sigemptyset(&sa.sa_mask);
  55.     sa.sa_flags = 0;
  56.     sigaction(SIGALRM, &sa, NULL);
  57.  
  58.     // Set up the timer
  59.     struct itimerval timer;
  60.     timer.it_interval.tv_sec = 1;       // 1 second interval
  61.     timer.it_interval.tv_usec = 0;
  62.     timer.it_value = timer.it_interval;
  63.     setitimer(ITIMER_REAL, &timer, NULL);
  64.  
  65.     // Wait indefinitely
  66.     //while (1) {
  67.    //     sleep(1);
  68.     //}
  69. }
  70. void *initlibrary() {
  71.     TaskQueue.next = NULL;
  72.     RunningTask = NULL;
  73.     return NULL;
  74. }
  75. void task_function() {
  76.     while (1) {
  77.         printf("%c", RunningTask->task_char);  // Print the character associated with the task
  78.         swapcontext(&RunningTask->context, &TaskQueue.context);
  79.     }
  80. }
  81.  
  82.  
  83. int create_task(void (*start_routine)(), char task_char) {
  84.     task_t *new_task = (task_t*) malloc(sizeof(task_t));
  85.     if (new_task == NULL) {
  86.         return -1;
  87.     }
  88.  
  89.     getcontext(&new_task->context);
  90.     new_task->context.uc_stack.ss_sp = malloc(SIGSTKSZ);
  91.     new_task->context.uc_stack.ss_size = SIGSTKSZ;
  92.     new_task->context.uc_link = &TaskQueue.context;
  93.  
  94.     new_task->task_char = task_char;
  95.  
  96.     makecontext(&new_task->context, start_routine, 0);
  97.  
  98.     addTask(new_task);
  99.  
  100.     return 0;
  101. }
  102.  
  103.  
  104. int main(int argc, char *argv[]) {
  105.     initlibrary();
  106.      if (argc != 3) {
  107.         printf("The correct usage is: %s <firstTask> <secondTask>\n", argv[0]);
  108.         return 1;
  109.     }
  110.    
  111.     if (create_task(task_function, '+') != 0) {
  112.     printf("ERROR WHILE CREATING TASK ->[firstTask]\n");
  113.     return 1;
  114.     }
  115.  
  116.     if (create_task(task_function, '-') != 0) {
  117.     printf("ERROR WHILE CREATING TASK ->[secondTask]\n");
  118.     return 1;
  119.     }    
  120.  
  121.      RunningTask = dequeue();
  122.     init_timer();
  123.      while (1) {
  124.         if (RunningTask == NULL) {
  125.             printf("\nNo tasks left to complete!\n");
  126.             exit(0);
  127.         }
  128.  
  129.         task_t *next_task = dequeue();
  130.         if (next_task != NULL) {
  131.             addTask(RunningTask);
  132.             RunningTask = next_task;
  133.         }
  134.  
  135.         swapcontext(&TaskQueue.context, &RunningTask->context);
  136.     }
  137.     }
  138.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement