
хз че сказать. вот вам шедулер.
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
#define MAX_PRIORITY 2
enum task_status {
READY,
SLEEP,
TERMINATE,
};
struct task {
enum task_status status;
int id;
uint32_t priority;
int (*routine)(void);
LIST_ENTRY(task) entries;
};
typedef struct task task_s;
LIST_HEAD(task_listhead, task);
typedef struct task_listhead task_listhead_s;
task_listhead_s tasks_lists[MAX_PRIORITY + 1];
int task_curr_id = 1;
int task_add(int (*routine)(void), uint32_t priority) {
if (priority > MAX_PRIORITY) {
return -1;
}
task_s *new_task_ptr;
if (!(new_task_ptr = malloc(sizeof(*new_task_ptr)))) {
return -1;
}
new_task_ptr->priority = priority;
new_task_ptr->status = READY;
new_task_ptr->routine = routine;
new_task_ptr->id = task_curr_id++;
LIST_INSERT_HEAD(tasks_lists + priority, new_task_ptr, entries);
return new_task_ptr->id;
}
static void remove_task(task_s *task_ptr) {
LIST_REMOVE(task_ptr, entries);
free(task_ptr);
}
static task_s *find_task(int id) {
task_s *found_task = NULL;
for (size_t i = 0; i <= MAX_PRIORITY; ++i) {
task_s *task_ptr;
LIST_FOREACH(task_ptr, tasks_lists + i, entries) {
if (task_ptr->id == id) {
found_task = task_ptr;
break;
}
}
}
return found_task;
}
int task_remove(int id) {
task_s *task_to_rm = find_task(id);
if (!task_to_rm) {
return 1;
}
task_to_rm->status = TERMINATE;
return 0;
}
int task_put_sleep(int id) {
task_s *task_to_sleep = find_task(id);
if (!task_to_sleep) {
return 1;
}
task_to_sleep->status = SLEEP;
return 0;
}
int task_wake_up(int id) {
task_s *task_to_wakeup = find_task(id);
if (!task_to_wakeup) {
return 1;
}
task_to_wakeup->status = READY;
return 0;
}
int task_change_priority(int id, uint32_t priority) {
task_s *task_to_change_pr = find_task(id);
if (!task_to_change_pr || priority > MAX_PRIORITY) {
return 1;
}
task_to_change_pr->priority = priority;
return 0;
}
void scheduler_init() {
for (size_t i = 0u; i < MAX_PRIORITY; ++i) {
LIST_INIT(tasks_lists + i);
}
}
void schedule() {
for (;;) {
int is_active = 0;
for (size_t i = 0u; i <= MAX_PRIORITY; ++i) {
size_t pr = MAX_PRIORITY - i;
task_s *task_ptr = LIST_FIRST(tasks_lists + pr);
while (task_ptr != NULL) {
if (task_ptr->priority != pr) {
task_s *task_to_mv = task_ptr;
task_ptr = LIST_NEXT(task_ptr, entries);
LIST_REMOVE(task_to_mv, entries);
LIST_INSERT_HEAD(tasks_lists + task_to_mv->priority, task_to_mv, entries);
continue;
}
task_s *task_to_rm = NULL;
switch (task_ptr->status) {
case READY: {
is_active = 1;
int new_status = task_ptr->routine();
task_ptr->status = new_status;
break;
}
case SLEEP:
break;
case TERMINATE:
task_to_rm = task_ptr;
break;
}
task_ptr = LIST_NEXT(task_ptr, entries);
if (task_to_rm) {
remove_task(task_to_rm);
}
}
}
if (!is_active) {
break;
}
}
}
int glob = 0;
int prod_id;
int prod_cnt = 10;
int cons_id;
int cons_cnt = 0;
int prod() {
if (!prod_cnt) {
task_remove(cons_id);
return TERMINATE;
}
prod_cnt--;
glob++;
task_wake_up(cons_id);
return SLEEP;
}
int cons() {
if (!glob) {
return SLEEP;
}
cons_cnt++;
glob--;
printf("%d\\n", cons_cnt);
task_wake_up(prod_id);
return SLEEP;
}
int main() {
scheduler_init();
prod_id = task_add(prod, 2);
cons_id = task_add(cons, 1);
schedule();
return 0;
}