-
Notifications
You must be signed in to change notification settings - Fork 0
/
usemaphore.c
42 lines (39 loc) · 1.14 KB
/
usemaphore.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
#include "types.h"
#include "stat.h"
#include "user.h"
#include "fs.h"
#include "uthread.h"
#include "usemaphore.h"
struct counting_semaphore * allocSem(int enterVal) {
struct counting_semaphore *semPtr = (struct counting_semaphore *)malloc(sizeof(struct counting_semaphore));
int binSemNum1 = bsem_alloc();
int binSemNum2 = bsem_alloc();
if (binSemNum1 == -1 || binSemNum2 == -1)
return 0; //There are no binary semaphores available to implement a counting semaphore
semPtr->binSemNum1 = binSemNum1;
semPtr->binSemNum2 = binSemNum2;
if (enterVal == 0)
bsem_down(semPtr->binSemNum2); //bSem init val = min(1, enterVal);
semPtr->value = enterVal;
return semPtr;
}
void freeSem(struct counting_semaphore *sem) {
bsem_free(sem->binSemNum1);
bsem_free(sem->binSemNum2);
free(sem);
}
void down(struct counting_semaphore *sem) {
bsem_down(sem->binSemNum2);
bsem_down(sem->binSemNum1);
sem->value--;
if (sem->value > 0)
bsem_up(sem->binSemNum2);
bsem_up(sem->binSemNum1);
}
void up (struct counting_semaphore *sem) {
bsem_down(sem->binSemNum1);
sem->value++;
if (sem->value == 1)
bsem_up(sem->binSemNum2);
bsem_up(sem->binSemNum1);
}