X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fposix%2FOSMem.c;h=bfe12964a23cea2f5f13dda3e4f7dad432e0f371;hb=7d9eb2e45b4a9ff4cb053b1ec37602be88528b62;hp=9e6e62b95c620922f317e77a30384ec3ba212284;hpb=016bac72c041e8589ece82fe86906fc9cf8f950c;p=ghc-hetmet.git diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c index 9e6e62b..bfe1296 100644 --- a/rts/posix/OSMem.c +++ b/rts/posix/OSMem.c @@ -6,12 +6,13 @@ * * ---------------------------------------------------------------------------*/ -/* This is non-posix compliant. */ -/* #include "PosixSource.h" */ +// This is non-posix compliant. +// #include "PosixSource.h" #include "Rts.h" -#include "OSMem.h" -#include "RtsFlags.h" + +#include "RtsUtils.h" +#include "sm/OSMem.h" #ifdef HAVE_UNISTD_H #include @@ -25,6 +26,9 @@ #ifdef HAVE_STRING_H #include #endif +#ifdef HAVE_FCNTL_H +#include +#endif #include @@ -93,7 +97,7 @@ my_mmap (void *addr, lnat size) // Let's just use the underlying Mach Microkernel calls directly, // they're much nicer. - kern_return_t err; + kern_return_t err = 0; ret = addr; if(addr) // try to allocate at adress err = vm_allocate(mach_task_self(),(vm_address_t*) &ret, size, FALSE); @@ -109,8 +113,8 @@ my_mmap (void *addr, lnat size) vm_protect(mach_task_self(),(vm_address_t)ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE); } #else - ret = mmap(addr, size, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_ANON | MAP_PRIVATE, -1, 0); + ret = mmap(addr, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); #endif if (ret == (void *)-1) { @@ -118,8 +122,8 @@ my_mmap (void *addr, lnat size) (errno == EINVAL && sizeof(void*)==4 && size >= 0xc0000000)) { // If we request more than 3Gig, then we get EINVAL // instead of ENOMEM (at least on Linux). - errorBelch("out of memory (requested %lu bytes)", size); - stg_exit(EXIT_FAILURE); + errorBelch("out of memory (requested %lu bytes)", size); + stg_exit(EXIT_FAILURE); } else { barf("getMBlock: mmap: %s", strerror(errno)); } @@ -135,7 +139,7 @@ static void * gen_map_mblocks (lnat size) { int slop; - void *ret; + StgWord8 *ret; // Try to map a larger block, and take the aligned portion from // it (unmap the rest). @@ -145,10 +149,10 @@ gen_map_mblocks (lnat size) // unmap the slop bits around the chunk we allocated slop = (W_)ret & MBLOCK_MASK; - if (munmap(ret, MBLOCK_SIZE - slop) == -1) { + if (munmap((void*)ret, MBLOCK_SIZE - slop) == -1) { barf("gen_map_mblocks: munmap failed"); } - if (slop > 0 && munmap(ret+size-slop, slop) == -1) { + if (slop > 0 && munmap((void*)(ret+size-slop), slop) == -1) { barf("gen_map_mblocks: munmap failed"); } @@ -173,8 +177,8 @@ void * osGetMBlocks(nat n) { caddr_t ret; - lnat size = MBLOCK_SIZE * n; - + lnat size = MBLOCK_SIZE * (lnat)n; + if (next_request == 0) { // use gen_map_mblocks the first time. ret = gen_map_mblocks(size); @@ -195,7 +199,6 @@ osGetMBlocks(nat n) ret = gen_map_mblocks(size); } } - // Next time, we'll try to allocate right after the block we just got. // ToDo: check that we haven't already grabbed the memory at next_request next_request = ret + size; @@ -203,9 +206,24 @@ osGetMBlocks(nat n) return ret; } +void osFreeMBlocks(char *addr, nat n) +{ + munmap(addr, n * MBLOCK_SIZE); +} + +void osReleaseFreeMemory(void) { + /* Nothing to do on POSIX */ +} + void osFreeAllMBlocks(void) { - /* XXX Do something here (bug #711) */ + void *mblock; + + for (mblock = getFirstMBlock(); + mblock != NULL; + mblock = getNextMBlock(mblock)) { + munmap(mblock, MBLOCK_SIZE); + } } lnat getPageSize (void) @@ -234,6 +252,6 @@ void setExecutable (void *p, lnat len, rtsBool exec) StgWord size = startOfLastPage - startOfFirstPage + pageSize; if (mprotect((void*)startOfFirstPage, (size_t)size, (exec ? PROT_EXEC : 0) | PROT_READ | PROT_WRITE) != 0) { - barf("makeExecutable: failed to protect 0x%p\n", p); + barf("setExecutable: failed to protect 0x%p\n", p); } }