/*
 * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
 *
 * @APPLE_APACHE_LICENSE_HEADER_START@
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @APPLE_APACHE_LICENSE_HEADER_END@
 */

#include <stdio.h>
#include <dispatch/dispatch.h>
#include <dispatch/private.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#include <stdlib.h>
#include <assert.h>
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
#include <sys/types.h>
#ifdef __ANDROID__
#include <linux/sysctl.h>
#else
#include <sys/sysctl.h>
#endif /* __ANDROID__ */

#include <bsdtests.h>
#include "dispatch_test.h"

static volatile int done;

#ifdef DISPATCH_QUEUE_PRIORITY_BACKGROUND // <rdar://problem/7439794>
#define USE_BACKGROUND_PRIORITY 1
#else
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
#endif

#define QUEUE_PRIORITY_PTHREAD INT_MAX

#if DISPATCH_API_VERSION < 20100518 // <rdar://problem/7790099>
#define DISPATCH_QUEUE_CONCURRENT NULL
#endif

#if TARGET_OS_EMBEDDED
#define LOOP_COUNT 5000000
const int importance = 24; // priority 55
#else
#define LOOP_COUNT 100000000
const int importance = 4; // priority 35
#endif

char *labels[] = { "BACKGROUND", "LOW", "DEFAULT", "HIGH", };
int levels[] = {
	DISPATCH_QUEUE_PRIORITY_BACKGROUND, DISPATCH_QUEUE_PRIORITY_LOW,
	DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_PRIORITY_HIGH,
};
#define PRIORITIES (sizeof(levels)/sizeof(*levels))

static union {
	long count;
	char padding[64];
} counts[PRIORITIES];

static volatile long iterations;
static long total;
static size_t prio0, priorities = PRIORITIES;

static int
n_blocks(void)
{
	static dispatch_once_t pred;
	static int n;
	dispatch_once(&pred, ^{
#ifdef __linux__
		n = (int)sysconf(_SC_NPROCESSORS_CONF);
#else
		size_t l = sizeof(n);
		int rc = sysctlbyname("hw.ncpu", &n, &l, NULL, 0);
		assert(rc == 0);
#endif
		n *= 32;
	});
	return n;
}

static void
histogram(void)
{
	long completed = 0;
	size_t x, y, i;
	printf("\n");
	for (y = prio0; y < prio0 + priorities; ++y) {
		printf("%s: %ld\n", labels[y], counts[y].count);
		completed += counts[y].count;

		double fraction = (double)counts[y].count / (double)n_blocks();
		double value = fraction * (double)80;
		for (x = 0; x < 80; ++x) {
			printf("%s", (value > x) ? "*" : " ");
		}
		printf("\n");
	}

	test_long("blocks completed", completed, total);
	for (i = prio0; i < prio0 + priorities; i++) {
		if (levels[i] == DISPATCH_QUEUE_PRIORITY_HIGH) {
			test_long_less_than_or_equal("high priority precedence",
					counts[i-2].count, counts[i].count);
		}
#if USE_BACKGROUND_PRIORITY
		if (levels[i] == DISPATCH_QUEUE_PRIORITY_BACKGROUND) {
			test_long_less_than_or_equal("background priority precedence",
					counts[i].count, counts[i+2].count);
		}
#endif
	}
}

static void
cpubusy(void* context)
{
	if (done) return;
	size_t idx;
	for (idx = 0; idx < LOOP_COUNT; ++idx) {
		if (done) break;
	}

	volatile long *count = context;
	long iterdone = __sync_sub_and_fetch(&iterations, 1);

	if (iterdone >= 0) {
		__sync_add_and_fetch(count, 1);
		if (!iterdone) {
			__sync_add_and_fetch(&done, 1);
			usleep(100000);
			histogram();
			dispatch_time_t delay = DISPATCH_TIME_NOW;
			dispatch_after(delay, dispatch_get_main_queue(), ^{
				test_stop();
			});
		}
	}
}

static void
submit_work(dispatch_queue_t queue, void* context)
{
	int i;

	for (i = n_blocks(); i; --i) {
		dispatch_async_f(queue, context, cpubusy);
	}

}

int
main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
{
	dispatch_queue_t q[PRIORITIES];
	size_t i;

#if !USE_BACKGROUND_PRIORITY
	prio0++;
	priorities--;
#endif

	iterations = total = ((int)priorities * n_blocks()) / 2;

#if USE_SET_TARGET_QUEUE
	dispatch_test_start("Dispatch Priority (Set Target Queue)");
#else
	dispatch_test_start("Dispatch Priority");
#endif

	for (i = prio0; i < prio0 + priorities; i++) {
		dispatch_queue_t rq = dispatch_get_global_queue(levels[i], 0);
#if USE_SET_TARGET_QUEUE
		q[i] = dispatch_queue_create(labels[i], DISPATCH_QUEUE_CONCURRENT);
		test_ptr_notnull("q[i]", q[i]);
		assert(q[i]);
		dispatch_suspend(q[i]);
		dispatch_set_target_queue(q[i], rq);
		if (DISPATCH_QUEUE_CONCURRENT != NULL) {
			dispatch_queue_set_width(q[i], LONG_MAX);
		}
		dispatch_release(rq);
#else
		q[i] = rq;
#endif
	}

	for (i = prio0; i < prio0 + priorities; i++) {
		submit_work(q[i], &counts[i].count);
	}

	for (i = prio0; i < prio0 + priorities; i++) {
		dispatch_resume(q[i]);
		dispatch_release(q[i]);
	}

	dispatch_main();

	return 0;
}
