-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmysemaphore.h
71 lines (53 loc) · 1.51 KB
/
mysemaphore.h
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
typedef struct
{
unsigned int count;
unsigned long waiters_count;
pthread_mutex_t lock;
pthread_cond_t count_nonzero;
} my_sem_t;
int my_sem_init(my_sem_t *s, int shared, unsigned int initial_count) {
int rc;
rc = pthread_mutex_init(&s->lock, NULL);
if (rc != 0) return rc;
rc = pthread_cond_init(&s->count_nonzero, NULL);
if (rc != 0) return rc;
s->count = initial_count;
s->waiters_count = 0;
return 0;
}
int my_sem_wait(my_sem_t *s) {
// Acquire mutex to enter critical section.
pthread_mutex_lock(&s->lock);
// Keep track of the number of waiters so that <sem_post> works correctly.
s->waiters_count++;
// Wait until the semaphore count is > 0, then atomically release
// <lock> and wait for <count_nonzero> to be signaled.
while (s->count == 0)
pthread_cond_wait(&s->count_nonzero, &s->lock);
// <s->lock> is now held.
// Decrement the waiters count.
s->waiters_count--;
// Decrement the semaphore's count.
s->count--;
// Release mutex to leave critical section.
pthread_mutex_unlock(&s->lock);
return 0;
}
int my_sem_post(my_sem_t *s) {
pthread_mutex_lock(&s->lock);
// Always allow one thread to continue if it is waiting.
if (s->waiters_count > 0)
pthread_cond_signal(&s->count_nonzero);
// Increment the semaphore's count.
s->count++;
pthread_mutex_unlock(&s->lock);
return 0;
}
int my_sem_destroy(my_sem_t *s) {
int rc;
rc = pthread_mutex_destroy(&s->lock);
if (rc != 0) return rc;
rc = pthread_cond_destroy(&s->count_nonzero);
if (rc != 0) return rc;
return 0;
}