@@ -40,11 +40,14 @@ class BAIDU_CACHELINE_ALIGNMENT ParkingLot {
40
40
int val;
41
41
};
42
42
43
- ParkingLot () : _pending_signal(0 ) {}
43
+ ParkingLot () : _pending_signal(0 ), _waiter_num( 0 ) {}
44
44
45
45
// Wake up at most `num_task' workers.
46
46
// Returns #workers woken up.
47
47
int signal (int num_task) {
48
+ if (_waiter_num.load (butil::memory_order_relaxed) == 0 ) {
49
+ return 0 ;
50
+ }
48
51
_pending_signal.fetch_add ((num_task << 1 ), butil::memory_order_release);
49
52
return futex_wake_private (&_pending_signal, num_task);
50
53
}
@@ -57,7 +60,9 @@ class BAIDU_CACHELINE_ALIGNMENT ParkingLot {
57
60
// Wait for tasks.
58
61
// If the `expected_state' does not match, wait() may finish directly.
59
62
void wait (const State& expected_state) {
63
+ _waiter_num.fetch_add (1 , butil::memory_order_relaxed);
60
64
futex_wait_private (&_pending_signal, expected_state.val , NULL );
65
+ _waiter_num.fetch_sub (1 , butil::memory_order_relaxed);
61
66
}
62
67
63
68
// Wakeup suspended wait() and make them unwaitable ever.
@@ -68,6 +73,7 @@ class BAIDU_CACHELINE_ALIGNMENT ParkingLot {
68
73
private:
69
74
// higher 31 bits for signalling, LSB for stopping.
70
75
butil::atomic<int > _pending_signal;
76
+ butil::atomic<int > _waiter_num;
71
77
};
72
78
73
79
} // namespace bthread
0 commit comments