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
|
// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;
SC_MODULE(SEMAPHORE) {
sc_semaphore s; // declares semaphore
SC_CTOR(SEMAPHORE) : s(2) { // init semaphore with 2 resources
SC_THREAD(thread_1); // register 3 threads competing for resources
SC_THREAD(thread_2);
SC_THREAD(thread_3);
}
void thread_1() {
while (true) {
if (s.trywait() == -1) { // try to obtain a resource
s.wait(); // if not successful, wait till resource is available
}
std::cout<< sc_time_stamp() << ": locked by thread_1, value is " << s.get_value() << std::endl;
wait(1, SC_SEC); // occupy resource for 1 s
s.post(); // release resource
std::cout<< sc_time_stamp() << ": unlocked by thread_1, value is " << s.get_value() << std::endl;
wait(SC_ZERO_TIME); // give time for the other process to lock
}
}
void thread_2() {
while (true) {
if (s.trywait() == -1) { // try to obtain a resource
s.wait(); // if not successful, wait till resource is available
}
std::cout<< sc_time_stamp() << ": locked by thread_2, value is " << s.get_value() << std::endl;
wait(1, SC_SEC); // occupy resource for 1 s
s.post(); // release resource
std::cout<< sc_time_stamp() << ": unlocked by thread_2, value is " << s.get_value() << std::endl;
wait(SC_ZERO_TIME); // give time for the other process to lock
}
}
void thread_3() {
while (true) {
if (s.trywait() == -1) { // try to obtain a resource
s.wait(); // if not successful, wait till resource is available
}
std::cout<< sc_time_stamp() << ": locked by thread_3, value is " << s.get_value() << std::endl;
wait(1, SC_SEC); // occupy resource for 1 s
s.post(); // release resource
std::cout<< sc_time_stamp() << ": unlocked by thread_3, value is " << s.get_value() << std::endl;
wait(SC_ZERO_TIME); // give time for the other process to lock
}
}
};
int sc_main(int, char*[]) {
SEMAPHORE semaphore("semaphore");
sc_start(4, SC_SEC);
return 0;
}
//Result:
//scheduling pattern: 1&2, then 2&3, then 1&2, then 2&3
//thread_1 locks @ 0 s
0 s: locked by thread_1, value is 1
//thread_2 locks @ 0 s
0 s: locked by thread_2, value is 0
//thread_1 unlocks @ 1 s
1 s: unlocked by thread_1, value is 1
//thread_2 unlocks @ 1 s
1 s: unlocked by thread_2, value is 2
//thread_3 locks @ 1 s
1 s: locked by thread_3, value is 1
//thread_2 locks @ 1 s
1 s: locked by thread_2, value is 0
2 s: unlocked by thread_3, value is 1
2 s: unlocked by thread_2, value is 2
//thread_1 locks @ 2 s
2 s: locked by thread_1, value is 1
//thread_2 locks at 2 s
2 s: locked by thread_2, value is 0
3 s: unlocked by thread_1, value is 1
3 s: unlocked by thread_2, value is 2
//thread_3 locks @ 3 s
3 s: locked by thread_3, value is 1
//thread_2 locks @ 3 s
3 s: locked by thread_2, value is 0
|