/*
 * Copyright (c) 2010-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 <sys/event.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#ifdef __APPLE__
#include <libkern/OSAtomic.h>
#endif
#include <assert.h>
#ifdef __ANDROID__
#include <linux/sysctl.h>
#else
#include <sys/sysctl.h>
#endif /* __ANDROID__ */
#include <stdarg.h>
#include <time.h>

#include <dispatch/dispatch.h>
#include <dispatch/private.h>

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

#if defined(DISPATCH_SOURCE_TYPE_VM) && defined(NOTE_VM_PRESSURE)

#if TARGET_OS_EMBEDDED
#define ALLOC_SIZE ((size_t)(1024*1024*1ul))	// 1MB
#define NOTIFICATIONS 1
#else
#define ALLOC_SIZE ((size_t)(1024*1024*20ul))	// 20MB
#define NOTIFICATIONS 2
#endif
#define pg2mb(p) ((p) * ALLOC_SIZE/(1024*1024))
#ifdef __LP64__
#define MAXMEM ((size_t)SIZE_MAX)
#else
#define MAXMEM ((size_t)(3200ul*1024*1024))		// 3200MB
#endif

static char **pages;
static volatile int32_t handler_call_count;
static volatile int32_t page_count;
static int32_t max_page_count;
static dispatch_source_t vm_source;
static dispatch_queue_t vm_queue;
static time_t initial;
static int interval = 16;

#define log_msg(msg, ...) \
do { \
	fprintf(stderr, "[%2ds] " msg, (int)(time(NULL) - initial), ##__VA_ARGS__);\
} while (0)

static bool
dispatch_test_check_evfilt_vm(void)
{
	int kq = kqueue();
	assert(kq != -1);
	struct kevent ke = {
		.filter = EVFILT_VM,
		.flags = EV_ADD|EV_ENABLE|EV_RECEIPT,
		.fflags = NOTE_VM_PRESSURE,
	};
	int r = kevent(kq, &ke, 1, &ke, 1, NULL);
	close(kq);
	return !(r > 0 && ke.flags & EV_ERROR && ke.data == ENOTSUP);
}

static void
cleanup(void)
{
	dispatch_source_cancel(vm_source);
	dispatch_release(vm_source);
	dispatch_release(vm_queue);

	int32_t pc = 0, i;
	for (i = 0; i < max_page_count; ++i) {
	   if (pages[i]) {
		   pc++;
		   free(pages[i]);
	   }
	}
	if (pc) {
		log_msg("Freed %ldMB\n", pg2mb(pc));
	}
	free(pages);
	test_stop();
}

int
main(void)
{
	dispatch_test_start("Dispatch VM Pressure test"); // rdar://problem/7000945
	if (!dispatch_test_check_evfilt_vm()) {
		test_skip("EVFILT_VM not supported");
		test_stop();
		return 0;
	}
	initial = time(NULL);
	uint64_t memsize;
#ifdef __linux__
	memsize = sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
#else
	size_t s = sizeof(memsize);
	int rc = sysctlbyname("hw.memsize", &memsize, &s, NULL, 0);
	assert(rc == 0);
#endif
	max_page_count = MIN(memsize, MAXMEM) / ALLOC_SIZE;
	pages = calloc(max_page_count, sizeof(char*));

	vm_queue = dispatch_queue_create("VM Pressure", NULL);
	vm_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VM, 0,
			DISPATCH_VM_PRESSURE, vm_queue);
	dispatch_source_set_event_handler(vm_source, ^{
		if (!page_count) {
			// Too much memory pressure already to start the test
			test_skip("Memory pressure at start of test");
			cleanup();
		}
		if (OSAtomicIncrement32Barrier(&handler_call_count) != NOTIFICATIONS) {
			log_msg("Ignoring vm pressure notification\n");
			interval = 1;
			return;
		}
		test_long("dispatch_source_get_data()",
				dispatch_source_get_data(vm_source), NOTE_VM_PRESSURE);
		int32_t i, pc = page_count + 1;
		for (i = 0; i < pc && pages[i]; ++i) {
				free(pages[i]);
				pages[i] = NULL;
		}
		log_msg("Freed %ldMB\n", pg2mb(i));
	});
	dispatch_resume(vm_source);
	dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC),
			dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
		while (handler_call_count < NOTIFICATIONS &&
				page_count < max_page_count) {
			void *p = valloc(ALLOC_SIZE);
			if (!p) {
				break;
			}
			bzero(p, ALLOC_SIZE);
			pages[page_count] = p;
			if (!(OSAtomicIncrement32Barrier(&page_count) % interval)) {
				log_msg("Allocated %ldMB\n", pg2mb(page_count));
				usleep(200000);
			}
		}
		if (page_count % interval) {
			log_msg("Allocated %ldMB\n", pg2mb(page_count));
		}
		if (handler_call_count < NOTIFICATIONS) {
			// Cannot allocate enough memory for test (e.g. on 32 bit)
			test_skip("Cannot allocate enough memory for test");
			dispatch_async(vm_queue, ^{cleanup();});
			return;
		}
		dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC),
				vm_queue, ^{
			test_long_greater_than_or_equal("VM Pressure fired",
					handler_call_count, NOTIFICATIONS);
			test_long_less_than("VM Pressure stopped firing",
					handler_call_count, 4);
			cleanup();
		});
	});
	dispatch_main();
	return 0;
}
#else //DISPATCH_SOURCE_TYPE_VM
int
main(void)
{
	dispatch_test_start("Dispatch VM Pressure test"
			" - No DISPATCH_SOURCE_TYPE_VM");
	test_stop();
	return 0;
}
#endif //DISPATCH_SOURCE_TYPE_VM
