// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Time-related runtime and pieces of package time.

package time

#include "runtime.h"
#include "defs.h"
#include "arch.h"
#include "malloc.h"
#include "race.h"

static Timers timers;
static void addtimer(Timer*);

// Package time APIs.
// Godoc uses the comments in package time, not these.

// time.now is implemented in assembly.

// Sleep puts the current goroutine to sleep for at least ns nanoseconds.
func Sleep(ns int64) {
	runtime_tsleep(ns, "sleep");
}

// startTimer adds t to the timer heap.
func startTimer(t *Timer) {
	if(raceenabled)
		runtime_racerelease(t);
	runtime_addtimer(t);
}

// stopTimer removes t from the timer heap if it is there.
// It returns true if t was removed, false if t wasn't even there.
func stopTimer(t *Timer) (stopped bool) {
	stopped = runtime_deltimer(t);
}

// C runtime.

static void timerproc(void*);
static void siftup(int32);
static void siftdown(int32);

// Ready the goroutine e.data.
static void
ready(int64 now, Eface e)
{
	USED(now);

	runtime_ready(e.__object);
}

static FuncVal readyv = {(void(*)(void))ready};

// Put the current goroutine to sleep for ns nanoseconds.
void
runtime_tsleep(int64 ns, const char *reason)
{
	G* g;
	Timer t;

	g = runtime_g();

	if(ns <= 0)
		return;

	t.when = runtime_nanotime() + ns;
	t.period = 0;
	t.fv = &readyv;
	t.arg.__object = g;
	runtime_lock(&timers);
	addtimer(&t);
	runtime_park(runtime_unlock, &timers, reason);
}

void
runtime_addtimer(Timer *t)
{
	runtime_lock(&timers);
	addtimer(t);
	runtime_unlock(&timers);
}

// Add a timer to the heap and start or kick the timer proc
// if the new timer is earlier than any of the others.
static void
addtimer(Timer *t)
{
	int32 n;
	Timer **nt;

	if(timers.len >= timers.cap) {
		// Grow slice.
		n = 16;
		if(n <= timers.cap)
			n = timers.cap*3 / 2;
		nt = runtime_malloc(n*sizeof nt[0]);
		runtime_memmove(nt, timers.t, timers.len*sizeof nt[0]);
		runtime_free(timers.t);
		timers.t = nt;
		timers.cap = n;
	}
	t->i = timers.len++;
	timers.t[t->i] = t;
	siftup(t->i);
	if(t->i == 0) {
		// siftup moved to top: new earliest deadline.
		if(timers.sleeping) {
			timers.sleeping = false;
			runtime_notewakeup(&timers.waitnote);
		}
		if(timers.rescheduling) {
			timers.rescheduling = false;
			runtime_ready(timers.timerproc);
		}
	}
	if(timers.timerproc == nil) {
		timers.timerproc = __go_go(timerproc, nil);
		timers.timerproc->issystem = true;
	}
}

// Delete timer t from the heap.
// Do not need to update the timerproc:
// if it wakes up early, no big deal.
bool
runtime_deltimer(Timer *t)
{
	int32 i;

	runtime_lock(&timers);

	// t may not be registered anymore and may have
	// a bogus i (typically 0, if generated by Go).
	// Verify it before proceeding.
	i = t->i;
	if(i < 0 || i >= timers.len || timers.t[i] != t) {
		runtime_unlock(&timers);
		return false;
	}

	timers.len--;
	if(i == timers.len) {
		timers.t[i] = nil;
	} else {
		timers.t[i] = timers.t[timers.len];
		timers.t[timers.len] = nil;
		timers.t[i]->i = i;
		siftup(i);
		siftdown(i);
	}
	runtime_unlock(&timers);
	return true;
}

// Timerproc runs the time-driven events.
// It sleeps until the next event in the timers heap.
// If addtimer inserts a new earlier event, addtimer
// wakes timerproc early.
static void
timerproc(void* dummy __attribute__ ((unused)))
{
	int64 delta, now;
	Timer *t;
	void (*f)(int64, Eface);
	Eface arg;

	for(;;) {
		runtime_lock(&timers);
		now = runtime_nanotime();
		for(;;) {
			if(timers.len == 0) {
				delta = -1;
				break;
			}
			t = timers.t[0];
			delta = t->when - now;
			if(delta > 0)
				break;
			if(t->period > 0) {
				// leave in heap but adjust next time to fire
				t->when += t->period * (1 + -delta/t->period);
				siftdown(0);
			} else {
				// remove from heap
				timers.t[0] = timers.t[--timers.len];
				timers.t[0]->i = 0;
				siftdown(0);
				t->i = -1;  // mark as removed
			}
			f = (void*)t->fv->fn;
			arg = t->arg;
			runtime_unlock(&timers);
			if(raceenabled)
				runtime_raceacquire(t);
			__go_set_closure(t->fv);
			f(now, arg);
			runtime_lock(&timers);
		}
		if(delta < 0) {
			// No timers left - put goroutine to sleep.
			timers.rescheduling = true;
			runtime_park(runtime_unlock, &timers, "timer goroutine (idle)");
			continue;
		}
		// At least one timer pending.  Sleep until then.
		timers.sleeping = true;
		runtime_noteclear(&timers.waitnote);
		runtime_unlock(&timers);
		runtime_entersyscallblock();
		runtime_notetsleep(&timers.waitnote, delta);
		runtime_exitsyscall();
	}
}

// heap maintenance algorithms.

static void
siftup(int32 i)
{
	int32 p;
	Timer **t, *tmp;

	t = timers.t;
	while(i > 0) {
		p = (i-1)/2;  // parent
		if(t[i]->when >= t[p]->when)
			break;
		tmp = t[i];
		t[i] = t[p];
		t[p] = tmp;
		t[i]->i = i;
		t[p]->i = p;
		i = p;
	}
}

static void
siftdown(int32 i)
{
	int32 c, len;
	Timer **t, *tmp;

	t = timers.t;
	len = timers.len;
	for(;;) {
		c = i*2 + 1;  // left child
		if(c >= len) {
			break;
		}
		if(c+1 < len && t[c+1]->when < t[c]->when)
			c++;
		if(t[c]->when >= t[i]->when)
			break;
		tmp = t[i];
		t[i] = t[c];
		t[c] = tmp;
		t[i]->i = i;
		t[c]->i = c;
		i = c;
	}
}

void
runtime_time_scan(void (*addroot)(Obj))
{
	addroot((Obj){(byte*)&timers, sizeof timers, 0});
}
