home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / efence / part01 / page.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-01  |  3.6 KB  |  171 lines

  1. #include "efence.h"
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <sys/mman.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>
  9.  
  10. /*
  11.  * For some reason, I can't find mprotect() in any of the headers on
  12.  * IRIX or SunOS 4.1.2
  13.  */
  14. extern C_LINKAGE int mprotect(caddr_t addr, size_t len, int prot);
  15.  
  16. static caddr_t    startAddr = (caddr_t) 0;
  17.  
  18. #if ( !defined(sgi) && !defined(_AIX) )
  19. extern int    sys_nerr;
  20. extern char *    sys_errlist[];
  21. #endif
  22.  
  23. static const char *
  24. stringErrorReport(void)
  25. {
  26. #if ( defined(sgi) )
  27.     return strerror(oserror());
  28. #elif ( defined(_AIX) )
  29.     return strerror(errno);
  30. #else
  31.     if ( errno > 0 && errno < sys_nerr )
  32.         return sys_errlist[errno];
  33.     else
  34.         return "Unknown error.\n";
  35. #endif
  36. }
  37.  
  38. /*
  39.  * Create memory.
  40.  */
  41. #if defined(MAP_ANONYMOUS)
  42. void *
  43. Page_Create(size_t size)
  44. {
  45.     caddr_t        allocation;
  46.  
  47.     /*
  48.      * In this version, "startAddr" is a _hint_, not a demand.
  49.      * When the memory I map here is contiguous with other
  50.      * mappings, the allocator can coalesce the memory from two
  51.      * or more mappings into one large contiguous chunk, and thus
  52.      * might be able to find a fit that would not otherwise have
  53.      * been possible. I could _force_ it to be contiguous by using
  54.      * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
  55.      * generated by other software, etc.
  56.      */
  57.     allocation = mmap(
  58.      startAddr
  59.     ,(int)size
  60.     ,PROT_READ|PROT_WRITE
  61.     ,MAP_PRIVATE|MAP_ANONYMOUS
  62.     ,-1
  63.     ,0);
  64.  
  65.     startAddr = allocation + size;
  66.  
  67.     if ( allocation == (caddr_t)-1 )
  68.         EF_Exit("mmap() failed: %s", stringErrorReport());
  69.  
  70.     return (void *)allocation;
  71. }
  72. #else
  73. void *
  74. Page_Create(size_t size)
  75. {
  76.     static int    devZeroFd = -1;
  77.     caddr_t        allocation;
  78.  
  79.     if ( devZeroFd == -1 ) {
  80.         devZeroFd = open("/dev/zero", O_RDWR);
  81.         if ( devZeroFd < 0 )
  82.             EF_Exit(
  83.              "open() on /dev/zero failed: %s"
  84.             ,stringErrorReport());
  85.     }
  86.  
  87.     /*
  88.      * In this version, "startAddr" is a _hint_, not a demand.
  89.      * When the memory I map here is contiguous with other
  90.      * mappings, the allocator can coalesce the memory from two
  91.      * or more mappings into one large contiguous chunk, and thus
  92.      * might be able to find a fit that would not otherwise have
  93.      * been possible. I could _force_ it to be contiguous by using
  94.      * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
  95.      * generated by other software, etc.
  96.      */
  97.     allocation = mmap(
  98.      startAddr
  99.     ,(int)size
  100.     ,PROT_READ|PROT_WRITE
  101.     ,MAP_PRIVATE
  102.     ,devZeroFd
  103.     ,0);
  104.  
  105.     startAddr = allocation + size;
  106.  
  107.     if ( allocation == (caddr_t)-1 )
  108.         EF_Exit("mmap() failed: %s", stringErrorReport());
  109.  
  110.     return (void *)allocation;
  111. }
  112. #endif
  113.  
  114. static void
  115. mprotectFailed(void)
  116. {
  117.     EF_Exit("mprotect() failed: %s", stringErrorReport());
  118. }
  119.  
  120. void
  121. Page_AllowAccess(void * address, size_t size)
  122. {
  123.     if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
  124.         mprotectFailed();
  125. }
  126.  
  127. void
  128. Page_DenyAccess(void * address, size_t size)
  129. {
  130.     if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
  131.         mprotectFailed();
  132. }
  133.  
  134. void
  135. Page_Delete(void * address, size_t size)
  136. {
  137. /*
  138.  * My SGI ONYX running IRIX 5.0 crashes reliably when "tstheap 3072" is
  139.  * run with the munmap call below compiled in. I'd like to hear how well
  140.  * other operating systems handle it, so that I can enable it on those
  141.  * systems.
  142.  */
  143. #if ( defined(_AIX) )
  144.     if ( munmap((caddr_t)address, size) < 0 )
  145.         EF_Exit("munmap() failed: %s", stringErrorReport());
  146. #else
  147.     Page_DenyAccess(address, size);
  148. #endif
  149. }
  150.  
  151. #if defined(_SC_PAGESIZE)
  152. size_t
  153. Page_Size(void)
  154. {
  155.     return (size_t)sysconf(_SC_PAGESIZE);
  156. }
  157. #elif defined(_SC_PAGE_SIZE)
  158. size_t
  159. Page_Size(void)
  160. {
  161.     return (size_t)sysconf(_SC_PAGE_SIZE);
  162. }
  163. #else
  164. extern int    getpagesize();
  165. size_t
  166. Page_Size(void)
  167. {
  168.     return getpagesize();
  169. }
  170. #endif
  171.