1
0
mirror of https://github.com/golang/go synced 2024-11-25 08:57:58 -07:00

runtime: implement SysUnused on windows

Fixes #5584.

R=golang-dev, chaishushan, alex.brainman
CC=golang-dev
https://golang.org/cl/12720043
This commit is contained in:
Dmitriy Vyukov 2013-08-14 21:54:07 +04:00
parent f8ca13c3e5
commit 4e76abbc60
9 changed files with 71 additions and 9 deletions

View File

@ -157,8 +157,9 @@ struct MLink
//
// SysUnused notifies the operating system that the contents
// of the memory region are no longer needed and can be reused
// for other purposes. The program reserves the right to start
// accessing those pages in the future.
// for other purposes.
// SysUsed notifies the operating system that the contents
// of the memory region are needed again.
//
// SysFree returns it unconditionally; this is only used if
// an out-of-memory error has been detected midway through
@ -174,6 +175,7 @@ struct MLink
void* runtime·SysAlloc(uintptr nbytes);
void runtime·SysFree(void *v, uintptr nbytes);
void runtime·SysUnused(void *v, uintptr nbytes);
void runtime·SysUsed(void *v, uintptr nbytes);
void runtime·SysMap(void *v, uintptr nbytes);
void* runtime·SysReserve(void *v, uintptr nbytes);

View File

@ -27,6 +27,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
runtime·SysFree(void *v, uintptr n)
{

View File

@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
runtime·SysFree(void *v, uintptr n)
{

View File

@ -77,6 +77,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_DONTNEED);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
runtime·SysFree(void *v, uintptr n)
{

View File

@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
runtime·SysFree(void *v, uintptr n)
{

View File

@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void
runtime·SysFree(void *v, uintptr n)
{

View File

@ -55,6 +55,12 @@ runtime·SysUnused(void *v, uintptr nbytes)
USED(v, nbytes);
}
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v, nbytes);
}
void
runtime·SysMap(void *v, uintptr nbytes)
{

View File

@ -11,6 +11,7 @@
enum {
MEM_COMMIT = 0x1000,
MEM_RESERVE = 0x2000,
MEM_DECOMMIT = 0x4000,
MEM_RELEASE = 0x8000,
PAGE_READWRITE = 0x0004,
@ -31,8 +32,21 @@ runtime·SysAlloc(uintptr n)
void
runtime·SysUnused(void *v, uintptr n)
{
USED(v);
USED(n);
uintptr r;
r = runtime·stdcall(runtime·VirtualFree, 3, v, n, (uintptr)MEM_DECOMMIT);
if(r == 0)
runtime·throw("runtime: failed to decommit pages");
}
void
runtime·SysUsed(void *v, uintptr n)
{
uintptr r;
r = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_READWRITE);
if(r != v)
runtime·throw("runtime: failed to commit pages");
}
void

View File

@ -156,6 +156,7 @@ HaveSpan:
// is just a unique constant not seen elsewhere in the
// runtime, as a clue in case it turns up unexpectedly in
// memory or in a stack trace.
runtime·SysUsed((void*)(s->start<<PageShift), s->npages<<PageShift);
*(uintptr*)(s->start<<PageShift) = (uintptr)0xbeadbeadbeadbeadULL;
}
s->npreleased = 0;
@ -350,8 +351,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
if(sizeof(void*) == 8)
p -= (uintptr)h->arena_start >> PageShift;
if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse) {
tp = (uintptr*)(t->start<<PageShift);
*tp |= *sp; // propagate "needs zeroing" mark
if(t->npreleased == 0) { // cant't touch this otherwise
tp = (uintptr*)(t->start<<PageShift);
*tp |= *sp; // propagate "needs zeroing" mark
}
s->start = t->start;
s->npages += t->npages;
s->npreleased = t->npreleased; // absorb released pages
@ -364,8 +367,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
mstats.mspan_sys = h->spanalloc.sys;
}
if((p+s->npages)*sizeof(h->spans[0]) < h->spans_mapped && (t = h->spans[p+s->npages]) != nil && t->state != MSpanInUse) {
tp = (uintptr*)(t->start<<PageShift);
*sp |= *tp; // propagate "needs zeroing" mark
if(t->npreleased == 0) { // cant't touch this otherwise
tp = (uintptr*)(t->start<<PageShift);
*sp |= *tp; // propagate "needs zeroing" mark
}
s->npages += t->npages;
s->npreleased += t->npreleased;
h->spans[p + s->npages - 1] = s;
@ -401,7 +406,7 @@ scavengelist(MSpan *list, uint64 now, uint64 limit)
sumreleased = 0;
for(s=list->next; s != list; s=s->next) {
if((now - s->unusedsince) > limit) {
if((now - s->unusedsince) > limit && s->npreleased != s->npages) {
released = (s->npages - s->npreleased) << PageShift;
mstats.heap_released += released;
sumreleased += released;