Threads and Scheduling
1#include "pq.h"
2#include "log.h"
3
4// Just sets the head to NULL.
5PQ pq_init() {
6 return (PQ){.head = NULL};
7}
8
9// Goes node by node freeing all the memory.
10void pq_deinit(PQ* pq) {
11 exists(pq);
12 struct Node* curr = pq->head;
13
14 while (curr != NULL) {
15 struct Node* kod = curr;
16 curr = curr->next;
17 free(kod->proc.program.buf);
18 free(kod);
19 }
20}
21
22
23// I spent way too long trying to implement this in C. . . So I tried it in
24// Haskell. The Haskell implementation looks like this:
25// n_insert :: a -> [a] -> [a]
26// n_insert p_time [] = [p_time]
27// n_insert p_time (n_time:n_next) = if n_time > p_time then p_time:n_time:n_next else n_time:n_insert p_time n_next
28// The C implementation looks like this:
29Node* n_insert(Proc p, Node* n) {
30 // n_insert p_time []
31 if (n == NULL) {
32 Node* list = malloc(sizeof(Node));
33 exists(list);
34
35 // [p_time]
36 list->proc = p;
37 list->next = NULL;
38 return list;
39 }
40 // n_insert p_time (n_time:n_next)
41 else
42 {
43 // if n_time > p_time then
44 if (n->proc.time > p.time) {
45 Node* list = malloc(sizeof(Node));
46 exists(list);
47
48 // p_time:n_time:n_next
49 list->proc = p;
50 list->next = n; // in this case n_time:n_next == n
51 return list;
52 } else {
53 // n_time:n_insert p_time n_next
54 n->next = n_insert(p, n->next);
55 return n;
56 }
57 }
58}
59
60// This function just calls n_insert.
61void pq_insert(PQ* pq, Proc proc) {
62 exists(pq);
63
64 pq->head = n_insert(proc, pq->head);
65}
66
67// Free node and buffer.
68void pq_delete(PQ* pq) {
69 exists(pq);
70 if (pq->head != NULL) {
71 struct Node* kod = pq->head;
72 pq->head = pq->head->next;
73 free(kod->proc.program.buf);
74 free(kod);
75 }
76}
77
78// This function creates a copy of the Proc.
79Proc pq_access(PQ pq) {
80 exists(pq.head);
81 Proc proc = pq.head->proc;
82 exists(proc.program.buf);
83
84 Byte* buf = (Byte*)malloc(sizeof(Byte) * proc.program.len);
85 exists(buf);
86
87 memcpy(buf, proc.program.buf, proc.program.len);
88
89 return (Proc){
90 .time = pq.head->proc.time,
91 .program = (Buffer){
92 .buf = buf,
93 .len = proc.program.len,
94 },
95 };
96}
97
98// This function.
99void pq_print(PQ pq) {
100 struct Node* curr = pq.head;
101 printf("\n");
102 log(INFO, "This is the queue:\n");
103 if (curr != NULL) {
104 printf("[INFO]:");
105 while (curr) {
106 printf("\t(%d, %s)\n", curr->proc.time, curr->proc.program.buf);
107 curr = curr->next;
108 }
109 printf("\n");
110 } else {
111 log(INFO, "Priority Queue is empty.\n");
112 }
113}
114
115// When the head is NULL the list is empty.
116bool pq_empty(PQ pq) {
117 return pq.head == NULL;
118}