diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0a223d9 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +CC = gcc-13 +CFLAGS = -Wall -Wextra +BIN = ./out + +TARGETS = init scheduler + +all: $(TARGETS) + +init: init.c + $(CC) $(CFLAGS) -o $(BIN)/init init.c + +scheduler: scheduler.c + $(CC) $(CFLAGS) -o $(BIN)/scheduler scheduler.c + +clean: + rm -f $(TARGETS) + +.PHONY: all clean diff --git a/init.c b/init.c new file mode 100644 index 0000000..94103b7 --- /dev/null +++ b/init.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include + +#define NUM_PROCS 4 +#define SHM_SIZE 1024 +#define PATHNAME "." +#define PROJ_ID 65 + +void write_pipes(int pipefds[][2], pid_t pids[]) { + for (int i = 0; i < NUM_PROCS; i++) { + // Creation of a pipe (child -> parent) + if (pipe(pipefds[i]) == -1) { + perror("[!] Pipe failed"); + exit(EXIT_FAILURE); + } + + // Creation of a fork + pids[i] = fork(); + + if (pids[i] == -1) { + perror("[!] Fork failed"); + exit(EXIT_FAILURE); + } + + // If the fork is successfully created + if (pids[i] == 0) { + // Read end of the pipe is closed before writing (sync) + close(pipefds[i][0]); + + // Random priority in the range 0-19 + srand(time(NULL) ^ getpid()); + int priority = rand() % 20; + + // Writing to the pipe and closing it afterwards (sync) + write(pipefds[i][1], &priority, sizeof(priority)); + close(pipefds[i][1]); + + printf("[P%d] Wrote %d into pipe\n", i + 1, priority); + + exit(0); + } + } +} + +void read_pipes(int pipefds[][2], int priorities[]) { + for (int i = 0; i < NUM_PROCS; i++) { + // Write end of the pipe is closed before reading (sync) + close(pipefds[i][1]); + + // Reading from the pipe and closing it afterwards (sync) + read(pipefds[i][0], &priorities[i], sizeof(priorities[i])); + close(pipefds[i][0]); + + printf("[INIT] Read %d from P%d\n", priorities[i], i + 1); + } +} + +void write_mem_segment(int priorities[]) { + int *shm_array; + int shmid; + + key_t key = ftok(PATHNAME, PROJ_ID); + + // Get the segment identifier + if ((shmid = shmget(key, SHM_SIZE, 0666)) < 0) { + perror("[!] Shmget failed"); + exit(EXIT_FAILURE); + } + + // Attach (system chooses a suitable address) + if ((shm_array = (int *)shmat(shmid, NULL, 0)) == (int *)-1) { + perror("[!] Shmat failed"); + exit(EXIT_FAILURE); + } + + printf("[INIT] Connected to shared segment at %p (%d)\n", (void *)&shm_array, + shmid); + + // Write + for (int i = 0; i < NUM_PROCS; i++) { + shm_array[i] = priorities[i]; + } + + // Detach + shmdt(shm_array); + + printf("[INIT] Wrote priorities to shared memory\n"); +} + +int main() { + int pipefds[NUM_PROCS][2]; + pid_t pids[NUM_PROCS]; + + // Creation of forks, their respective pipes, and random priorities + write_pipes(pipefds, pids); + + int priorities[NUM_PROCS]; + + // Reading priorities from the pipes + read_pipes(pipefds, priorities); + + // Attaching and writing priorities to a shared memory segment + write_mem_segment(priorities); + + return 0; +} diff --git a/scheduler.c b/scheduler.c new file mode 100644 index 0000000..955e080 --- /dev/null +++ b/scheduler.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include + +#define NUM_PROCS 4 +#define SHM_SIZE 1024 +#define PATHNAME "." +#define PROJ_ID 65 + +int create_mem_segment(int **shm_array) { + int shmid; + key_t key = ftok(PATHNAME, PROJ_ID); + + // Create a new shared segment + if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) < 0) { + perror("[!] Shmget failed"); + exit(EXIT_FAILURE); + } + + // Attach (system chooses a suitable address) + if ((*shm_array = (int *)shmat(shmid, NULL, 0)) == (int *)-1) { + perror("[!] Shmat failed"); + exit(EXIT_FAILURE); + } + + return shmid; +} + +int compare(const void *a, const void *b) { return (*(int *)a - *(int *)b); } + +int main() { + int *shm_array; + + int delay = 5; + + // Creation and attaching into a new shared segment + int shmid = create_mem_segment(&shm_array); + printf("[SCHEDULER] Shared segment created at %p (%d)\n", (void *)shm_array, + shmid); + + // Wait until init has finished writing into the segment + printf("[SCHEDULER] Sleeping for %d seconds before reading\n", delay); + sleep(delay); + + // Copying array to a local variable + int priorities[NUM_PROCS]; + + for (int i = 0; i < NUM_PROCS; i++) { + priorities[i] = shm_array[i]; + } + + // TODO: "After scheduler prints the data, init should detach from shared + // memory" -> Some mechanism to indicate when init has detached must be put in + // place + + // Detaching and deleting the segment + shmdt(shm_array); + shmctl(shmid, IPC_RMID, NULL); + + // Sorting and printing the priorities + qsort(&priorities, NUM_PROCS, sizeof(int), compare); + + printf("[SCHEDULER] Priorities: "); + + for (int i = 0; i < NUM_PROCS; i++) { + printf("%d ", priorities[i]); + } + + printf("\n"); + + return 0; +}