7
7
#include < iostream>
8
8
#include < thread>
9
9
10
- static constexpr int NUM_ITERATIONS = 15 ; // total iterations; each has a scenario
11
- static constexpr auto MAX_BLOCK_MS = 5000 ; // 5s => generous for slow/VM systems
10
+ static constexpr int NUM_ITERATIONS = 15 ; // total iterations; each has a scenario
11
+ static constexpr auto MAX_BLOCK_MS = 5000 ; // 5s => generous for slow/VM systems
12
12
13
- // Shared data for consumer/producer synchronization
14
- static std::mutex g_mutex;
13
+ // / Shared data for consumer/producer synchronization
14
+ static std::mutex g_mutex;
15
15
static std::condition_variable g_cv;
16
16
17
- // Let consumer tell producer "I just set the park bit"
17
+ // / Let consumer tell producer "I just set the park bit"
18
18
static bool g_consumerReady = false ;
19
19
20
- // Let producer tell consumer "I have woken you (or tried to wake you)"
20
+ // / Let producer tell consumer "I have woken you (or tried to wake you)"
21
21
static bool g_wakeDone = false ;
22
22
23
- // We’ll store test failures if we detect a lost wake
24
- static std::atomic< bool > g_testFailed{false };
23
+ // / We’ll store test failures if we detect a lost wake
24
+ static std::atomic g_testFailed{false };
25
25
26
- int main ()
27
- {
26
+ int main () {
28
27
// 1) Create our thread parking handle
29
- tpark_handle_t * handle = tparkCreateHandle ();
28
+ tpark_handle_t * handle = tparkCreateHandle ();
30
29
31
30
// 2) Producer: wakes the consumer under different timing scenarios
32
31
std::thread producer ([&]() {
33
- for (int i = 0 ; i < NUM_ITERATIONS && !g_testFailed.load (); i++)
34
- {
32
+ for (int i = 0 ; i < NUM_ITERATIONS && !g_testFailed.load (); i++) {
35
33
// Acquire lock and wait until consumer sets the park bit
36
- std::unique_lock<std::mutex> lk (g_mutex);
34
+ std::unique_lock lk (g_mutex);
37
35
g_cv.wait (lk, [] { return g_consumerReady || g_testFailed.load (); });
38
36
if (g_testFailed.load ()) break ;
39
37
40
38
// Decide how long to wait before calling wake
41
39
// scenario 0 = immediate
42
40
// scenario 1 = 100 ms
43
41
// scenario 2 = 500 ms
44
- int scenario = i % 3 ;
45
- auto sleepMs = (scenario == 0 ) ? 0
46
- : (scenario == 1 ) ? 100
47
- : 500 ;
42
+ const int scenario = i % 3 ;
43
+ auto sleepMs = (scenario == 0 )
44
+ ? 0
45
+ : (scenario == 1 )
46
+ ? 100
47
+ : 500 ;
48
48
49
49
// Sleep some time to let the consumer possibly call parkWait
50
50
lk.unlock ();
@@ -63,16 +63,15 @@ int main()
63
63
64
64
// 3) Consumer: sets the park bit, signals producer, then calls parkWait
65
65
std::thread consumer ([&]() {
66
- for (int i = 0 ; i < NUM_ITERATIONS; i++)
67
- {
66
+ for (int i = 0 ; i < NUM_ITERATIONS; i++) {
68
67
// 3.1) "Begin Park": set bit=1
69
68
{
70
- std::unique_lock<std::mutex> lk (g_mutex);
69
+ std::unique_lock lk (g_mutex);
71
70
tparkBeginPark (handle);
72
71
73
72
// Indicate "ready" so producer knows to do a wake
74
73
g_consumerReady = true ;
75
- g_wakeDone = false ;
74
+ g_wakeDone = false ;
76
75
g_cv.notify_one ();
77
76
78
77
// Wait until producer has definitely done a wake attempt
@@ -86,11 +85,10 @@ int main()
86
85
tparkWait (handle, /* unlocked=*/ true );
87
86
auto t2 = std::chrono::steady_clock::now ();
88
87
89
- auto msBlocked = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count ();
90
- if (msBlocked > MAX_BLOCK_MS)
91
- {
88
+ if (const auto msBlocked = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count ();
89
+ msBlocked > MAX_BLOCK_MS) {
92
90
std::cerr << " [Iteration " << i << " ] BLOCKED too long ("
93
- << msBlocked << " ms). Potential lost wake or deadlock.\n " ;
91
+ << msBlocked << " ms). Potential lost wake or deadlock.\n " ;
94
92
g_testFailed.store (true );
95
93
return ;
96
94
}
0 commit comments