167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
|
|
#ifndef SCHEDULER_ROUND_ROBIN_TEST_H
|
||
|
|
#define SCHEDULER_ROUND_ROBIN_TEST_H
|
||
|
|
|
||
|
|
#include <assert.h>
|
||
|
|
#include "scheduler.h"
|
||
|
|
|
||
|
|
void stud_RR_start(struct run_queue *rq, int pid);
|
||
|
|
void stud_RR_elect(struct run_queue *rq);
|
||
|
|
void stud_RR_terminate(struct run_queue *rq);
|
||
|
|
void stud_RR_clock_tick(struct run_queue *rq);
|
||
|
|
void stud_RR_wait(struct run_queue *rq);
|
||
|
|
void stud_RR_wake_up(struct run_queue *rq, int pid);
|
||
|
|
void stud_RR(struct run_queue* rq, enum events event, int pid);
|
||
|
|
|
||
|
|
// Mock implementation of the grader's verifier
|
||
|
|
bool rq_eq(struct run_queue *sol, struct run_queue *stu) {
|
||
|
|
if (sol->n_tasks != stu->n_tasks) return false;
|
||
|
|
if (sol->n_tasks == 0) return true;
|
||
|
|
|
||
|
|
struct task *c1 = sol->head;
|
||
|
|
struct task *c2 = stu->head;
|
||
|
|
int pos = 0;
|
||
|
|
do {
|
||
|
|
if (c1->pid != c2->pid || c1->state != c2->state) {
|
||
|
|
fprintf(stderr, "Task (%d, %s) error at position %d\n",
|
||
|
|
c2->pid, c2->state == RUNNING ? "running" : "other", pos);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
c1 = c1->next;
|
||
|
|
c2 = c2->next;
|
||
|
|
pos++;
|
||
|
|
} while (c1 != sol->head && c2 != stu->head);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 73 in your log
|
||
|
|
void test_RR_start() {
|
||
|
|
struct run_queue stu = {NULL, 0, 0};
|
||
|
|
struct run_queue sol = {NULL, 0, 0}; // Mock expected state
|
||
|
|
|
||
|
|
// Manually build expected solution queue to compare against
|
||
|
|
stud_rq_enqueue(&sol, stud_task_create(1, RUNNING));
|
||
|
|
stud_rq_enqueue(&sol, stud_task_create(2, READY));
|
||
|
|
stud_rq_enqueue(&sol, stud_task_create(3, READY));
|
||
|
|
|
||
|
|
printf("add task 1\n");
|
||
|
|
stud_RR_start(&stu, 1);
|
||
|
|
|
||
|
|
printf("add task 2\n");
|
||
|
|
stud_RR_start(&stu, 2);
|
||
|
|
|
||
|
|
printf("add task 3\n");
|
||
|
|
stud_RR_start(&stu, 3);
|
||
|
|
|
||
|
|
printf("add task 1 again\n");
|
||
|
|
stud_RR_start(&stu, 1);
|
||
|
|
|
||
|
|
print_rq(&stu);
|
||
|
|
|
||
|
|
// Line 73
|
||
|
|
assert(rq_eq(&sol, &stu));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper to prepopulate a specific queue state for testing the crash logs
|
||
|
|
void prepopulate_queue(struct run_queue *rq) {
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(1, RUNNING));
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(2, TERMINATED));
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(3, READY));
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(4, TERMINATED));
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(8, READY));
|
||
|
|
stud_rq_enqueue(rq, stud_task_create(14, BLOCKED));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 109 in your log
|
||
|
|
void test_RR_elect_running() {
|
||
|
|
struct run_queue rq = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&rq);
|
||
|
|
print_rq(&rq);
|
||
|
|
printf("electing new task...\n");
|
||
|
|
|
||
|
|
// Line 109
|
||
|
|
stud_RR_elect(&rq);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 127 in your log
|
||
|
|
void test_RR_elect_blocked() {
|
||
|
|
struct run_queue rq = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&rq);
|
||
|
|
rq.head->state = BLOCKED; // Change 1 to blocked
|
||
|
|
print_rq(&rq);
|
||
|
|
printf("electing new task...\n");
|
||
|
|
|
||
|
|
// Line 127
|
||
|
|
stud_RR_elect(&rq);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 148 in your log
|
||
|
|
void test_RR_terminate() {
|
||
|
|
struct run_queue rq = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&rq);
|
||
|
|
print_rq(&rq);
|
||
|
|
printf("task terminating...\n");
|
||
|
|
|
||
|
|
// Line 148
|
||
|
|
stud_RR_terminate(&rq);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 169 in your log
|
||
|
|
void test_RR_wait() {
|
||
|
|
struct run_queue rq = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&rq);
|
||
|
|
print_rq(&rq);
|
||
|
|
printf("task is waiting...\n");
|
||
|
|
|
||
|
|
// Line 169
|
||
|
|
stud_RR_wait(&rq);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 190 in your log
|
||
|
|
void test_RR_wake_up() {
|
||
|
|
struct run_queue rq = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&rq);
|
||
|
|
print_rq(&rq);
|
||
|
|
printf("task 14 waking up...\n");
|
||
|
|
|
||
|
|
// Line 190
|
||
|
|
stud_RR_wake_up(&rq, 14);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 216 in your log
|
||
|
|
void test_RR_clock_tick() {
|
||
|
|
struct run_queue stu = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&stu);
|
||
|
|
print_rq(&stu);
|
||
|
|
|
||
|
|
for(int i=0; i<10; i++) {
|
||
|
|
printf("running clock tick...\n");
|
||
|
|
stud_RR_clock_tick(&stu);
|
||
|
|
}
|
||
|
|
|
||
|
|
print_rq(&stu);
|
||
|
|
|
||
|
|
struct run_queue sol = {NULL, 0, 0};
|
||
|
|
// Expected solution queue state omitted for brevity
|
||
|
|
|
||
|
|
// Line 216
|
||
|
|
// assert(rq_eq(&sol, &stu));
|
||
|
|
}
|
||
|
|
|
||
|
|
// Crash line 263 in your log
|
||
|
|
void test_RR_scripted_1() {
|
||
|
|
struct run_queue stu = {NULL, 0, 0};
|
||
|
|
prepopulate_queue(&stu);
|
||
|
|
print_rq(&stu);
|
||
|
|
for(int i=0; i<5; i++) {
|
||
|
|
printf("running clock tick...\n");
|
||
|
|
stud_RR_clock_tick(&stu);
|
||
|
|
}
|
||
|
|
print_rq(&stu);
|
||
|
|
printf("task is waiting...\n");
|
||
|
|
|
||
|
|
// Line 263
|
||
|
|
stud_RR(&stu, wait, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif // SCHEDULER_ROUND_ROBIN_TEST_H
|