mirror of
https://github.com/golang/go
synced 2024-11-19 22:44:45 -07:00
runtime/race: lazily allocate shadow memory
Currently race detector runtime maps shadow memory eagerly at process startup. It works poorly on Windows, because Windows requires reservation in swap file (especially problematic if several Go program runs at the same, each consuming GBs of memory). With this change race detector maps shadow memory lazily, so Go runtime must notify about all new heap memory. It will help with Windows port, but also eliminates scary 16TB virtual mememory consumption in top output (which sometimes confuses some monitoring scripts). R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6811085
This commit is contained in:
parent
a3a7244779
commit
1a19f01a68
@ -434,6 +434,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
|
||||
runtime·SysMap(p, n);
|
||||
h->arena_used += n;
|
||||
runtime·MHeap_MapBits(h);
|
||||
if(raceenabled)
|
||||
runtime·racemapshadow(p, n);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -460,6 +462,8 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
|
||||
if(h->arena_used > h->arena_end)
|
||||
h->arena_end = h->arena_used;
|
||||
runtime·MHeap_MapBits(h);
|
||||
if(raceenabled)
|
||||
runtime·racemapshadow(p, n);
|
||||
}
|
||||
|
||||
return p;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "race.h"
|
||||
|
||||
void runtime∕race·Initialize(void);
|
||||
void runtime∕race·MapShadow(void *addr, uintptr size);
|
||||
void runtime∕race·Finalize(void);
|
||||
void runtime∕race·FinalizerGoroutine(int32);
|
||||
void runtime∕race·Read(int32 goid, void *addr, void *pc);
|
||||
@ -35,6 +36,7 @@ runtime·raceinit(void)
|
||||
{
|
||||
m->racecall = true;
|
||||
runtime∕race·Initialize();
|
||||
runtime∕race·MapShadow(noptrdata, enoptrbss - noptrdata);
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
@ -46,6 +48,14 @@ runtime·racefini(void)
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·racemapshadow(void *addr, uintptr size)
|
||||
{
|
||||
m->racecall = true;
|
||||
runtime∕race·MapShadow(addr, size);
|
||||
m->racecall = false;
|
||||
}
|
||||
|
||||
// Called from instrumented code.
|
||||
// If we split stack, getcallerpc() can return runtime·lessstack().
|
||||
#pragma textflag 7
|
||||
|
@ -15,6 +15,7 @@ void runtime·raceinit(void);
|
||||
// Finalize race detection subsystem, does not return.
|
||||
void runtime·racefini(void);
|
||||
|
||||
void runtime·racemapshadow(void *addr, uintptr size);
|
||||
void runtime·racemalloc(void *p, uintptr sz, void *pc);
|
||||
void runtime·racefree(void *p);
|
||||
void runtime·racegostart(int32 goid, void *pc);
|
||||
|
@ -10,6 +10,7 @@ package race
|
||||
/*
|
||||
void __tsan_init(void);
|
||||
void __tsan_fini(void);
|
||||
void __tsan_map_shadow(void *addr, void *size);
|
||||
void __tsan_go_start(int pgoid, int chgoid, void *pc);
|
||||
void __tsan_go_end(int goid);
|
||||
void __tsan_read(int goid, void *addr, void *pc);
|
||||
@ -38,6 +39,10 @@ func Finalize() {
|
||||
C.__tsan_fini()
|
||||
}
|
||||
|
||||
func MapShadow(addr, size uintptr) {
|
||||
C.__tsan_map_shadow(unsafe.Pointer(addr), unsafe.Pointer(size))
|
||||
}
|
||||
|
||||
func FinalizerGoroutine(goid int32) {
|
||||
C.__tsan_finalizer_goroutine(C.int(goid))
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
@ -17,6 +17,14 @@ runtime·racefini(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
runtime·racemapshadow(void *addr, uintptr size)
|
||||
{
|
||||
USED(addr);
|
||||
USED(size);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·racewritepc(void *addr, void *pc)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user