mirror of
https://github.com/golang/go
synced 2024-11-12 07:40:23 -07:00
runtime: fix tv_sec 32-bit overflows in sleep routines.
Fixes #5063. R=golang-dev, minux.ma, rsc CC=golang-dev https://golang.org/cl/7876043
This commit is contained in:
parent
e7537157a5
commit
ba50e4f120
13
src/pkg/runtime/export_futex_test.go
Normal file
13
src/pkg/runtime/export_futex_test.go
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// +build linux freebsd
|
||||
|
||||
package runtime
|
||||
|
||||
func futexsleep(addr *uint32, val uint32, ns int64)
|
||||
func futexwakeup(addr *uint32, val uint32)
|
||||
|
||||
var Futexsleep = futexsleep
|
||||
var Futexwakeup = futexwakeup
|
31
src/pkg/runtime/futex_test.go
Normal file
31
src/pkg/runtime/futex_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2013 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.
|
||||
|
||||
// +build linux freebsd
|
||||
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
. "runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFutexsleep(t *testing.T) {
|
||||
ch := make(chan bool, 1)
|
||||
var dummy uint32
|
||||
start := time.Now()
|
||||
go func() {
|
||||
Entersyscall()
|
||||
Futexsleep(&dummy, 0, (1<<31+100)*1e9)
|
||||
Exitsyscall()
|
||||
ch <- true
|
||||
}()
|
||||
select {
|
||||
case <-ch:
|
||||
t.Errorf("futexsleep finished early after %s!", time.Since(start))
|
||||
case <-time.After(time.Second):
|
||||
Futexwakeup(&dummy, 1)
|
||||
}
|
||||
}
|
@ -409,9 +409,14 @@ int32
|
||||
runtime·mach_semacquire(uint32 sem, int64 ns)
|
||||
{
|
||||
int32 r;
|
||||
int64 secs;
|
||||
|
||||
if(ns >= 0) {
|
||||
r = runtime·mach_semaphore_timedwait(sem, ns/1000000000LL, ns%1000000000LL);
|
||||
secs = ns/1000000000LL;
|
||||
// Avoid overflow
|
||||
if(secs > 1LL<<30)
|
||||
secs = 1LL<<30;
|
||||
r = runtime·mach_semaphore_timedwait(sem, secs, ns%1000000000LL);
|
||||
if(r == KERN_ABORTED || r == KERN_OPERATION_TIMED_OUT)
|
||||
return -1;
|
||||
if(r != 0)
|
||||
|
@ -45,11 +45,16 @@ runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
|
||||
{
|
||||
int32 ret;
|
||||
Timespec ts, *tsp;
|
||||
int64 secs;
|
||||
|
||||
if(ns < 0)
|
||||
tsp = nil;
|
||||
else {
|
||||
ts.tv_sec = ns / 1000000000LL;
|
||||
secs = ns / 1000000000LL;
|
||||
// Avoid overflow
|
||||
if(secs > 1LL<<30)
|
||||
secs = 1LL<<30;
|
||||
ts.tv_sec = secs;
|
||||
ts.tv_nsec = ns % 1000000000LL;
|
||||
tsp = &ts;
|
||||
}
|
||||
|
@ -36,15 +36,17 @@ void
|
||||
runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
|
||||
{
|
||||
Timespec ts, *tsp;
|
||||
int64 secs;
|
||||
|
||||
if(ns < 0)
|
||||
tsp = nil;
|
||||
else {
|
||||
ts.tv_sec = ns/1000000000LL;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
secs = ns/1000000000LL;
|
||||
// Avoid overflow
|
||||
if(ts.tv_sec > 1<<30)
|
||||
ts.tv_sec = 1<<30;
|
||||
if(secs > 1LL<<30)
|
||||
secs = 1LL<<30;
|
||||
ts.tv_sec = secs;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
tsp = &ts;
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@ int32
|
||||
runtime·semasleep(int64 ns)
|
||||
{
|
||||
Timespec ts;
|
||||
int64 secs;
|
||||
|
||||
// spin-mutex lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
@ -93,7 +94,11 @@ runtime·semasleep(int64 ns)
|
||||
runtime·lwp_park(nil, 0, &m->waitsemacount, nil);
|
||||
} else {
|
||||
ns += runtime·nanotime();
|
||||
ts.tv_sec = ns/1000000000LL;
|
||||
secs = ns/1000000000LL;
|
||||
// Avoid overflow
|
||||
if(secs > 1LL<<30)
|
||||
secs = 1LL<<30;
|
||||
ts.tv_sec = secs;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
// TODO(jsing) - potential deadlock!
|
||||
// See above for details.
|
||||
|
@ -62,6 +62,7 @@ int32
|
||||
runtime·semasleep(int64 ns)
|
||||
{
|
||||
Timespec ts;
|
||||
int64 secs;
|
||||
|
||||
// spin-mutex lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
@ -76,7 +77,11 @@ runtime·semasleep(int64 ns)
|
||||
runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock, nil);
|
||||
else {
|
||||
ns += runtime·nanotime();
|
||||
ts.tv_sec = ns/1000000000LL;
|
||||
secs = ns/1000000000LL;
|
||||
// Avoid overflow
|
||||
if(secs > 1LL<<30)
|
||||
secs = 1LL<<30;
|
||||
ts.tv_sec = secs;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
runtime·thrsleep(&m->waitsemacount, CLOCK_REALTIME, &ts, &m->waitsemalock, nil);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user