// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

#include <pthread.h>

typedef pthread_t osthread_t;

void thread_start(osthread_t* t, void* (*fn)(void*), void* arg)
{
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setstacksize(&attr, 128 << 10);
	if (pthread_create(t, &attr, fn, arg))
		exitf("pthread_create failed");
	pthread_attr_destroy(&attr);
}

struct event_t {
	int state;
};

void event_init(event_t* ev)
{
	ev->state = 0;
}

void event_reset(event_t* ev)
{
	ev->state = 0;
}

void event_set(event_t* ev)
{
	if (ev->state)
		fail("event already set");
	__atomic_store_n(&ev->state, 1, __ATOMIC_RELEASE);
	syscall(SYS_futex, &ev->state, FUTEX_WAKE);
}

void event_wait(event_t* ev)
{
	while (!__atomic_load_n(&ev->state, __ATOMIC_ACQUIRE))
		syscall(SYS_futex, &ev->state, FUTEX_WAIT, 0, 0);
}

bool event_isset(event_t* ev)
{
	return __atomic_load_n(&ev->state, __ATOMIC_ACQUIRE);
}

bool event_timedwait(event_t* ev, uint64_t timeout_ms)
{
	uint64_t start = current_time_ms();
	uint64_t now = start;
	for (;;) {
		timespec ts = {};
		ts.tv_sec = 0;
		ts.tv_nsec = (timeout_ms - (now - start)) * 1000 * 1000;
		syscall(SYS_futex, &ev->state, FUTEX_WAIT, 0, &ts);
		if (__atomic_load_n(&ev->state, __ATOMIC_RELAXED))
			return true;
		now = current_time_ms();
		if (now - start > timeout_ms)
			return false;
	}
}
