summaryrefslogtreecommitdiff
path: root/rts/win32/OSMem.c
diff options
context:
space:
mode:
authorIan Lynagh <igloo@earth.li>2010-08-13 17:04:02 +0000
committerIan Lynagh <igloo@earth.li>2010-08-13 17:04:02 +0000
commit3fb074b5fcfd91fe0d37af83f221450ac4734908 (patch)
treece49021f2f6411643cfc261b79bbb73e4ea1ff1c /rts/win32/OSMem.c
parent429dc9a048f5533143fb5c9908b09d3155496e9b (diff)
downloadhaskell-3fb074b5fcfd91fe0d37af83f221450ac4734908.tar.gz
Return memory to the OS; trac #698
Diffstat (limited to 'rts/win32/OSMem.c')
-rw-r--r--rts/win32/OSMem.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c
index f61aadc762..44286d2562 100644
--- a/rts/win32/OSMem.c
+++ b/rts/win32/OSMem.c
@@ -203,6 +203,42 @@ osGetMBlocks(nat n) {
return ret;
}
+void osFreeMBlocks(char *addr, nat n)
+{
+ alloc_rec *p;
+ lnat nBytes = (lnat)n * MBLOCK_SIZE;
+
+ insertFree(addr, nBytes);
+
+ p = allocs;
+ while ((p != NULL) && (addr >= (p->base + p->size))) {
+ p = p->next;
+ }
+ while (nBytes > 0) {
+ if ((p == NULL) || (p->base > addr)) {
+ errorBelch("Memory to be freed isn't allocated\n");
+ stg_exit(EXIT_FAILURE);
+ }
+ if (p->base + p->size >= addr + nBytes) {
+ if (!VirtualFree(addr, nBytes, MEM_DECOMMIT)) {
+ sysErrorBelch("osFreeMBlocks: VirtualFree MEM_DECOMMIT failed");
+ stg_exit(EXIT_FAILURE);
+ }
+ nBytes = 0;
+ }
+ else {
+ lnat bytesToFree = p->base + p->size - addr;
+ if (!VirtualFree(addr, bytesToFree, MEM_DECOMMIT)) {
+ sysErrorBelch("osFreeMBlocks: VirtualFree MEM_DECOMMIT failed");
+ stg_exit(EXIT_FAILURE);
+ }
+ addr += bytesToFree;
+ nBytes -= bytesToFree;
+ p = p->next;
+ }
+ }
+}
+
void
osFreeAllMBlocks(void)
{