



#ifndef OPERATING_SYSTEM_GENERALBLOCKEDQUEUE_H
#define OPERATING_SYSTEM_GENERALBLOCKEDQUEUE_H
#define MAX_PROCESSES 3
#include "Process.h"
typedef struct {
Process *queue[MAX_PROCESSES];
int front;
int rear;
int capacity;
} BlockedQueue;
void init_BlockedQueue(BlockedQueue *blockedQueue) {
blockedQueue->front = 0;
blockedQueue->rear = -1;
blockedQueue->capacity = MAX_PROCESSES;
}
int isBlockedEmpty(BlockedQueue* queues) {
return queues->rear == -1;
}
int isBlockedFull(BlockedQueue* queues) {
return queues->rear+1 == queues->capacity;
}
void printBlocked(BlockedQueue* queue){
printf("General Blocked Queue: ");
for(int i = 0; i <= queue->rear; i++){
printf("%d ",queue->queue[i]->pcb->processID);
}
printf("\n");
}
void enqueueBlocked(BlockedQueue *queue, Process * process) {
if(isBlockedFull(queue)){
printf("Queue is Full\n");
return;
}
queue->queue[++queue->rear] = process;
printf("\n");
printf("enqueue process %d\n", process->pcb->processID);
printBlocked(queue);
printf("\n");
}
void dequeueBlocked(BlockedQueue *queue, Process* unblocked) {
if(isBlockedEmpty(queue)){
printf("General Blocked queue is empty\n");
return;
}
int removed = -1;
for(int i = 0; i <= queue->rear; i++){
if(queue->queue[i] == unblocked){
// or check if processId's are equal, if something goes wrong
removed = i;
}
}
int id = queue->queue[removed]->pcb->processID;
for(int i = removed; i < queue->rear; i++){
queue->queue[i] = queue->queue[i+1];
}
queue->rear--;
printf("\n");
printf("dequeue process %d\n", id);
printBlocked(queue);
printf("\n");
}
#endif //OPERATING_SYSTEM_GENERALBLOCKEDQUEUE_H
#ifndef OPERATING_SYSTEM_MUTEX_H
#define OPERATING_SYSTEM_MUTEX_H
#include "Process.h"
#include "GeneralBlockedQueue.h"
typedef struct {
Process* queue[3];
int front;
int rear;
int capacity;
}LockQueue;
typedef struct {
enum {zero,one} value;
char resourceName[10];
LockQueue queue;
int ownerID;
}MUTEX;
enum state {Failed = -1, Success = 0, Blocked = 1};
void init_mutex(MUTEX *mutex, char name[]) {
mutex->value = one; // Assuming 'zero' means unlocked. No 'one means unlocked you twat
strcpy(mutex->resourceName,name);
mutex->queue.front = 0;
mutex->queue.rear = -1;
mutex->queue.capacity = 3;
mutex->ownerID = -1; // No owner initially
}
int isLockQueueEmpty(LockQueue* queues) {
return queues->rear == -1;
}
int isLockQueueFull(LockQueue* queues) {
return queues->rear+1 == queues->capacity;
}
void printMutexQ(MUTEX *m){
printf("Mutex🔒 %s ownerID: %d\n", m->resourceName, m->ownerID);
printf("🔒LockQueue🔒: ");
for(int i = 0; i<=m->queue.rear; i++){
printf("%d ", m->queue.queue[i]->pcb->processID);
}
printf("\n");
}
void enqueueLock(LockQueue *queue, Process * process) {
if(isLockQueueFull(queue)){
printf("Queue is Full\n");
return;
}
queue->queue[++queue->rear] = process;
}
Process* dequeueLock(LockQueue *queue) {
int highest = 5;
int highi = 0;
for(int i = 0; i < queue->rear; i++){
if(queue->queue[i]->pcb->currentPriority < highest){
highest = queue->queue[i]->pcb->currentPriority;
highi = i;
}
}
Process *process = queue->queue[highi];
for(int i = highi; i < queue->rear; i++){
queue->queue[i] = queue->queue[i+1];
}
queue->rear--;
return process;
}
enum state semWait(MUTEX *m , Process * p) {
if (m->value == one) {
m->ownerID = p->pcb->processID;
m->value = zero;
return Success;
}
printf("\n");
enqueueLock(&m->queue,p);
printMutexQ(m);
printf("\n");
return Blocked;
}
Process *semSignal(MUTEX *m , Process* p) {
if(m->ownerID == p->pcb->processID){
if (isLockQueueEmpty(&m->queue)){
m->value = one;
m->ownerID = -1;
return NULL;
}
else {
printf("\n");
Process * proc = dequeueLock(&m->queue);
m->ownerID = proc->pcb->processID;
printMutexQ(m);
printf("\n");
return proc;
}
}
return NULL;
}
#endif //OPERATING_SYSTEM_MUTEX_H
struct binary_semaphore {
enum {zero,one} value;
queueType queue;
};
void semWaitB(binary_semaphore s) {
if (s.value == one)
s.value = zero;
else {
/* place this process in s.queue */
}
}
void semSignalB(semaphore s) {
if (s.queue.isEmpty())
s.value = one;
else {
/* remove a process P from s.queue and place it on ready list*/
}
}
Counting Semaphore
struct semaphore {
int count;
queueType queue;
};
void semWait(semaphore s) {
s.count--;
if (s.count < 0) {
/* place this process in s.queue */
/* block this process */
}
}
void semSignal(semaphore s) {
S.count++;
if (s.count <= 0) {
/* remove a process P from s.queue and place it on ready list*/
}
}
These synchronization techniques are crucial in concurrent and real-time systems to ensure the correct and efficient execution of tasks, preventing issues like race conditions, deadlocks, and priority inversion.