// 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_GOOS_GOARCH.h"
#include "os_GOOS.h"
#include "arch_GOARCH.h"
#include "malloc.h"

static Timers timers;
static void addtimer(Timer*);
static bool deltimer(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) {
	g->status = Gwaiting;
	g->waitreason = "sleep";
	runtime·tsleep(ns);
}

// startTimer adds t to the timer heap.
func startTimer(t *Timer) {
	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 = 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.data);
}

// Put the current goroutine to sleep for ns nanoseconds.
// The caller must have set g->status and g->waitreason.
void
runtime·tsleep(int64 ns)
{
	Timer t;

	if(ns <= 0) {
		g->status = Grunning;
		g->waitreason = nil;
		return;
	}

	t.when = runtime·nanotime() + ns;
	t.period = 0;
	t.f = ready;
	t.arg.data = g;
	addtimer(&t);
	runtime·gosched();
}

// 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;

	runtime·lock(&timers);
	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 = runtime·newproc1((byte*)timerproc, nil, 0, 0, addtimer);
	runtime·unlock(&timers);
}

// Delete timer t from the heap.
// Do not need to update the timerproc:
// if it wakes up early, no big deal.
static bool
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)
{
	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 = t->f;
			arg = t->arg;
			runtime·unlock(&timers);
			f(now, arg);
			runtime·lock(&timers);
		}
		if(delta < 0) {
			// No timers left - put goroutine to sleep.
			timers.rescheduling = true;
			g->status = Gwaiting;
			g->waitreason = "timer goroutine (idle)";
			runtime·unlock(&timers);
			runtime·gosched();
			continue;
		}
		// At least one timer pending.  Sleep until then.
		timers.sleeping = true;
		runtime·noteclear(&timers.waitnote);
		runtime·unlock(&timers);
		runtime·entersyscall();
		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;
	}
}
