xref: /llvm-project/lldb/test/Shell/ExecControl/StopHook/Inputs/stop-hook-threads.cpp (revision fdea9a4ec9b0d9585b8fe8a612686d9f44f40ddc)
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