-
Notifications
You must be signed in to change notification settings - Fork 0
/
shared_queue.c
123 lines (98 loc) · 2.72 KB
/
shared_queue.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#define MAX_QUEUE_SIZE 30
#define MAX_ITEM_SIZE 128
typedef struct Process {
char executable[MAX_ITEM_SIZE];
pid_t pid;
int priority;
} Process;
typedef struct PriorityQueue {
Process processes[MAX_QUEUE_SIZE];
int rear;
int num_process;
sem_t mutex;
sem_t empty;
sem_t full;
} PriorityQueue;
int create_priority_queue(key_t key, PriorityQueue **queue);
void enqueue(PriorityQueue* queue, const Process* process);
int dequeue(PriorityQueue* queue, Process* process);
void destroy_priority_queue(PriorityQueue *queue);
int get_rear(PriorityQueue* queue);
int get_num_process(PriorityQueue* queue);
int is_empty(PriorityQueue *queue) {
sem_wait(&queue->mutex);
int empty = (queue->rear == -1);
sem_post(&queue->mutex);
return empty;
}
int is_full(PriorityQueue *queue) {
sem_wait(&queue->mutex);
int full = (queue->rear == MAX_QUEUE_SIZE - 1);
sem_post(&queue->mutex);
return full;
}
int create_priority_queue(key_t key, PriorityQueue **queue) {
int shmid = shmget(key, sizeof(PriorityQueue), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
return -1;
}
*queue = (PriorityQueue *)shmat(shmid, NULL, 0);
if (*queue == (PriorityQueue *)(-1)) {
perror("shmat");
return -1;
}
sem_init(&(*queue)->mutex, 1, 1);
sem_init(&(*queue)->empty, 1, MAX_QUEUE_SIZE);
sem_init(&(*queue)->full, 1, 0);
(*queue)->num_process = 0;
(*queue)->rear = -1;
return 0;
}
void enqueue(PriorityQueue* queue, const Process* process) {
sem_wait(&queue->empty);
sem_wait(&queue->mutex);
queue->rear++;
queue->processes[queue->rear] = *process;
queue->num_process++;
sem_post(&queue->mutex);
sem_post(&queue->full);
}
int dequeue(PriorityQueue* queue, Process* process) {
if (queue->rear == -1) {
return 0; // Queue is empty
}
sem_wait(&queue->full);
sem_wait(&queue->mutex);
*process = queue->processes[0];
for (int i = 0; i < queue->rear; i++) {
queue->processes[i] = queue->processes[i + 1];
}
queue->num_process--;
queue->rear--;
sem_post(&queue->mutex);
sem_post(&queue->empty);
return 1; // Successfully dequeued
}
void destroy_priority_queue(PriorityQueue *queue) {
shmdt(queue);
}
int get_rear(PriorityQueue *queue) {
sem_wait(&queue->mutex);
int ret = queue->rear;
sem_post(&queue->mutex);
return ret;
}
int get_num_process(PriorityQueue* queue){
sem_wait(&queue->mutex);
int ret = queue->num_process;
sem_post(&queue->mutex);
return ret;
}