2 /* test that the header doesn't implicitly depend on others */
3 #include <sys/work_interval.h>
13 #include <mach/mach.h>
15 #include <darwintest.h>
17 T_GLOBAL_META(T_META_NAMESPACE("xnu.scheduler"));
19 static mach_port_t port
= MACH_PORT_NULL
;
22 joining_thread_fn(__unused
void *arg
)
25 kern_return_t kr
= KERN_SUCCESS
;
27 ret
= work_interval_join_port(port
);
28 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, another thread");
30 kr
= mach_port_deallocate(mach_task_self(), port
);
31 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_deallocate of port, another thread");
33 /* deliberately exit with joined work interval */
37 T_DECL(work_interval
, "work interval interface")
40 work_interval_t handle
= NULL
;
41 uint64_t now
= mach_absolute_time();
42 kern_return_t kr
= KERN_SUCCESS
;
44 ret
= work_interval_create(NULL
, 0);
45 T_ASSERT_EQ(errno
, EINVAL
, "create with null errno EINVAL");
46 T_ASSERT_EQ(ret
, -1, "create with null returns -1");
48 /* Binary must be entitled for this to succeed */
49 ret
= work_interval_create(&handle
, 0);
50 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, no flags");
52 ret
= work_interval_copy_port(handle
, &port
);
53 T_ASSERT_EQ(errno
, EINVAL
, "work_interval_copy_port on non-joinable interval errno EINVAL");
54 T_ASSERT_EQ(ret
, -1, "work_interval_copy_port on non-joinable interval returns -1");
56 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
57 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, no flags");
59 ret
= work_interval_destroy(handle
);
60 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy, no flags");
63 WORK_INTERVAL_FLAG_JOINABLE
,
64 WORK_INTERVAL_FLAG_JOINABLE
| WORK_INTERVAL_FLAG_GROUP
,
67 for (uint32_t i
= 0 ; i
< sizeof(flags
) / sizeof(flags
[0]) ; i
++) {
68 ret
= work_interval_create(&handle
, flags
[i
]);
69 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, joinable");
71 ret
= work_interval_copy_port(handle
, &port
);
72 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_copy_port, joinable");
74 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
75 T_ASSERT_EQ(ret
, -1, "work_interval_notify on non-joined thread returns -1");
76 T_ASSERT_EQ(errno
, EINVAL
, "work_interval_copy_port on non-joined thread errno EINVAL");
78 ret
= work_interval_join_port(port
);
79 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, joinable");
81 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
82 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, on joined thread");
84 ret
= work_interval_join_port(port
);
85 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, join the same interval after destroy");
87 kr
= mach_port_deallocate(mach_task_self(), port
);
88 T_ASSERT_MACH_SUCCESS(kr
, "mach_port_deallocate of port");
90 ret
= work_interval_notify(handle
, now
- 1000, now
, now
+ 1000, now
+ 2000, 0);
91 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_notify, on joined thread after destroy");
93 ret
= work_interval_destroy(handle
);
94 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy, joinable, on joined thread");
96 ret
= work_interval_leave();
97 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_leave, on destroyed work interval");
100 ret
= work_interval_create(&handle
, WORK_INTERVAL_FLAG_JOINABLE
| WORK_INTERVAL_FLAG_GROUP
);
101 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_create, joinable");
103 ret
= work_interval_copy_port(handle
, &port
);
104 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_copy_port, joinable");
106 ret
= work_interval_join_port(port
);
107 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_join_port, join before handing to another thread");
109 pthread_t joining_thread
;
111 T_ASSERT_POSIX_ZERO(pthread_create(&joining_thread
, NULL
, joining_thread_fn
, NULL
), "pthread_create");
113 T_ASSERT_POSIX_ZERO(pthread_join(joining_thread
, NULL
), "pthread_join");
115 ret
= work_interval_leave();
116 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_leave");
118 ret
= work_interval_destroy(handle
);
119 T_ASSERT_POSIX_SUCCESS(ret
, "work_interval_destroy");