time.goc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Time-related runtime and pieces of package time.
  5. package time
  6. #include <sys/time.h>
  7. #include "runtime.h"
  8. #include "defs.h"
  9. #include "arch.h"
  10. #include "malloc.h"
  11. enum {
  12. debug = 0,
  13. };
  14. static Timers timers;
  15. static void addtimer(Timer*);
  16. static void dumptimers(const char*);
  17. // nacl fake time support.
  18. int64 runtime_timens;
  19. // Package time APIs.
  20. // Godoc uses the comments in package time, not these.
  21. // time.now is implemented in assembly.
  22. // runtimeNano returns the current value of the runtime clock in nanoseconds.
  23. func runtimeNano() (ns int64) {
  24. ns = runtime_nanotime();
  25. }
  26. // Sleep puts the current goroutine to sleep for at least ns nanoseconds.
  27. func Sleep(ns int64) {
  28. runtime_tsleep(ns, "sleep");
  29. }
  30. // startTimer adds t to the timer heap.
  31. func startTimer(t *Timer) {
  32. runtime_addtimer(t);
  33. }
  34. // stopTimer removes t from the timer heap if it is there.
  35. // It returns true if t was removed, false if t wasn't even there.
  36. func stopTimer(t *Timer) (stopped bool) {
  37. stopped = runtime_deltimer(t);
  38. }
  39. // C runtime.
  40. int64 runtime_unixnanotime(void)
  41. {
  42. struct time_now_ret r;
  43. r = now();
  44. return r.sec*1000000000 + r.nsec;
  45. }
  46. static void timerproc(void*);
  47. static void siftup(int32);
  48. static void siftdown(int32);
  49. // Ready the goroutine e.data.
  50. static void
  51. ready(Eface e, uintptr seq)
  52. {
  53. USED(seq);
  54. runtime_ready(e.__object);
  55. }
  56. static FuncVal readyv = {(void(*)(void))ready};
  57. // Put the current goroutine to sleep for ns nanoseconds.
  58. void
  59. runtime_tsleep(int64 ns, const char *reason)
  60. {
  61. G* g;
  62. Timer t;
  63. g = runtime_g();
  64. if(ns <= 0)
  65. return;
  66. t.when = runtime_nanotime() + ns;
  67. t.period = 0;
  68. t.fv = &readyv;
  69. t.arg.__object = g;
  70. t.seq = 0;
  71. runtime_lock(&timers);
  72. addtimer(&t);
  73. runtime_parkunlock(&timers, reason);
  74. }
  75. void
  76. runtime_addtimer(Timer *t)
  77. {
  78. runtime_lock(&timers);
  79. addtimer(t);
  80. runtime_unlock(&timers);
  81. }
  82. // Add a timer to the heap and start or kick the timer proc
  83. // if the new timer is earlier than any of the others.
  84. static void
  85. addtimer(Timer *t)
  86. {
  87. int32 n;
  88. Timer **nt;
  89. // when must never be negative; otherwise timerproc will overflow
  90. // during its delta calculation and never expire other timers.
  91. if(t->when < 0)
  92. t->when = (int64)((1ULL<<63)-1);
  93. if(timers.len >= timers.cap) {
  94. // Grow slice.
  95. n = 16;
  96. if(n <= timers.cap)
  97. n = timers.cap*3 / 2;
  98. nt = runtime_malloc(n*sizeof nt[0]);
  99. runtime_memmove(nt, timers.t, timers.len*sizeof nt[0]);
  100. runtime_free(timers.t);
  101. timers.t = nt;
  102. timers.cap = n;
  103. }
  104. t->i = timers.len++;
  105. timers.t[t->i] = t;
  106. siftup(t->i);
  107. if(t->i == 0) {
  108. // siftup moved to top: new earliest deadline.
  109. if(timers.sleeping) {
  110. timers.sleeping = false;
  111. runtime_notewakeup(&timers.waitnote);
  112. }
  113. if(timers.rescheduling) {
  114. timers.rescheduling = false;
  115. runtime_ready(timers.timerproc);
  116. }
  117. }
  118. if(timers.timerproc == nil) {
  119. timers.timerproc = __go_go(timerproc, nil);
  120. timers.timerproc->issystem = true;
  121. }
  122. if(debug)
  123. dumptimers("addtimer");
  124. }
  125. // Used to force a dereference before the lock is acquired.
  126. static int32 gi;
  127. // Delete timer t from the heap.
  128. // Do not need to update the timerproc:
  129. // if it wakes up early, no big deal.
  130. bool
  131. runtime_deltimer(Timer *t)
  132. {
  133. int32 i;
  134. // Dereference t so that any panic happens before the lock is held.
  135. // Discard result, because t might be moving in the heap.
  136. i = t->i;
  137. gi = i;
  138. runtime_lock(&timers);
  139. // t may not be registered anymore and may have
  140. // a bogus i (typically 0, if generated by Go).
  141. // Verify it before proceeding.
  142. i = t->i;
  143. if(i < 0 || i >= timers.len || timers.t[i] != t) {
  144. runtime_unlock(&timers);
  145. return false;
  146. }
  147. timers.len--;
  148. if(i == timers.len) {
  149. timers.t[i] = nil;
  150. } else {
  151. timers.t[i] = timers.t[timers.len];
  152. timers.t[timers.len] = nil;
  153. timers.t[i]->i = i;
  154. siftup(i);
  155. siftdown(i);
  156. }
  157. if(debug)
  158. dumptimers("deltimer");
  159. runtime_unlock(&timers);
  160. return true;
  161. }
  162. // Timerproc runs the time-driven events.
  163. // It sleeps until the next event in the timers heap.
  164. // If addtimer inserts a new earlier event, addtimer
  165. // wakes timerproc early.
  166. static void
  167. timerproc(void* dummy __attribute__ ((unused)))
  168. {
  169. int64 delta, now;
  170. Timer *t;
  171. FuncVal *fv;
  172. void (*f)(Eface, uintptr);
  173. Eface arg;
  174. uintptr seq;
  175. for(;;) {
  176. runtime_lock(&timers);
  177. timers.sleeping = false;
  178. now = runtime_nanotime();
  179. for(;;) {
  180. if(timers.len == 0) {
  181. delta = -1;
  182. break;
  183. }
  184. t = timers.t[0];
  185. delta = t->when - now;
  186. if(delta > 0)
  187. break;
  188. if(t->period > 0) {
  189. // leave in heap but adjust next time to fire
  190. t->when += t->period * (1 + -delta/t->period);
  191. siftdown(0);
  192. } else {
  193. // remove from heap
  194. timers.t[0] = timers.t[--timers.len];
  195. timers.t[0]->i = 0;
  196. siftdown(0);
  197. t->i = -1; // mark as removed
  198. }
  199. fv = t->fv;
  200. f = (void*)t->fv->fn;
  201. arg = t->arg;
  202. seq = t->seq;
  203. runtime_unlock(&timers);
  204. __builtin_call_with_static_chain(f(arg, seq), fv);
  205. // clear f and arg to avoid leak while sleeping for next timer
  206. f = nil;
  207. USED(f);
  208. arg.__type_descriptor = nil;
  209. arg.__object = nil;
  210. USED(&arg);
  211. runtime_lock(&timers);
  212. }
  213. if(delta < 0) {
  214. // No timers left - put goroutine to sleep.
  215. timers.rescheduling = true;
  216. runtime_g()->isbackground = true;
  217. runtime_parkunlock(&timers, "timer goroutine (idle)");
  218. runtime_g()->isbackground = false;
  219. continue;
  220. }
  221. // At least one timer pending. Sleep until then.
  222. timers.sleeping = true;
  223. runtime_noteclear(&timers.waitnote);
  224. runtime_unlock(&timers);
  225. runtime_notetsleepg(&timers.waitnote, delta);
  226. }
  227. }
  228. // heap maintenance algorithms.
  229. static void
  230. siftup(int32 i)
  231. {
  232. int32 p;
  233. int64 when;
  234. Timer **t, *tmp;
  235. t = timers.t;
  236. when = t[i]->when;
  237. tmp = t[i];
  238. while(i > 0) {
  239. p = (i-1)/4; // parent
  240. if(when >= t[p]->when)
  241. break;
  242. t[i] = t[p];
  243. t[i]->i = i;
  244. t[p] = tmp;
  245. tmp->i = p;
  246. i = p;
  247. }
  248. }
  249. static void
  250. siftdown(int32 i)
  251. {
  252. int32 c, c3, len;
  253. int64 when, w, w3;
  254. Timer **t, *tmp;
  255. t = timers.t;
  256. len = timers.len;
  257. when = t[i]->when;
  258. tmp = t[i];
  259. for(;;) {
  260. c = i*4 + 1; // left child
  261. c3 = c + 2; // mid child
  262. if(c >= len) {
  263. break;
  264. }
  265. w = t[c]->when;
  266. if(c+1 < len && t[c+1]->when < w) {
  267. w = t[c+1]->when;
  268. c++;
  269. }
  270. if(c3 < len) {
  271. w3 = t[c3]->when;
  272. if(c3+1 < len && t[c3+1]->when < w3) {
  273. w3 = t[c3+1]->when;
  274. c3++;
  275. }
  276. if(w3 < w) {
  277. w = w3;
  278. c = c3;
  279. }
  280. }
  281. if(w >= when)
  282. break;
  283. t[i] = t[c];
  284. t[i]->i = i;
  285. t[c] = tmp;
  286. tmp->i = c;
  287. i = c;
  288. }
  289. }
  290. static void
  291. dumptimers(const char *msg)
  292. {
  293. Timer *t;
  294. int32 i;
  295. runtime_printf("timers: %s\n", msg);
  296. for(i = 0; i < timers.len; i++) {
  297. t = timers.t[i];
  298. runtime_printf("\t%d\t%p:\ti %d when %D period %D fn %p\n",
  299. i, t, t->i, t->when, t->period, t->fv->fn);
  300. }
  301. runtime_printf("\n");
  302. }
  303. void
  304. runtime_time_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
  305. {
  306. enqueue1(wbufp, (Obj){(byte*)&timers, sizeof timers, 0});
  307. }