// AUTO-GENERATED by autogen.sh; DO NOT EDIT

#include <sys/time.h>
#include "runtime.h"
#include "defs.h"
#include "arch.h"
#include "malloc.h"

#line 16 "../../../gcc-5.1.0/libgo/runtime/time.goc"
enum { 
debug = 0 , 
} ; 
#line 20 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static Timers timers; 
static void addtimer ( Timer* ) ; 
static void dumptimers ( const char* ) ; 
#line 25 "../../../gcc-5.1.0/libgo/runtime/time.goc"
int64 runtime_timens; 
int64 time_runtimeNano() __asm__ (GOSYM_PREFIX "time.runtimeNano");
int64 time_runtimeNano()
{
  int64 ns;
#line 33 "../../../gcc-5.1.0/libgo/runtime/time.goc"

	ns = runtime_nanotime();
return ns;
}
void time_Sleep(int64 ns) __asm__ (GOSYM_PREFIX "time.Sleep");
void time_Sleep(int64 ns)
{
#line 38 "../../../gcc-5.1.0/libgo/runtime/time.goc"

	runtime_tsleep(ns, "sleep");
}
void time_startTimer(Timer* t) __asm__ (GOSYM_PREFIX "time.startTimer");
void time_startTimer(Timer* t)
{
#line 43 "../../../gcc-5.1.0/libgo/runtime/time.goc"

	runtime_addtimer(t);
}
bool time_stopTimer(Timer* t) __asm__ (GOSYM_PREFIX "time.stopTimer");
bool time_stopTimer(Timer* t)
{
  bool stopped;
#line 49 "../../../gcc-5.1.0/libgo/runtime/time.goc"

	stopped = runtime_deltimer(t);
return stopped;
}

#line 55 "../../../gcc-5.1.0/libgo/runtime/time.goc"
int64 runtime_unixnanotime ( void ) 
{ 
struct time_now_ret r; 
#line 59 "../../../gcc-5.1.0/libgo/runtime/time.goc"
r = now ( ) ; 
return r.sec*1000000000 + r.nsec; 
} 
#line 63 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void timerproc ( void* ) ; 
static void siftup ( int32 ) ; 
static void siftdown ( int32 ) ; 
#line 68 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
ready ( Eface e , uintptr seq ) 
{ 
USED ( seq ) ; 
#line 73 "../../../gcc-5.1.0/libgo/runtime/time.goc"
runtime_ready ( e.__object ) ; 
} 
#line 76 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static FuncVal readyv = { ( void ( * ) ( void ) ) ready } ; 
#line 79 "../../../gcc-5.1.0/libgo/runtime/time.goc"
void 
runtime_tsleep ( int64 ns , const char *reason ) 
{ 
G* g; 
Timer t; 
#line 85 "../../../gcc-5.1.0/libgo/runtime/time.goc"
g = runtime_g ( ) ; 
#line 87 "../../../gcc-5.1.0/libgo/runtime/time.goc"
if ( ns <= 0 ) 
return; 
#line 90 "../../../gcc-5.1.0/libgo/runtime/time.goc"
t.when = runtime_nanotime ( ) + ns; 
t.period = 0; 
t.fv = &readyv; 
t.arg.__object = g; 
t.seq = 0; 
runtime_lock ( &timers ) ; 
addtimer ( &t ) ; 
runtime_parkunlock ( &timers , reason ) ; 
} 
#line 100 "../../../gcc-5.1.0/libgo/runtime/time.goc"
void 
runtime_addtimer ( Timer *t ) 
{ 
runtime_lock ( &timers ) ; 
addtimer ( t ) ; 
runtime_unlock ( &timers ) ; 
} 
#line 110 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
addtimer ( Timer *t ) 
{ 
int32 n; 
Timer **nt; 
#line 118 "../../../gcc-5.1.0/libgo/runtime/time.goc"
if ( t->when < 0 ) 
t->when = ( int64 ) ( ( 1ULL<<63 ) -1 ) ; 
#line 121 "../../../gcc-5.1.0/libgo/runtime/time.goc"
if ( timers.len >= timers.cap ) { 
#line 123 "../../../gcc-5.1.0/libgo/runtime/time.goc"
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 ) { 
#line 137 "../../../gcc-5.1.0/libgo/runtime/time.goc"
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; 
} 
if ( debug ) 
dumptimers ( "addtimer" ) ; 
} 
#line 155 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static int32 gi; 
#line 160 "../../../gcc-5.1.0/libgo/runtime/time.goc"
bool 
runtime_deltimer ( Timer *t ) 
{ 
int32 i; 
#line 167 "../../../gcc-5.1.0/libgo/runtime/time.goc"
i = t->i; 
gi = i; 
#line 170 "../../../gcc-5.1.0/libgo/runtime/time.goc"
runtime_lock ( &timers ) ; 
#line 175 "../../../gcc-5.1.0/libgo/runtime/time.goc"
i = t->i; 
if ( i < 0 || i >= timers.len || timers.t[i] != t ) { 
runtime_unlock ( &timers ) ; 
return false; 
} 
#line 181 "../../../gcc-5.1.0/libgo/runtime/time.goc"
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 ) ; 
} 
if ( debug ) 
dumptimers ( "deltimer" ) ; 
runtime_unlock ( &timers ) ; 
return true; 
} 
#line 201 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
timerproc ( void* dummy __attribute__ ( ( unused ) ) ) 
{ 
int64 delta , now; 
Timer *t; 
FuncVal *fv; 
void ( *f ) ( Eface , uintptr ) ; 
Eface arg; 
uintptr seq; 
#line 211 "../../../gcc-5.1.0/libgo/runtime/time.goc"
for ( ;; ) { 
runtime_lock ( &timers ) ; 
timers.sleeping = false; 
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 ) { 
#line 226 "../../../gcc-5.1.0/libgo/runtime/time.goc"
t->when += t->period * ( 1 + -delta/t->period ) ; 
siftdown ( 0 ) ; 
} else { 
#line 230 "../../../gcc-5.1.0/libgo/runtime/time.goc"
timers.t[0] = timers.t[--timers.len]; 
timers.t[0]->i = 0; 
siftdown ( 0 ) ; 
t->i = -1; 
} 
fv = t->fv; 
f = ( void* ) t->fv->fn; 
arg = t->arg; 
seq = t->seq; 
runtime_unlock ( &timers ) ; 
__builtin_call_with_static_chain ( f ( arg , seq ) , fv ) ; 
#line 243 "../../../gcc-5.1.0/libgo/runtime/time.goc"
f = nil; 
USED ( f ) ; 
arg.__type_descriptor = nil; 
arg.__object = nil; 
USED ( &arg ) ; 
#line 249 "../../../gcc-5.1.0/libgo/runtime/time.goc"
runtime_lock ( &timers ) ; 
} 
if ( delta < 0 ) { 
#line 253 "../../../gcc-5.1.0/libgo/runtime/time.goc"
timers.rescheduling = true; 
runtime_g ( ) ->isbackground = true; 
runtime_parkunlock ( &timers , "timer goroutine (idle)" ) ; 
runtime_g ( ) ->isbackground = false; 
continue; 
} 
#line 260 "../../../gcc-5.1.0/libgo/runtime/time.goc"
timers.sleeping = true; 
runtime_noteclear ( &timers.waitnote ) ; 
runtime_unlock ( &timers ) ; 
runtime_notetsleepg ( &timers.waitnote , delta ) ; 
} 
} 
#line 269 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
siftup ( int32 i ) 
{ 
int32 p; 
int64 when; 
Timer **t , *tmp; 
#line 276 "../../../gcc-5.1.0/libgo/runtime/time.goc"
t = timers.t; 
when = t[i]->when; 
tmp = t[i]; 
while ( i > 0 ) { 
p = ( i-1 ) /4; 
if ( when >= t[p]->when ) 
break; 
t[i] = t[p]; 
t[i]->i = i; 
t[p] = tmp; 
tmp->i = p; 
i = p; 
} 
} 
#line 291 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
siftdown ( int32 i ) 
{ 
int32 c , c3 , len; 
int64 when , w , w3; 
Timer **t , *tmp; 
#line 298 "../../../gcc-5.1.0/libgo/runtime/time.goc"
t = timers.t; 
len = timers.len; 
when = t[i]->when; 
tmp = t[i]; 
for ( ;; ) { 
c = i*4 + 1; 
c3 = c + 2; 
if ( c >= len ) { 
break; 
} 
w = t[c]->when; 
if ( c+1 < len && t[c+1]->when < w ) { 
w = t[c+1]->when; 
c++; 
} 
if ( c3 < len ) { 
w3 = t[c3]->when; 
if ( c3+1 < len && t[c3+1]->when < w3 ) { 
w3 = t[c3+1]->when; 
c3++; 
} 
if ( w3 < w ) { 
w = w3; 
c = c3; 
} 
} 
if ( w >= when ) 
break; 
t[i] = t[c]; 
t[i]->i = i; 
t[c] = tmp; 
tmp->i = c; 
i = c; 
} 
} 
#line 334 "../../../gcc-5.1.0/libgo/runtime/time.goc"
static void 
dumptimers ( const char *msg ) 
{ 
Timer *t; 
int32 i; 
#line 340 "../../../gcc-5.1.0/libgo/runtime/time.goc"
runtime_printf ( "timers: %s\n" , msg ) ; 
for ( i = 0; i < timers.len; i++ ) { 
t = timers.t[i]; 
runtime_printf ( "\t%d\t%p:\ti %d when %D period %D fn %p\n" , 
i , t , t->i , t->when , t->period , t->fv->fn ) ; 
} 
runtime_printf ( "\n" ) ; 
} 
#line 349 "../../../gcc-5.1.0/libgo/runtime/time.goc"
void 
runtime_time_scan ( struct Workbuf** wbufp , void ( *enqueue1 ) ( struct Workbuf** , Obj ) ) 
{ 
enqueue1 ( wbufp , ( Obj ) { ( byte* ) &timers , sizeof timers , 0 } ) ; 
} 