feat: update structure
This commit is contained in:
55
cs2106/labs/lab3/progs/part2/barrier.c
Normal file
55
cs2106/labs/lab3/progs/part2/barrier.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
int nproc = 0;
|
||||
// count must be a semaphore
|
||||
int *count;
|
||||
sem_t *barrier;
|
||||
sem_t *countMut;
|
||||
int barrierShmId, countShmId, countMutShmId;
|
||||
|
||||
void init_barrier(int numproc) {
|
||||
nproc = numproc;
|
||||
barrierShmId = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600);
|
||||
countMutShmId = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0600);
|
||||
|
||||
countShmId = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600);
|
||||
|
||||
barrier = (sem_t *)shmat(barrierShmId, NULL, 0);
|
||||
countMut = (sem_t *)shmat(countMutShmId, NULL, 0);
|
||||
|
||||
count = (int *)shmat(countShmId, NULL, 0);
|
||||
sem_init(barrier, 1, 0);
|
||||
sem_init(countMut, 1, 1);
|
||||
}
|
||||
|
||||
void reach_barrier() {
|
||||
sem_wait(countMut);
|
||||
*count += 1;
|
||||
sem_post(countMut);
|
||||
if (*count == nproc) {
|
||||
sem_post(barrier);
|
||||
} else {
|
||||
sem_wait(barrier);
|
||||
sem_post(barrier);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_barrier(int my_pid) {
|
||||
if (my_pid != 0) {
|
||||
sem_destroy(barrier);
|
||||
sem_destroy(countMut);
|
||||
shmdt(count);
|
||||
shmdt(barrier);
|
||||
shmdt(countMut);
|
||||
shmctl(countShmId, IPC_RMID, 0);
|
||||
shmctl(barrierShmId, IPC_RMID, 0);
|
||||
shmctl(countMutShmId, IPC_RMID, 0);
|
||||
// Destroy the semaphores and detach
|
||||
// and free any shared memory. Notice
|
||||
// that we explicity check that it is
|
||||
// the parent doing it.
|
||||
}
|
||||
}
|
||||
3
cs2106/labs/lab3/progs/part2/barrier.h
Normal file
3
cs2106/labs/lab3/progs/part2/barrier.h
Normal file
@@ -0,0 +1,3 @@
|
||||
void init_barrier(int);
|
||||
void reach_barrier();
|
||||
void destroy_barrier(int);
|
||||
48
cs2106/labs/lab3/progs/part2/test_barrier.c
Normal file
48
cs2106/labs/lab3/progs/part2/test_barrier.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
#include "barrier.h"
|
||||
|
||||
#define NUM_PROCESSES 6
|
||||
#define MAX_SLEEP 1000000 // Maximum sleep period in microseconds
|
||||
|
||||
int main() {
|
||||
int i, pid;
|
||||
int sleep_time[NUM_PROCESSES];
|
||||
|
||||
init_barrier(NUM_PROCESSES+1);
|
||||
|
||||
srand(time(NULL));
|
||||
for(i=0; i<NUM_PROCESSES; i++) {
|
||||
|
||||
// The children will all slip at different amounts of time
|
||||
sleep_time[i] = (int) (((float) rand() / RAND_MAX) * MAX_SLEEP);
|
||||
if((pid = fork()) == 0) {
|
||||
srand(time(NULL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(pid == 0) {
|
||||
usleep(sleep_time[i]);
|
||||
|
||||
// Reach the barrier.
|
||||
printf("\tChild %d slept for %3.2f seconds and has now reached the barrier\n", i, sleep_time[i]/1000000.0);
|
||||
reach_barrier();
|
||||
}
|
||||
else {
|
||||
// Parent will just wait at barrier for all children to return
|
||||
printf("**Parent waiting for children**\n\n");
|
||||
reach_barrier();
|
||||
printf("\n**All the children have returned**\n");
|
||||
|
||||
// Clean up the process table
|
||||
for(i=0; i<NUM_PROCESSES; i++)
|
||||
wait(NULL);
|
||||
|
||||
destroy_barrier(pid);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user