int main() { dispatch_queue_t q[PRIORITIES]; int i; #if USE_SET_TARGET_QUEUE test_start("Dispatch Priority (Set Target Queue)"); for(i = 0; i < PRIORITIES; i++) { q[i] = dispatch_queue_create(labels[i], NULL); test_ptr_notnull("q[i]", q[i]); assert(q[i]); dispatch_set_target_queue(as_do(q[i]), dispatch_get_global_queue(priorities[i], 0)); dispatch_queue_set_width(q[i], DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS); } #else test_start("Dispatch Priority"); for(i = 0; i < PRIORITIES; i++) { q[i] = dispatch_get_global_queue(priorities[i], 0); } #endif for(i = 0; i < PRIORITIES; i++) { submit_work(q[i], &counts[i].count); } dispatch_main(); }
void dispatch_source_cancel(dispatch_source_t ds) { #if DISPATCH_DEBUG dispatch_debug(as_do(ds), __FUNCTION__); #endif // Right after we set the cancel flag, someone else // could potentially invoke the source, do the cancelation, // unregister the source, and deallocate it. We would // need to therefore retain/release before setting the bit _dispatch_retain(as_do(ds)); dispatch_atomic_or(&ds->ds_atomic_flags, DSF_CANCELED); _dispatch_wakeup(as_do(ds)); _dispatch_release(as_do(ds)); }
int main(int argc, char* argv[]) { // interval is 1/10th of a second uint64_t interval = NSEC_PER_SEC / 10; // for 25 seconds struct timeval now_tv; struct timespec now_ts; interval_d = (double)interval / (double)NSEC_PER_SEC; target = (unsigned int)(25 / interval_d); test_start("Timer drift test"); timeBeginPeriod(1); timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); test_ptr_notnull("DISPATCH_SOURCE_TYPE_TIMER", timer); dispatch_source_set_event_handler_f(timer, timer_handler); gettimeofday(&now_tv, NULL); now_ts.tv_sec = now_tv.tv_sec; now_ts.tv_nsec = now_tv.tv_usec * NSEC_PER_USEC; dispatch_source_set_timer(timer, dispatch_walltime(&now_ts, interval), interval, 0); dispatch_resume(as_do(timer)); dispatch_main(); return 0; }
dispatch_source_t dispatch_source_create(dispatch_source_type_t type, uintptr_t handle, uintptr_t mask, dispatch_queue_t q) { dispatch_source_t ds = NULL; static char source_label[sizeof(ds->dq_label)] = "source"; // input validation if (type == NULL || (mask & ~type->mask)) { goto out_bad; } ds = calloc(1ul, sizeof(struct dispatch_source_s)); if (slowpath(!ds)) { goto out_bad; } // Initialize as a queue first, then override some settings below. _dispatch_queue_init((dispatch_queue_t)ds); memcpy(ds->dq_label, source_label, sizeof(source_label)); // Dispatch Object ds->do_vtable = &_dispatch_source_kevent_vtable; ds->do_ref_cnt++; // the reference the manger queue holds ds->do_suspend_cnt = DISPATCH_OBJECT_SUSPEND_INTERVAL; // do_targetq will be retained below, past point of no-return ds->do_targetq = q; if (slowpath(!type->init(ds, type, handle, mask, q))) { goto out_bad; } dispatch_assert(!(ds->ds_is_level && ds->ds_is_adder)); #if DISPATCH_DEBUG dispatch_debug(as_do(ds), __FUNCTION__); #endif _dispatch_retain(as_do(ds->do_targetq)); return ds; out_bad: free(ds); return NULL; }
size_t _dispatch_source_debug(dispatch_source_t ds, char* buf, size_t bufsiz) { size_t offset = 0; offset += snprintf(&buf[offset], bufsiz - offset, "%s[%p] = { ", dx_kind(ds), ds); offset += dispatch_object_debug_attr(as_do(ds), &buf[offset], bufsiz - offset); offset += dispatch_source_debug_attr(ds, &buf[offset], bufsiz - offset); return offset; }
DISPATCH_NOINLINE void _dispatch_source_xref_release(dispatch_source_t ds) { #ifndef DISPATCH_NO_LEGACY if (ds->ds_is_legacy) { if (!(ds->ds_timer.flags & DISPATCH_TIMER_TYPE_MASK == DISPATCH_TIMER_ONESHOT)) { dispatch_source_cancel(ds); } // Clients often leave sources suspended at the last release dispatch_atomic_and(&ds->do_suspend_cnt, DISPATCH_OBJECT_SUSPEND_LOCK); } else #endif if (slowpath(DISPATCH_OBJECT_SUSPENDED(ds))) { // Arguments for and against this assert are within 6705399 DISPATCH_CLIENT_CRASH("Release of a suspended object"); } _dispatch_wakeup(as_do(ds)); _dispatch_release(as_do(ds)); }
void submit_work(dispatch_queue_t queue, void* context) { int i; for (i = 0; i < BLOCKS; ++i) { dispatch_async_f(queue, context, cpubusy); } #if USE_SET_TARGET_QUEUE dispatch_release(as_do(queue)); #endif }
int main(void) { test_start("Dispatch Reader/Writer Queues"); dq = dispatch_queue_create("com.apple.libdispatch.test_readsync", NULL); assert(dq); dispatch_queue_set_width(dq, LONG_MAX); dispatch_apply_f(LAPS, dispatch_get_global_queue(0, 0), NULL, apply_fn); dispatch_release(as_do(dq)); dispatch_main(); }
int main(void) { dispatch_queue_t main_q; test_start("Dispatch Update Timer"); main_q = dispatch_get_main_queue(); test_ptr("dispatch_get_main_queue", main_q, dispatch_get_current_queue()); timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, main_q); dispatch_source_set_timer(timer, 1000000000ull, 0, 0); dispatch_source_set_cancel_handler_f(timer, cancel_handler); dispatch_source_set_event_handler_f(timer, event_handler); test_ptr_notnull("dispatch_source_timer_create", timer); gettimeofday(&start_time, NULL); dispatch_resume(as_do(timer)); dispatch_main(); }