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");