1#include <chrono>
2#include <condition_variable>
3#include <cstdio>
4#include <random>
5#include <thread>
6
7std::default_random_engine g_random_engine{std::random_device{}()};
8std::uniform_int_distribution<> g_distribution{0, 3000000};
9std::condition_variable g_condition_variable;
10std::mutex g_mutex;
11int g_count;
12
13char *g_char_ptr = nullptr;
14
15void
16barrier_wait()
17{
18 std::unique_lock<std::mutex> lock{g_mutex};
19 if (--g_count > 0)
20 g_condition_variable.wait(lock&: lock);
21 else
22 g_condition_variable.notify_all();
23}
24
25void
26do_bad_thing_with_location(char *char_ptr, char new_val)
27{
28 *char_ptr = new_val;
29}
30
31uint32_t
32access_pool (bool flag = false)
33{
34 static std::mutex g_access_mutex;
35 if (!flag)
36 g_access_mutex.lock();
37
38 char old_val = *g_char_ptr;
39 if (flag)
40 do_bad_thing_with_location(char_ptr: g_char_ptr, new_val: old_val + 1);
41
42 if (!flag)
43 g_access_mutex.unlock();
44 return *g_char_ptr;
45}
46
47void
48thread_func (uint32_t thread_index)
49{
50 printf (format: "%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
51
52 barrier_wait();
53
54 uint32_t count = 0;
55 uint32_t val;
56 while (count++ < 15)
57 {
58 // random micro second sleep from zero to 3 seconds
59 int usec = g_distribution(g_random_engine);
60 printf (format: "%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
61 std::this_thread::sleep_for(rtime: std::chrono::microseconds{usec});
62
63 if (count < 7)
64 val = access_pool ();
65 else
66 val = access_pool (flag: true);
67
68 printf (format: "%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
69 }
70 printf (format: "%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
71}
72
73
74int main (int argc, char const *argv[])
75{
76 g_count = 4;
77 std::thread threads[3];
78
79 g_char_ptr = new char{};
80
81 // Create 3 threads
82 for (auto &thread : threads)
83 thread = std::thread{thread_func, std::distance(first: threads, last: &thread)};
84
85 printf (format: "Before turning all three threads loose...\n"); // Set break point at this line.
86 barrier_wait();
87
88 // Join all of our threads
89 for (auto &thread : threads)
90 thread.join();
91
92 delete g_char_ptr;
93
94 return 0;
95}
96

source code of lldb/test/API/python_api/watchpoint/watchlocation/main.cpp