Commit 4e76abbc authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: implement SysUnused on windows

Fixes #5584.

R=golang-dev, chaishushan, alex.brainman
CC=golang-dev
https://golang.org/cl/12720043
parent f8ca13c3
...@@ -157,8 +157,9 @@ struct MLink ...@@ -157,8 +157,9 @@ struct MLink
// //
// SysUnused notifies the operating system that the contents // SysUnused notifies the operating system that the contents
// of the memory region are no longer needed and can be reused // of the memory region are no longer needed and can be reused
// for other purposes. The program reserves the right to start // for other purposes.
// accessing those pages in the future. // SysUsed notifies the operating system that the contents
// of the memory region are needed again.
// //
// SysFree returns it unconditionally; this is only used if // SysFree returns it unconditionally; this is only used if
// an out-of-memory error has been detected midway through // an out-of-memory error has been detected midway through
...@@ -174,6 +175,7 @@ struct MLink ...@@ -174,6 +175,7 @@ struct MLink
void* runtime·SysAlloc(uintptr nbytes); void* runtime·SysAlloc(uintptr nbytes);
void runtime·SysFree(void *v, uintptr nbytes); void runtime·SysFree(void *v, uintptr nbytes);
void runtime·SysUnused(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·SysMap(void *v, uintptr nbytes);
void* runtime·SysReserve(void *v, uintptr nbytes); void* runtime·SysReserve(void *v, uintptr nbytes);
......
...@@ -27,6 +27,13 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -27,6 +27,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE); runtime·madvise(v, n, MADV_FREE);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void void
runtime·SysFree(void *v, uintptr n) runtime·SysFree(void *v, uintptr n)
{ {
......
...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE); runtime·madvise(v, n, MADV_FREE);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void void
runtime·SysFree(void *v, uintptr n) runtime·SysFree(void *v, uintptr n)
{ {
......
...@@ -77,6 +77,13 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -77,6 +77,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_DONTNEED); runtime·madvise(v, n, MADV_DONTNEED);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void void
runtime·SysFree(void *v, uintptr n) runtime·SysFree(void *v, uintptr n)
{ {
......
...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE); runtime·madvise(v, n, MADV_FREE);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void void
runtime·SysFree(void *v, uintptr n) runtime·SysFree(void *v, uintptr n)
{ {
......
...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -31,6 +31,13 @@ runtime·SysUnused(void *v, uintptr n)
runtime·madvise(v, n, MADV_FREE); runtime·madvise(v, n, MADV_FREE);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v);
USED(n);
}
void void
runtime·SysFree(void *v, uintptr n) runtime·SysFree(void *v, uintptr n)
{ {
......
...@@ -55,6 +55,12 @@ runtime·SysUnused(void *v, uintptr nbytes) ...@@ -55,6 +55,12 @@ runtime·SysUnused(void *v, uintptr nbytes)
USED(v, nbytes); USED(v, nbytes);
} }
void
runtime·SysUsed(void *v, uintptr n)
{
USED(v, nbytes);
}
void void
runtime·SysMap(void *v, uintptr nbytes) runtime·SysMap(void *v, uintptr nbytes)
{ {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
enum { enum {
MEM_COMMIT = 0x1000, MEM_COMMIT = 0x1000,
MEM_RESERVE = 0x2000, MEM_RESERVE = 0x2000,
MEM_DECOMMIT = 0x4000,
MEM_RELEASE = 0x8000, MEM_RELEASE = 0x8000,
PAGE_READWRITE = 0x0004, PAGE_READWRITE = 0x0004,
...@@ -31,8 +32,21 @@ runtime·SysAlloc(uintptr n) ...@@ -31,8 +32,21 @@ runtime·SysAlloc(uintptr n)
void void
runtime·SysUnused(void *v, uintptr n) runtime·SysUnused(void *v, uintptr n)
{ {
USED(v); uintptr r;
USED(n);
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 void
......
...@@ -156,6 +156,7 @@ HaveSpan: ...@@ -156,6 +156,7 @@ HaveSpan:
// is just a unique constant not seen elsewhere in the // is just a unique constant not seen elsewhere in the
// runtime, as a clue in case it turns up unexpectedly in // runtime, as a clue in case it turns up unexpectedly in
// memory or in a stack trace. // memory or in a stack trace.
runtime·SysUsed((void*)(s->start<<PageShift), s->npages<<PageShift);
*(uintptr*)(s->start<<PageShift) = (uintptr)0xbeadbeadbeadbeadULL; *(uintptr*)(s->start<<PageShift) = (uintptr)0xbeadbeadbeadbeadULL;
} }
s->npreleased = 0; s->npreleased = 0;
...@@ -350,8 +351,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) ...@@ -350,8 +351,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
if(sizeof(void*) == 8) if(sizeof(void*) == 8)
p -= (uintptr)h->arena_start >> PageShift; p -= (uintptr)h->arena_start >> PageShift;
if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse) { if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse) {
if(t->npreleased == 0) { // cant't touch this otherwise
tp = (uintptr*)(t->start<<PageShift); tp = (uintptr*)(t->start<<PageShift);
*tp |= *sp; // propagate "needs zeroing" mark *tp |= *sp; // propagate "needs zeroing" mark
}
s->start = t->start; s->start = t->start;
s->npages += t->npages; s->npages += t->npages;
s->npreleased = t->npreleased; // absorb released pages s->npreleased = t->npreleased; // absorb released pages
...@@ -364,8 +367,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s) ...@@ -364,8 +367,10 @@ MHeap_FreeLocked(MHeap *h, MSpan *s)
mstats.mspan_sys = h->spanalloc.sys; 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) { if((p+s->npages)*sizeof(h->spans[0]) < h->spans_mapped && (t = h->spans[p+s->npages]) != nil && t->state != MSpanInUse) {
if(t->npreleased == 0) { // cant't touch this otherwise
tp = (uintptr*)(t->start<<PageShift); tp = (uintptr*)(t->start<<PageShift);
*sp |= *tp; // propagate "needs zeroing" mark *sp |= *tp; // propagate "needs zeroing" mark
}
s->npages += t->npages; s->npages += t->npages;
s->npreleased += t->npreleased; s->npreleased += t->npreleased;
h->spans[p + s->npages - 1] = s; h->spans[p + s->npages - 1] = s;
...@@ -401,7 +406,7 @@ scavengelist(MSpan *list, uint64 now, uint64 limit) ...@@ -401,7 +406,7 @@ scavengelist(MSpan *list, uint64 now, uint64 limit)
sumreleased = 0; sumreleased = 0;
for(s=list->next; s != list; s=s->next) { 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; released = (s->npages - s->npreleased) << PageShift;
mstats.heap_released += released; mstats.heap_released += released;
sumreleased += released; sumreleased += released;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment