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>
- typedef struct Task Task;
- struct Task {
- ucontext_t context;
- char taskChar;
- Task *next;
- };
- Task taskQueue;
- Task *runningTask;
- void enqueueTask(Task *newTask) {
- newTask->next = NULL;
- if (taskQueue.next == NULL) {
- taskQueue.next = newTask;
- } else {
- Task *lastTask = taskQueue.next;
- while (lastTask->next != NULL) {
- lastTask = lastTask->next;
- }
- lastTask->next = newTask;
- }
- }
- Task* dequeueTask() {
- if (taskQueue.next == NULL) {
- return NULL;
- }
- Task *nextTask = taskQueue.next;
- taskQueue.next = nextTask->next;
- nextTask->next = NULL;
- return nextTask;
- }
- void handleSignal(int signum) {
- Task *nextTask = dequeueTask();
- if (nextTask != NULL) {
- enqueueTask(runningTask);
- runningTask = nextTask;
- swapcontext(&taskQueue.context, &runningTask->context);
- }
- }
- void initializeTimer() {
- struct sigaction sa;
- sa.sa_handler = handleSignal;
- 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);
- }
- void* initializeLibrary() {
- taskQueue.next = NULL;
- runningTask = NULL;
- return NULL;
- }
- void taskFunction() {
- while (1) {
- printf("%c", runningTask->taskChar); // Print the character associated with the task
- swapcontext(&runningTask->context, &taskQueue.context);
- }
- }
- int createTask(void (*startRoutine)(), char taskChar) {
- Task *newTask = (Task*) malloc(sizeof(Task));
- if (newTask == NULL) {
- return -1;
- }
- getcontext(&newTask->context);
- newTask->context.uc_stack.ss_sp = malloc(SIGSTKSZ);
- newTask->context.uc_stack.ss_size = SIGSTKSZ;
- newTask->context.uc_link = &taskQueue.context;
- newTask->taskChar = taskChar;
- makecontext(&newTask->context, startRoutine, 0);
- enqueueTask(newTask);
- return 0;
- }
- int main(int argc, char *argv[]) {
- initializeLibrary();
- if (argc != 3) {
- printf("The correct usage is: %s <firstTask> <secondTask>\n", argv[0]);
- return 1;
- }
- if (createTask(taskFunction, '+') != 0) {
- printf("ERROR WHILE CREATING TASK -> [firstTask]\n");
- return 1;
- }
- if (createTask(taskFunction, '-') != 0) {
- printf("ERROR WHILE CREATING TASK -> [secondTask]\n");
- return 1;
- }
- runningTask = dequeueTask();
- initializeTimer();
- while (1) {
- if (runningTask == NULL) {
- printf("\nAll tasks completed!\n");
- exit(0);
- }
- Task *nextTask = dequeueTask();
- if (nextTask != NULL) {
- enqueueTask(runningTask);
- runningTask = nextTask;
- }
- swapcontext(&taskQueue.context, &runningTask->context);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement