]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement SysUnused on windows
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 14 Aug 2013 17:54:07 +0000 (21:54 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 14 Aug 2013 17:54:07 +0000 (21:54 +0400)
Fixes #5584.

R=golang-dev, chaishushan, alex.brainman
CC=golang-dev
https://golang.org/cl/12720043

src/pkg/runtime/malloc.h
src/pkg/runtime/mem_darwin.c
src/pkg/runtime/mem_freebsd.c
src/pkg/runtime/mem_linux.c
src/pkg/runtime/mem_netbsd.c
src/pkg/runtime/mem_openbsd.c
src/pkg/runtime/mem_plan9.c
src/pkg/runtime/mem_windows.c
src/pkg/runtime/mheap.c

index 20cf6fb96b04b9fbc51a58f5bb9a0d9e6ff27d2a..36166543ee3ba0f47d85bdb9ee89ded17770711a 100644 (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);
 
index 7aa607f8ee727d2809980b6ca0047ca5268493be..ef5674e3408aa68088b2c0753cd08480f5552694 100644 (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)
 {
index 805e74cffba6943373787ab909a36aed6c2c339a..e47ea7a436d10aff1a00b4922ee24b2da6c881f0 100644 (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)
 {
index bacd568d9e0c3fa642085c09ce96c09a55e986b6..d96eb69e899a213c11c5e36dfea28620bddffa2a 100644 (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)
 {
index e5bdac0ef65ebbf5b11ae7940210bc6788bfc8f8..8a7ef17e84f72e394f61d7283ea52be84a3826f8 100644 (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)
 {
index e5bdac0ef65ebbf5b11ae7940210bc6788bfc8f8..8a7ef17e84f72e394f61d7283ea52be84a3826f8 100644 (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)
 {
index 26ca367f11ebdd0191a1433ef7b8108fa03b3df7..3aa16eb3a639195be540f6fc25dc8ba683363391 100644 (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)
 {
index 1a778b77527c1977a53129c3d77a6f93414c33fe..0a1ea38d567f3bff0615c9fae40d8495c989063e 100644 (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
index c03b13bdfd8cd8fe2aadc2299045f0089e60e63a..d7713965cfc9aaad6ee6902dc15abb7d57b07a59 100644 (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;