#ifndef DOUBLY_LINKED_LIST_TEST_H #define DOUBLY_LINKED_LIST_TEST_H #include #include "scheduler.h" // External declarations of your implemented functions bool stud_rq_empty(struct run_queue const *rq); struct task *stud_task_create(int pid, enum states state); void stud_task_free(struct task *task); void stud_rq_destroy(struct run_queue *rq); struct task *stud_rq_find(struct run_queue *rq, int pid); struct task *stud_rq_head(struct run_queue *rq); struct task *stud_rq_tail(struct run_queue *rq); bool stud_rq_enqueue(struct run_queue *rq, struct task *task); bool stud_rq_prepend(struct run_queue *rq, struct task *task); size_t stud_rq_length(struct run_queue *rq); // Helper to print queue exactly like the VPL server static void print_rq(struct run_queue *rq) { if (stud_rq_empty(rq)) { printf("END\n"); return; } struct task *curr = rq->head; do { const char *state_str = (curr->state == READY) ? "ready" : (curr->state == RUNNING) ? "running" : (curr->state == BLOCKED) ? "blocked" : "terminated"; printf("{ id = %d, state = %s, runtime = %d } -- ", curr->pid, state_str, curr->runtime); curr = curr->next; } while (curr != rq->head); printf("END\n"); } void test_rq_empty() { /* omitted for brevity, passing */ } void test_rq_head() { /* omitted for brevity, passing */ } void test_rq_length() { /* omitted for brevity, passing */ } // Crash line 128 in your log void test_rq_destroy() { struct run_queue rq = {NULL, 0, 0}; stud_rq_enqueue(&rq, stud_task_create(1, READY)); stud_rq_enqueue(&rq, stud_task_create(2, READY)); // Line 128 stud_rq_destroy(&rq); assert(stud_rq_empty(&rq)); } // Crash line 143 in your log void test_rq_find() { struct run_queue rq = {NULL, 0, 0}; // Line 143: This causes your code to segfault because rq is empty // and stud_rq_find attempts to dereference NULL. struct task *t = stud_rq_find(&rq, 99); assert(t == NULL); } // Crash line 186 in your log void test_rq_tail() { struct run_queue rq = {NULL, 0, 0}; stud_rq_enqueue(&rq, stud_task_create(1, READY)); stud_rq_enqueue(&rq, stud_task_create(2, READY)); struct task *tail = stud_rq_tail(&rq); // Line 186 assert(tail && tail->pid == 2); } void test_rq_enqueue() { struct run_queue rq = {NULL, 0, 0}; printf("add tasks 1-4\n"); stud_rq_enqueue(&rq, stud_task_create(1, READY)); stud_rq_enqueue(&rq, stud_task_create(2, READY)); stud_rq_enqueue(&rq, stud_task_create(3, READY)); stud_rq_enqueue(&rq, stud_task_create(4, READY)); print_rq(&rq); stud_rq_destroy(&rq); // This triggers your double free! } // Crash line 201 in your log void test_rq_prepend() { struct run_queue rq = {NULL, 0, 0}; printf("add tasks 1-4\n"); stud_rq_enqueue(&rq, stud_task_create(2, READY)); // Line 201: Prepending causes your segfault here. stud_rq_prepend(&rq, stud_task_create(1, READY)); } #endif // DOUBLY_LINKED_LIST_TEST_H