Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <ucontext.h>
- #include <signal.h>
- #include <sys/time.h>
- //tcb
- typedef struct task_t task_t;
- struct task_t {
- ucontext_t context;
- char task_char;
- task_t *next;
- };
- task_t TaskQueue; //
- task_t *RunningTask;
- void addTask(task_t *new_task) {
- new_task->next = NULL;
- if (TaskQueue.next == NULL) {
- TaskQueue.next = new_task;
- } else {
- task_t *last_task = TaskQueue.next;
- while (last_task->next != NULL) {
- last_task = last_task->next;
- }
- last_task->next = new_task;
- }
- }
- task_t* dequeue() {
- if (TaskQueue.next == NULL) {
- return NULL;
- }
- task_t *next_task = TaskQueue.next;
- TaskQueue.next = next_task->next;
- next_task->next = NULL;
- return next_task;
- }
- void signalHandler(int signum) {
- task_t *next_task = dequeue();
- if (next_task != NULL) {
- addTask(RunningTask);
- RunningTask = next_task;
- swapcontext(&TaskQueue.context, &RunningTask->context);
- }
- }
- void init_timer(){
- struct sigaction sa;
- sa.sa_handler = signalHandler;
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sigaction(SIGALRM, &sa, NULL);
- // Set up the timer
- struct itimerval timer;
- timer.it_interval.tv_sec = 1; // 1 second interval
- timer.it_interval.tv_usec = 0;
- timer.it_value = timer.it_interval;
- setitimer(ITIMER_REAL, &timer, NULL);
- // Wait indefinitely
- //while (1) {
- // sleep(1);
- //}
- }
- void *initlibrary() {
- TaskQueue.next = NULL;
- RunningTask = NULL;
- return NULL;
- }
- void task_function() {
- while (1) {
- printf("%c", RunningTask->task_char); // Print the character associated with the task
- swapcontext(&RunningTask->context, &TaskQueue.context);
- }
- }
- int create_task(void (*start_routine)(), char task_char) {
- task_t *new_task = (task_t*) malloc(sizeof(task_t));
- if (new_task == NULL) {
- return -1;
- }
- getcontext(&new_task->context);
- new_task->context.uc_stack.ss_sp = malloc(SIGSTKSZ);
- new_task->context.uc_stack.ss_size = SIGSTKSZ;
- new_task->context.uc_link = &TaskQueue.context;
- new_task->task_char = task_char;
- makecontext(&new_task->context, start_routine, 0);
- addTask(new_task);
- return 0;
- }
- int main(int argc, char *argv[]) {
- initlibrary();
- if (argc != 3) {
- printf("The correct usage is: %s <firstTask> <secondTask>\n", argv[0]);
- return 1;
- }
- if (create_task(task_function, '+') != 0) {
- printf("ERROR WHILE CREATING TASK ->[firstTask]\n");
- return 1;
- }
- if (create_task(task_function, '-') != 0) {
- printf("ERROR WHILE CREATING TASK ->[secondTask]\n");
- return 1;
- }
- RunningTask = dequeue();
- init_timer();
- while (1) {
- if (RunningTask == NULL) {
- printf("\nNo tasks left to complete!\n");
- exit(0);
- }
- task_t *next_task = dequeue();
- if (next_task != NULL) {
- addTask(RunningTask);
- RunningTask = next_task;
- }
- swapcontext(&TaskQueue.context, &RunningTask->context);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement