1 /* test that the header doesn't implicitly depend on others */
2 #include <sys/work_interval.h>
12 #include <mach/mach.h>
14 #include <darwintest.h>
16 T_GLOBAL_META(T_META_NAMESPACE("xnu.scheduler"));
18 static mach_port_t port
= MACH_PORT_NULL
;
21 joining_thread_fn(__unused
void *arg
)
24 kern_return_t kr
= KERN_SUCCESS
;
26 ret
= work_interval_join_port(port
);
27 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, another thread");
29 kr
= mach_port_deallocate(mach_task_self(), port
);
30 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_deallocate of port, another thread");
32 /* deliberately exit with joined work interval */
36 T_DECL(work_interval
, "work interval interface")
39 work_interval_t handle
= NULL
;
40 uint64_t now
= mach_absolute_time();
41 kern_return_t kr
= KERN_SUCCESS
;
43 ret
= work_interval_create(NULL
, 0);
44 T_ASSERT_EQ(errno
, EINVAL
, "create with null errno EINVAL");
45 T_ASSERT_EQ(ret
, -1, "create with null returns -1");
47 /* Binary must be entitled for this to succeed */
48 ret
= work_interval_create(&handle
, 0);
49 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, no flags");
51 ret
= work_interval_copy_port(handle
, &port
);
52 T_ASSERT_EQ(errno
, EINVAL
, "work_interval_copy_port on non-joinable interval errno EINVAL");
53 T_ASSERT_EQ(ret
, -1, "work_interval_copy_port on non-joinable interval returns -1");
55 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
56 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, no flags");
58 ret
= work_interval_destroy(handle
);
59 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy, no flags");
62 WORK_INTERVAL_FLAG_JOINABLE
,
63 WORK_INTERVAL_FLAG_JOINABLE
| WORK_INTERVAL_FLAG_GROUP
,
66 for (uint32_t i
= 0; i
< sizeof(flags
) / sizeof(flags
[0]); i
++) {
67 ret
= work_interval_create(&handle
, flags
[i
]);
68 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, joinable");
70 ret
= work_interval_copy_port(handle
, &port
);
71 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_copy_port, joinable");
73 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
74 T_ASSERT_EQ(ret
, -1, "work_interval_notify on non-joined thread returns -1");
75 T_ASSERT_EQ(errno
, EINVAL
, "work_interval_copy_port on non-joined thread errno EINVAL");
77 ret
= work_interval_join_port(port
);
78 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, joinable");
80 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
81 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, on joined thread");
83 ret
= work_interval_join_port(port
);
84 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, join the same interval after destroy");
86 kr
= mach_port_deallocate(mach_task_self(), port
);
87 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_deallocate of port");
89 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
90 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, on joined thread after destroy");
92 ret
= work_interval_destroy(handle
);
93 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy, joinable, on joined thread");
95 ret
= work_interval_leave();
96 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_leave, on destroyed work interval");
99 ret
= work_interval_create(&handle
, WORK_INTERVAL_FLAG_JOINABLE
| WORK_INTERVAL_FLAG_GROUP
);
100 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, joinable");
102 ret
= work_interval_copy_port(handle
, &port
);
103 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_copy_port, joinable");
105 ret
= work_interval_join_port(port
);
106 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, join before handing to another thread");
108 pthread_t joining_thread
;
110 T_ASSERT_POSIX_ZERO(pthread_create(&joining_thread
, NULL
, joining_thread_fn
, NULL
), "pthread_create");
112 T_ASSERT_POSIX_ZERO(pthread_join(joining_thread
, NULL
), "pthread_join");
114 ret
= work_interval_leave();
115 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_leave");
117 ret
= work_interval_destroy(handle
);
118 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy");