-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy paththreads_attack.c
86 lines (72 loc) · 1.74 KB
/
threads_attack.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
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
const int NUM_ITERS = 1000000;
const int NUM_THREADS = 2;
typedef struct {
_Atomic bool thread0WantsLock;
_Atomic bool thread1WantsLock;
_Atomic int turn;
} MyLock;
void acquireLock(MyLock* lock, int threadIdx) {
if (threadIdx == 0) {
lock->thread0WantsLock = true;
lock->turn = 1;
while (lock->thread1WantsLock && (lock->turn == 1)) {
// Busy loop.
}
} else {
lock->thread1WantsLock = true;
lock->turn = 0;
while (lock->thread0WantsLock && (lock->turn == 0)) {
// Busy loop.
}
}
}
void releaseLock(MyLock* lock, int threadIdx) {
if (threadIdx == 0) {
lock->thread0WantsLock = false;
} else {
lock->thread1WantsLock = false;
}
}
typedef struct {
int threadIdx;
int* result;
MyLock* lock;
} ThreadArgument;
void* thread_work(void* _argument) {
// Cast.
ThreadArgument* threadArgument = (ThreadArgument*) _argument;
for (int i = 0; i < NUM_ITERS; i++) {
acquireLock(threadArgument->lock, threadArgument->threadIdx);
*(threadArgument->result) += 1;
releaseLock(threadArgument->lock, threadArgument->threadIdx);
}
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
int result = 0;
MyLock lock = {
.thread0WantsLock = false,
.thread1WantsLock = false,
.turn = -1
};
ThreadArgument arg0 = {
.threadIdx = 0,
.result = &result,
.lock = &lock
};
ThreadArgument arg1 = {
.threadIdx = 1,
.result = &result,
.lock = &lock
};
pthread_create(&threads[0], NULL, thread_work, &arg0);
pthread_create(&threads[1], NULL, thread_work, &arg1);
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
printf("Result: %d\n", result);
return 0;
}