xref: /llvm-project/lldb/test/API/linux/thread/create_during_instruction_step/main.cpp (revision fdea9a4ec9b0d9585b8fe8a612686d9f44f40ddc)
1*99451b44SJordan Rupprecht // This file deliberately uses low level linux-specific API for thread creation because:
2*99451b44SJordan Rupprecht // - instruction-stepping over thread creation using higher-level functions was very slow
3*99451b44SJordan Rupprecht // - it was also unreliable due to single-stepping bugs unrelated to this test
4*99451b44SJordan Rupprecht // - some threading libraries do not create or destroy threads when we would expect them to
5*99451b44SJordan Rupprecht 
6*99451b44SJordan Rupprecht #include <sched.h>
7*99451b44SJordan Rupprecht 
8*99451b44SJordan Rupprecht #include <atomic>
9*99451b44SJordan Rupprecht #include <cstdio>
10*99451b44SJordan Rupprecht 
11*99451b44SJordan Rupprecht enum { STACK_SIZE = 0x2000 };
12*99451b44SJordan Rupprecht 
13*99451b44SJordan Rupprecht static uint8_t child_stack[STACK_SIZE];
14*99451b44SJordan Rupprecht 
15*99451b44SJordan Rupprecht pid_t child_tid;
16*99451b44SJordan Rupprecht 
17*99451b44SJordan Rupprecht std::atomic<bool> flag(false);
18*99451b44SJordan Rupprecht 
thread_main(void *)19*99451b44SJordan Rupprecht int thread_main(void *)
20*99451b44SJordan Rupprecht {
21*99451b44SJordan Rupprecht     while (! flag) // Make sure the thread does not exit prematurely
22*99451b44SJordan Rupprecht         ;
23*99451b44SJordan Rupprecht 
24*99451b44SJordan Rupprecht     return 0;
25*99451b44SJordan Rupprecht }
26*99451b44SJordan Rupprecht 
main()27*99451b44SJordan Rupprecht int main ()
28*99451b44SJordan Rupprecht {
29*99451b44SJordan Rupprecht     int ret = clone(thread_main,
30*99451b44SJordan Rupprecht             child_stack + STACK_SIZE/2, // Don't care whether the stack grows up or down,
31*99451b44SJordan Rupprecht                                         // just point to the middle
32*99451b44SJordan Rupprecht             CLONE_CHILD_CLEARTID | CLONE_FILES | CLONE_FS | CLONE_PARENT_SETTID |
33*99451b44SJordan Rupprecht             CLONE_SIGHAND | CLONE_SYSVSEM | CLONE_THREAD | CLONE_VM,
34*99451b44SJordan Rupprecht             nullptr, // thread_main argument
35*99451b44SJordan Rupprecht             &child_tid);
36*99451b44SJordan Rupprecht 
37*99451b44SJordan Rupprecht     if (ret == -1)
38*99451b44SJordan Rupprecht     {
39*99451b44SJordan Rupprecht         perror("clone");
40*99451b44SJordan Rupprecht         return 1;
41*99451b44SJordan Rupprecht     }
42*99451b44SJordan Rupprecht 
43*99451b44SJordan Rupprecht     flag = true;
44*99451b44SJordan Rupprecht 
45*99451b44SJordan Rupprecht     return 0;
46*99451b44SJordan Rupprecht }
47