1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 #include <errno.h>
4 #include <libproc_internal.h>
5 #include <stdio.h>
6
7 // waste some time.
8 static uint64_t
ackermann(uint64_t m,uint64_t n)9 ackermann(uint64_t m, uint64_t n)
10 {
11 if (m == 0) {
12 return n + 1;
13 } else if (n == 0) {
14 return ackermann(m - 1, 1);
15 } else {
16 return ackermann(m - 1, ackermann(m, n - 1));
17 }
18 }
19
20 T_DECL(int_time, "interrupt time collection")
21 {
22 struct proc_threadschedinfo info, info_new;
23
24 // for checking that the kernel filled in values.
25 info.int_time_ns = (uint64_t)-3;
26 info_new.int_time_ns = (uint64_t)-3;
27
28 int retval = proc_current_thread_schedinfo((void*)&info, sizeof(info));
29 T_ASSERT_EQ_INT(retval, 0, "proc_current_thread_schedinfo succeeded");
30 T_ASSERT_NE(info.int_time_ns, (uint64_t)-3, "info.int_time_ns was filled");
31
32 printf("result: %llu\n", ackermann(3, 10));
33
34 retval = proc_current_thread_schedinfo((void*)&info_new, sizeof(info_new));
35 T_ASSERT_EQ_INT(retval, 0, "proc_current_thread_schedinfo succeeded (2nd time)");
36 T_ASSERT_NE(info_new.int_time_ns, (uint64_t)-3, "info.int_time_ns was filled (2nd time)");
37
38 int64_t duration_ns = (int64_t)info_new.int_time_ns - (int64_t)info.int_time_ns;
39
40 printf("before : %lluns\n",
41 info.int_time_ns);
42 printf("after : %lluns\n",
43 info_new.int_time_ns);
44 printf("duration : %llins\n", duration_ns);
45
46 /*
47 * If time went backwards, life is missing its monotony.
48 */
49
50 T_EXPECT_FALSE(duration_ns < 0, "Kernel claims time went forewards");
51
52 /*
53 * If the kernel says we spent more than 10 seconds in an interrupt context, something is definitely wrong.
54 */
55
56 int64_t const limit_ns = 10 * (int64_t)NSEC_PER_SEC;
57 T_EXPECT_FALSE(duration_ns > limit_ns, "Kernel claims we spent less than 10 seconds in interrupt context");
58 }
59