1*87aa9c9eSJonas Devlieghere #include <chrono>
2*87aa9c9eSJonas Devlieghere #include <cstdio>
3*87aa9c9eSJonas Devlieghere #include <mutex>
4*87aa9c9eSJonas Devlieghere #include <random>
5*87aa9c9eSJonas Devlieghere #include <thread>
6*87aa9c9eSJonas Devlieghere
7*87aa9c9eSJonas Devlieghere std::default_random_engine g_random_engine{std::random_device{}()};
8*87aa9c9eSJonas Devlieghere std::uniform_int_distribution<> g_distribution{0, 3000};
9*87aa9c9eSJonas Devlieghere
10*87aa9c9eSJonas Devlieghere uint32_t g_val = 0;
11*87aa9c9eSJonas Devlieghere uint32_t lldb_val = 0;
12*87aa9c9eSJonas Devlieghere
13*87aa9c9eSJonas Devlieghere uint32_t
access_pool(bool flag=false)14*87aa9c9eSJonas Devlieghere access_pool (bool flag = false)
15*87aa9c9eSJonas Devlieghere {
16*87aa9c9eSJonas Devlieghere static std::mutex g_access_mutex;
17*87aa9c9eSJonas Devlieghere if (!flag)
18*87aa9c9eSJonas Devlieghere g_access_mutex.lock();
19*87aa9c9eSJonas Devlieghere
20*87aa9c9eSJonas Devlieghere uint32_t old_val = g_val;
21*87aa9c9eSJonas Devlieghere if (flag)
22*87aa9c9eSJonas Devlieghere g_val = old_val + 1;
23*87aa9c9eSJonas Devlieghere
24*87aa9c9eSJonas Devlieghere if (!flag)
25*87aa9c9eSJonas Devlieghere g_access_mutex.unlock();
26*87aa9c9eSJonas Devlieghere return g_val;
27*87aa9c9eSJonas Devlieghere }
28*87aa9c9eSJonas Devlieghere
29*87aa9c9eSJonas Devlieghere void
thread_func(uint32_t thread_index)30*87aa9c9eSJonas Devlieghere thread_func (uint32_t thread_index)
31*87aa9c9eSJonas Devlieghere {
32*87aa9c9eSJonas Devlieghere // Break here to test that the stop-hook mechanism works for multiple threads.
33*87aa9c9eSJonas Devlieghere printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
34*87aa9c9eSJonas Devlieghere
35*87aa9c9eSJonas Devlieghere uint32_t count = 0;
36*87aa9c9eSJonas Devlieghere uint32_t val;
37*87aa9c9eSJonas Devlieghere while (count++ < 4)
38*87aa9c9eSJonas Devlieghere {
39*87aa9c9eSJonas Devlieghere // random micro second sleep from zero to .3 seconds
40*87aa9c9eSJonas Devlieghere int usec = g_distribution(g_random_engine);
41*87aa9c9eSJonas Devlieghere printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
42*87aa9c9eSJonas Devlieghere std::this_thread::sleep_for(std::chrono::microseconds{usec}); // Set break point at this line
43*87aa9c9eSJonas Devlieghere
44*87aa9c9eSJonas Devlieghere if (count < 2)
45*87aa9c9eSJonas Devlieghere val = access_pool ();
46*87aa9c9eSJonas Devlieghere else
47*87aa9c9eSJonas Devlieghere val = access_pool (true);
48*87aa9c9eSJonas Devlieghere
49*87aa9c9eSJonas Devlieghere printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
50*87aa9c9eSJonas Devlieghere }
51*87aa9c9eSJonas Devlieghere printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
52*87aa9c9eSJonas Devlieghere }
53*87aa9c9eSJonas Devlieghere
54*87aa9c9eSJonas Devlieghere
main(int argc,char const * argv[])55*87aa9c9eSJonas Devlieghere int main (int argc, char const *argv[])
56*87aa9c9eSJonas Devlieghere {
57*87aa9c9eSJonas Devlieghere std::thread threads[3];
58*87aa9c9eSJonas Devlieghere // Break here to set up the stop hook
59*87aa9c9eSJonas Devlieghere printf("Stop hooks engaged.\n");
60*87aa9c9eSJonas Devlieghere // Create 3 threads
61*87aa9c9eSJonas Devlieghere for (auto &thread : threads)
62*87aa9c9eSJonas Devlieghere thread = std::thread{thread_func, std::distance(threads, &thread)};
63*87aa9c9eSJonas Devlieghere
64*87aa9c9eSJonas Devlieghere // Join all of our threads
65*87aa9c9eSJonas Devlieghere for (auto &thread : threads)
66*87aa9c9eSJonas Devlieghere thread.join();
67*87aa9c9eSJonas Devlieghere
68*87aa9c9eSJonas Devlieghere // print lldb_val so we can check it here.
69*87aa9c9eSJonas Devlieghere printf ("lldb_val was set to: %d.\n", lldb_val);
70*87aa9c9eSJonas Devlieghere return 0;
71*87aa9c9eSJonas Devlieghere }
72