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