1 module during.tests.thread;
2 
3 import during;
4 import during.tests.base;
5 
6 import core.stdc.stdio;
7 import core.sys.posix.pthread;
8 
9 import std.algorithm : filter;
10 import std.range : drop, empty;
11 
12 // setup io_uring from multiple threads at once
13 @("setup")
14 unittest
15 {
16     enum NUM_THREADS = 4;
17     ThreadInfo[NUM_THREADS] threads;
18 
19     // start threads
20     foreach (i; 0..NUM_THREADS)
21     {
22         threads[i].num = i;
23         auto ret = pthread_create(&threads[i].tid, null, &doTest, &threads[i]);
24         assert(ret == 0, "pthread_create()");
25     }
26 
27     // join threads
28     foreach (i; 0..NUM_THREADS)
29     {
30         auto ret = pthread_join(threads[i].tid, cast(void**)null);
31         assert(ret == 0, "pthread_join()");
32     }
33 
34     // check for errors
35     auto errors = threads[].filter!(a => a.err != 0);
36     if (!errors.empty)
37     {
38         version (D_BetterC) errmsg = "failed (check 'ulimit -l')";
39         else assert(0, "failed (check 'ulimit -l')");
40     }
41 }
42 
43 extern(C) void* doTest(void *arg)
44 {
45     enum RING_SIZE = 32;
46     // printf("%d: start\n", (cast(ThreadInfo*)arg).num);
47 
48     Uring io;
49     auto res = io.setup(RING_SIZE);
50     if (res < 0)
51     {
52         // printf("%d: error=%d\n", (cast(ThreadInfo*)arg).num, -res);
53         (cast(ThreadInfo*)arg).err = -res;
54         return null;
55     }
56 
57     // simulate some work
58     foreach (_; 0..5)
59     {
60         foreach (i; 0..RING_SIZE) io.putWith!((ref SubmissionEntry e) => e.prepNop());
61         res = io.submit(RING_SIZE);
62         if (res != RING_SIZE)
63         {
64             // printf("%d: submit error=%d\n", (cast(ThreadInfo*)arg).num, -res);
65             (cast(ThreadInfo*)arg).err = -res;
66             return null;
67         }
68         io.drop(RING_SIZE);
69     }
70 
71     // printf("%d: done\n", (cast(ThreadInfo*)arg).num);
72     return null;
73 }
74 
75 struct ThreadInfo
76 {
77     pthread_t tid;
78     int num;
79     int err;
80 }