// Copyright 2017 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. package runtime import "unsafe" var labelSync uintptr //go:linkname runtime_setProfLabel runtime/pprof.runtime_setProfLabel func runtime_setProfLabel(labels unsafe.Pointer) { // Introduce race edge for read-back via profile. // This would more properly use &getg().labels as the sync address, // but we do the read in a signal handler and can't call the race runtime then. // // This uses racereleasemerge rather than just racerelease so // the acquire in profBuf.read synchronizes with *all* prior // setProfLabel operations, not just the most recent one. This // is important because profBuf.read will observe different // labels set by different setProfLabel operations on // different goroutines, so it needs to synchronize with all // of them (this wouldn't be an issue if we could synchronize // on &getg().labels since we would synchronize with each // most-recent labels write separately.) // // racereleasemerge is like a full read-modify-write on // labelSync, rather than just a store-release, so it carries // a dependency on the previous racereleasemerge, which // ultimately carries forward to the acquire in profBuf.read. if raceenabled { racereleasemerge(unsafe.Pointer(&labelSync)) } getg().labels = labels } //go:linkname runtime_getProfLabel runtime/pprof.runtime_getProfLabel func runtime_getProfLabel() unsafe.Pointer { return getg().labels }