[NFC][AArch64] Explicitly define undefined bits for instructions (#122129)
[llvm-project.git] / lldb / test / API / api / multithreaded / test_concurrent_unwind.cpp.template
blobe5101dde79619a11df0ee8655d52dc4376bdf919
1 #include "pseudo_barrier.h"
3 #include <atomic>
4 #include <thread>
6 %include_SB_APIs%
8 #include "common.h"
10 using namespace lldb;
12 void test (SBDebugger &dbg, std::vector<std::string> args) {
14 SBError error;
15   dbg.SetAsync(false);
16   SBTarget target = dbg.CreateTarget(args.at(0).c_str());
17   if (!target.IsValid())
18     throw Exception("Invalid target");
20   // Now set our breakpoint and launch:
21   SBFileSpec main_sourcefile("deep_stack.cpp");
22   SBBreakpoint bkpt = target.BreakpointCreateBySourceRegex("Set a breakpoint here",
23                                                            main_sourcefile);
24   if (bkpt.GetNumLocations() == 0)
25     throw Exception("Main breakpoint got no locations");
27   SBLaunchInfo launch_info = target.GetLaunchInfo();
28   SBProcess process = target.Launch(launch_info, error);
29   if (error.Fail())
30     throw Exception("Failed to launch process");
31   if (!process.IsValid())
32     throw Exception("Process is not valid");
33   if (process.GetState() != lldb::eStateStopped)
34     throw Exception("Process was not stopped");
36   size_t num_threads = process.GetNumThreads();
37   if (num_threads != 1)
38     throw Exception("Unexpected number of threads.");
39   SBThread cur_thread = process.GetThreadAtIndex(0);
40   if (!cur_thread.IsValid())
41     throw Exception("Didn't get a valid thread");
43   // Record the number of frames at the point where we stopped:
44   const size_t num_frames = cur_thread.GetNumFrames();
45   // Now step once to clear the frame cache:
46   cur_thread.StepOver();
47   
48   // Create three threads and set them to getting frames simultaneously,
49   // and make sure we don't deadlock.
50   pseudo_barrier_t rendevous;
51   pseudo_barrier_init(rendevous, 5);
52   std::atomic_size_t success(true);
53   std::atomic_size_t largest(0);
55   auto lambda = [&](size_t stride){
56     pseudo_barrier_wait(rendevous);
57     bool younger = true;
58     while (1) {
59       size_t cursor = largest;
60       if (cursor > stride && !younger) {
61         cursor -= stride;
62         younger = true;
63       } else {
64         cursor += stride;
65         largest += stride;
66         younger = false;
67       }
68       SBFrame frame = cur_thread.GetFrameAtIndex(cursor);
69       if (!frame.IsValid()) {
70         if (cursor < num_frames)
71           success = false;
72         break;
73       }
74     }
75     
76   };
78   std::thread thread1(lambda, 1);
79   std::thread thread2(lambda, 3);
80   std::thread thread3(lambda, 5);
81   std::thread thread4(lambda, 7);
82   std::thread thread5(lambda, 11);
83   thread1.join();
84   thread2.join();
85   thread3.join();
86   thread4.join();
87   thread5.join();
88   
89   if (!success)
90     throw Exception("One thread stopped before 1000");