예제 #1
0
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();
}
예제 #2
0
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));
}
예제 #3
0
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;
}
예제 #4
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;
}
예제 #5
0
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;
}
예제 #6
0
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));
}
예제 #7
0
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
}
예제 #8
0
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();
}
예제 #9
0
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();
}