mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: add timer support, use for package time
This looks like it is just moving some code from time to runtime (and translating it to C), but the runtime can do a better job managing the goroutines, and it needs this functionality for its own maintenance (for example, for the garbage collector to hand back unused memory to the OS on a time delay). Might as well have just one copy of the timer logic, and runtime can't depend on time, so vice versa. It also unifies Sleep, NewTicker, and NewTimer behind one mechanism, so that there are no claims that one is more efficient than another. (For example, today people recommend using time.After instead of time.Sleep to avoid blocking an OS thread.) Fixes #1644. Fixes #1731. Fixes #2190. R=golang-dev, r, hectorchu, iant, iant, jsing, alex.brainman, dvyukov CC=golang-dev https://golang.org/cl/5334051
This commit is contained in:
parent
fbfed49134
commit
3b860269ee
15 changed files with 662 additions and 390 deletions
|
|
@ -62,21 +62,52 @@ runtime·semacreate(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·semasleep(void)
|
||||
int32
|
||||
runtime·semasleep(int64 ns)
|
||||
{
|
||||
retry:
|
||||
Timespec ts;
|
||||
|
||||
// spin-mutex lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
runtime·osyield();
|
||||
if(m->waitsemacount == 0) {
|
||||
// the function unlocks the spinlock
|
||||
runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock);
|
||||
goto retry;
|
||||
|
||||
for(;;) {
|
||||
// lock held
|
||||
if(m->waitsemacount == 0) {
|
||||
// sleep until semaphore != 0 or timeout.
|
||||
// thrsleep unlocks m->waitsemalock.
|
||||
if(ns < 0)
|
||||
runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock);
|
||||
else {
|
||||
ts.tv_sec = ns/1000000000LL;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
runtime·thrsleep(&m->waitsemacount, CLOCK_REALTIME, &ts, &m->waitsemalock);
|
||||
}
|
||||
// reacquire lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
runtime·osyield();
|
||||
}
|
||||
|
||||
// lock held (again)
|
||||
if(m->waitsemacount != 0) {
|
||||
// semaphore is available.
|
||||
m->waitsemacount--;
|
||||
// spin-mutex unlock
|
||||
runtime·atomicstore(&m->waitsemalock, 0);
|
||||
return 0; // semaphore acquired
|
||||
}
|
||||
|
||||
// semaphore not available.
|
||||
// if there is a timeout, stop now.
|
||||
// otherwise keep trying.
|
||||
if(ns >= 0)
|
||||
break;
|
||||
}
|
||||
m->waitsemacount--;
|
||||
|
||||
// lock held but giving up
|
||||
// spin-mutex unlock
|
||||
runtime·atomicstore(&m->waitsemalock, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue