-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocks.cpp
69 lines (46 loc) · 1.25 KB
/
locks.cpp
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
/*
* locks.cpp
*
* Created on: Apr 24, 2011
* Author: changokkim
*/
#include <time.h>
#include "locks.h"
namespace baseLock {
Spinlock::Spinlock()
: locked_(false) {
}
Spinlock::~Spinlock() {
}
void Spinlock::lock() {
int failed = 0; // for watching failed times
struct timespec tim, tim2; // for sleeping time
// loop until locked_ is releasd
while (__sync_lock_test_and_set(&locked_, true)) {
// sleep time: 10 nano seconds
tim.tv_nsec = 10;
// test on local cache to see until lock is released
while( locked_ == true) {
// increase failed count
failed++;
// if failed to grab lock more than 10 times, sleep
if( failed > 10) {
nanosleep( &tim, &tim2);
// if timed waited nanosecond is higher than 1000 nanosecond, increase by 1 instead of exponentially to prevent possibility of starvation
if( tim.tv_nsec < 1000) {
tim.tv_nsec = tim.tv_nsec * 2;
} else if( tim.tv_nsec > 4000) {
tim.tv_nsec = tim.tv_nsec = 10;
} else {
tim.tv_nsec = tim.tv_nsec + 10;
}
// initialize faled count
failed = 0;
}
}
}
}
void Spinlock::unlock() {
__sync_lock_release(&locked_);
}
} // namespace base