mmaptest.nim 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. # Small test program to test for mmap() weirdnesses
  2. include "lib/system/ansi_c"
  3. const
  4. PageSize = 4096
  5. PROT_READ = 1 # page can be read
  6. PROT_WRITE = 2 # page can be written
  7. MAP_PRIVATE = 2 # Changes are private
  8. when defined(macosx) or defined(bsd):
  9. const MAP_ANONYMOUS = 0x1000
  10. elif defined(solaris):
  11. const MAP_ANONYMOUS = 0x100
  12. else:
  13. var
  14. MAP_ANONYMOUS {.importc: "MAP_ANONYMOUS", header: "<sys/mman.h>".}: cint
  15. proc mmap(adr: pointer, len: int, prot, flags, fildes: cint,
  16. off: int): pointer {.header: "<sys/mman.h>".}
  17. proc munmap(adr: pointer, len: int) {.header: "<sys/mman.h>".}
  18. proc osAllocPages(size: int): pointer {.inline.} =
  19. result = mmap(nil, size, PROT_READ or PROT_WRITE,
  20. MAP_PRIVATE or MAP_ANONYMOUS, -1, 0)
  21. if result == nil or result == cast[pointer](-1):
  22. quit 1
  23. cfprintf(c_stdout, "allocated pages %p..%p\n", result,
  24. cast[int](result) + size)
  25. proc osDeallocPages(p: pointer, size: int) {.inline} =
  26. cfprintf(c_stdout, "freed pages %p..%p\n", p, cast[int](p) + size)
  27. munmap(p, size-1)
  28. proc `+!!`(p: pointer, size: int): pointer {.inline.} =
  29. result = cast[pointer](cast[int](p) + size)
  30. var p = osAllocPages(3 * PageSize)
  31. osDeallocPages(p, PageSize)
  32. # If this fails the OS has freed the whole block starting at 'p':
  33. echo(cast[ptr int](p +!! (pageSize*2))[])
  34. osDeallocPages(p +!! PageSize*2, PageSize)
  35. osDeallocPages(p +!! PageSize, PageSize)