]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - packages/Python/lldbsuite/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / packages / Python / lldbsuite / test / functionalities / watchpoint / watchpoint_set_command / main.cpp
1 //===-- main.cpp ------------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <chrono>
11 #include <condition_variable>
12 #include <cstdio>
13 #include <random>
14 #include <thread>
15
16 std::default_random_engine g_random_engine{std::random_device{}()};
17 std::uniform_int_distribution<> g_distribution{0, 3000000};
18 std::condition_variable g_condition_variable;
19 std::mutex g_mutex;
20 int g_count;
21
22 char *g_char_ptr = nullptr;
23
24 void
25 barrier_wait()
26 {
27     std::unique_lock<std::mutex> lock{g_mutex};
28     if (--g_count > 0)
29         g_condition_variable.wait(lock);
30     else
31         g_condition_variable.notify_all();
32 }
33
34 void
35 do_bad_thing_with_location(unsigned index, char *char_ptr, char new_val)
36 {
37     unsigned what = new_val;
38     printf("new value written to array(%p) and index(%u) = %u\n", char_ptr, index, what);
39     char_ptr[index] = new_val;
40 }
41
42 uint32_t
43 access_pool (bool flag = false)
44 {
45     static std::mutex g_access_mutex;
46     static unsigned idx = 0; // Well-behaving thread only writes into indexs from 0..6.
47     if (!flag)
48         g_access_mutex.lock();
49
50     // idx valid range is [0, 6].
51     if (idx > 6)
52         idx = 0;
53
54     if (flag)
55     {
56         // Write into a forbidden area.
57         do_bad_thing_with_location(7, g_char_ptr, 99);
58     }
59
60     unsigned index = idx++;
61
62     if (!flag)
63         g_access_mutex.unlock();
64     return g_char_ptr[index];
65 }
66
67 void
68 thread_func (uint32_t thread_index)
69 {
70     printf ("%s (thread index = %u) startng...\n", __FUNCTION__, thread_index);
71
72     barrier_wait();
73
74     uint32_t count = 0;
75     uint32_t val;
76     while (count++ < 15)
77     {
78         // random micro second sleep from zero to 3 seconds
79         int usec = g_distribution(g_random_engine);
80         printf ("%s (thread = %u) doing a usleep (%d)...\n", __FUNCTION__, thread_index, usec);
81         std::this_thread::sleep_for(std::chrono::microseconds{usec});
82
83         if (count < 7)
84             val = access_pool ();
85         else
86             val = access_pool (true);
87
88         printf ("%s (thread = %u) after usleep access_pool returns %d (count=%d)...\n", __FUNCTION__, thread_index, val, count);
89     }
90     printf ("%s (thread index = %u) exiting...\n", __FUNCTION__, thread_index);
91 }
92
93
94 int main (int argc, char const *argv[])
95 {
96     g_count = 4;
97     std::thread threads[3];
98
99     g_char_ptr = new char[10]{};
100
101     // Create 3 threads
102     for (auto &thread : threads)
103         thread = std::thread{thread_func, std::distance(threads, &thread)};
104
105     struct {
106         int a;
107         int b;
108         int c;
109     } MyAggregateDataType;
110
111     printf ("Before turning all three threads loose...\n"); // Set break point at this line.
112     barrier_wait();
113
114     // Join all of our threads
115     for (auto &thread : threads)
116         thread.join();
117
118     delete[] g_char_ptr;
119
120     return 0;
121 }