-
Notifications
You must be signed in to change notification settings - Fork 0
/
semaphore.cc
56 lines (49 loc) · 1.46 KB
/
semaphore.cc
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
#include "semaphore.h"
#include "cpu.h"
#include "thread.h"
#include "traits.h"
#include "debug.h"
__BEGIN_API
Semaphore::~Semaphore() {
db<Semaphore>(TRC) << "~Semaphore()\n";
wakeup_all();
}
void Semaphore::p() {
db<Semaphore>(TRC) << "Semaphore p(): Thread id="<< Thread::running()->id() << " count:" << _count << "\n";
if (_count == 0)
sleep();
else
fdec(_count);
}
void Semaphore::v() {
db<Semaphore>(TRC) << "Semaphore v(): Thread id="<< Thread::running()->id() << " count:" << _count << "\n";
if (_count == 0 && !_threads.empty())
wakeup();
else
finc(_count);
}
int Semaphore::finc(volatile int & number) {
db<Semaphore>(TRC) << "Semaphore finc():\n";
return CPU::finc(number);
}
int Semaphore::fdec(volatile int & number) {
db<Semaphore>(TRC) << "Semaphore fdec():\n";
return CPU::fdec(number);
}
void Semaphore::sleep() {
db<Semaphore>(TRC) << "Semaphore sleep(): Thread id="<< Thread::running()->id() << " \n";
_threads.insert(Thread::running()->link());
Thread::running()->sleep(&_threads);
}
void Semaphore::wakeup() {
Thread* waking_thread = _threads.remove()->object();
db<Semaphore>(TRC) << "Semaphore wakeup(): Thread id="<< waking_thread->id() << " \n";
waking_thread->wakeup();
}
void Semaphore::wakeup_all() {
db<Semaphore>(TRC) << "Semaphore wakeup_all()\n";
while (!_threads.empty()) {
_threads.remove()->object()->wakeup();
}
}
__END_API