mirror of
https://github.com/golang/go
synced 2024-11-08 01:46:14 -07:00
caa2147532
Race runtime also needs local malloc caches and currently uses a mix of per-OS-thread and per-goroutine caches. This leads to increased memory consumption. But more importantly cache of synchronization objects is per-goroutine and we don't always have goroutine context when feeing memory in GC. As the result synchronization object descriptors leak (more precisely, they can be reused if another synchronization object is recreated at the same address, but it does not always help). For example, the added BenchmarkSyncLeak has effectively runaway memory consumption (based on a real long running server). This change updates race runtime with support for per-P contexts. BenchmarkSyncLeak now stabilizes at ~1GB memory consumption. Long term, this will allow us to remove race runtime dependency on glibc (as malloc is the main cornerstone). I've also implemented a different scheme to pass P context to race runtime: scheduler notified race runtime about association between G and P by calling procwire(g, p)/procunwire(g, p). But it turned out to be very messy as we have lots of places where the association changes (e.g. syscalls). So I dropped it in favor of the current scheme: race runtime asks scheduler about the current P. Fixes #14533 Change-Id: Iad10d2f816a44affae1b9fed446b3580eafd8c69 Reviewed-on: https://go-review.googlesource.com/19970 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
41 lines
2.4 KiB
Go
41 lines
2.4 KiB
Go
// Copyright 2014 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 !race
|
|
|
|
// Dummy race detection API, used when not built with -race.
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
const raceenabled = false
|
|
|
|
// Because raceenabled is false, none of these functions should be called.
|
|
|
|
func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { throw("race") }
|
|
func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { throw("race") }
|
|
func raceinit() (uintptr, uintptr) { throw("race"); return 0, 0 }
|
|
func racefini() { throw("race") }
|
|
func raceproccreate() uintptr { throw("race"); return 0 }
|
|
func raceprocdestroy(ctx uintptr) { throw("race") }
|
|
func racemapshadow(addr unsafe.Pointer, size uintptr) { throw("race") }
|
|
func racewritepc(addr unsafe.Pointer, callerpc, pc uintptr) { throw("race") }
|
|
func racereadpc(addr unsafe.Pointer, callerpc, pc uintptr) { throw("race") }
|
|
func racereadrangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr) { throw("race") }
|
|
func racewriterangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr) { throw("race") }
|
|
func raceacquire(addr unsafe.Pointer) { throw("race") }
|
|
func raceacquireg(gp *g, addr unsafe.Pointer) { throw("race") }
|
|
func racerelease(addr unsafe.Pointer) { throw("race") }
|
|
func racereleaseg(gp *g, addr unsafe.Pointer) { throw("race") }
|
|
func racereleasemerge(addr unsafe.Pointer) { throw("race") }
|
|
func racereleasemergeg(gp *g, addr unsafe.Pointer) { throw("race") }
|
|
func racefingo() { throw("race") }
|
|
func racemalloc(p unsafe.Pointer, sz uintptr) { throw("race") }
|
|
func racefree(p unsafe.Pointer, sz uintptr) { throw("race") }
|
|
func racegostart(pc uintptr) uintptr { throw("race"); return 0 }
|
|
func racegoend() { throw("race") }
|