home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / src / memory / prseg.c < prev   
Encoding:
C/C++ Source or Header  |  1998-04-08  |  4.8 KB  |  193 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "primpl.h"
  20.  
  21. void _PR_InitSegs(void)
  22. {
  23.     _PR_MD_INIT_SEGS();
  24. }
  25.  
  26. /*
  27. ** Allocate a memory segment. The size value is rounded up to the native
  28. ** system page size and a page aligned portion of memory is returned.
  29. ** This memory is not part of the malloc heap. If "vaddr" is not NULL
  30. ** then PR tries to allocate the segment at the desired virtual address.
  31. */
  32. PR_IMPLEMENT(PRSegment*) PR_NewSegment(PRUint32 size, void *vaddr)
  33. {
  34.     PRSegment *seg;
  35.  
  36.     /* calloc the data structure for the segment */
  37.     seg = PR_NEWZAP(PRSegment);
  38.  
  39.     if (seg) {
  40.         size = ((size + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
  41.         /*
  42.         **    Now, allocate the actual segment memory (or map under some OS)
  43.         **    The OS specific code decides from where or how to allocate memory.
  44.         */
  45.         if (_PR_MD_ALLOC_SEGMENT(seg, size, vaddr) != PR_SUCCESS) {
  46.             PR_DELETE(seg);
  47.             return NULL;
  48.         }
  49.     }
  50.  
  51.     return seg;
  52. }
  53.  
  54. /*
  55. ** Free a memory segment.
  56. */
  57. PR_IMPLEMENT(void) PR_DestroySegment(PRSegment *seg)
  58. {
  59.     _PR_MD_FREE_SEGMENT(seg);
  60.     PR_DELETE(seg);
  61. }
  62.  
  63. /* XXX Fix the following to make machine-independent */
  64. #ifdef XP_UNIX
  65. #include <sys/mman.h>
  66. #endif
  67.  
  68. #ifndef PROT_NONE
  69. #define PROT_NONE 0
  70. #endif
  71.  
  72. extern    PRInt32 _pr_zero_fd;
  73.  
  74. /*
  75. ** Attempt to grow/shrink the given segment.
  76. */
  77. PR_IMPLEMENT(PRUint32) PR_GrowSegment(PRSegment *seg, PRInt32 delta)
  78. {
  79.     char *oldend, *newend;
  80. #if 0
  81. #ifdef XP_UNIX
  82.     int prot;
  83.     void *rv = (void *) -1;
  84. #endif
  85. #endif /* 0 */
  86.  
  87.     if (!(seg->flags & _PR_SEG_VM)) {
  88.         return 0;
  89.     }
  90.  
  91.     oldend = (char*)seg->vaddr + seg->size;
  92.     if (delta > 0) {
  93. #if 0
  94.  
  95.         /*
  96.          * CANNOT use MAP_FIXED because it will replace any existing mappings
  97.          */
  98.         /* Growing the segment */
  99.         delta = ((delta + _pr_pageSize - 1) >> _pr_pageShift) << _pr_pageShift;
  100.         newend = oldend + delta;
  101. #ifdef XP_UNIX
  102.         prot = PROT_READ|PROT_WRITE;
  103.         rv = mmap(oldend, delta, prot,
  104. #ifdef OSF1
  105.                   /* XXX need to pick a vaddr to use */
  106.                   MAP_PRIVATE|MAP_FIXED,
  107. #else
  108.                   MAP_SHARED|MAP_FIXED,
  109. #endif
  110.                   _pr_zero_fd, 0);
  111. #endif    /* XP_UNIX */
  112.         if (rv == (void*)-1) {
  113.             /* Can't extend the heap */
  114.             return 0;
  115.         }
  116.         seg->size = seg->size + delta;
  117. #endif /* 0 */
  118.     } else if (delta < 0) {
  119.         /* Shrinking the segment */
  120.         delta = -delta;
  121.         delta = (delta >> _pr_pageShift) << _pr_pageShift;      /* trunc */
  122.         if ((PRUint32)delta >= seg->size) {
  123.             /* XXX what to do? */
  124.             return 0;
  125.         }
  126.         newend = oldend - delta;
  127.         if (newend < oldend) {
  128. #ifdef XP_UNIX
  129.             (void) munmap(oldend, newend - oldend);
  130.             seg->size = seg->size + delta;
  131. #endif
  132.         }
  133.     }
  134.     return delta;
  135. }
  136.  
  137. /*
  138. ** Change the mapping on a segment.
  139. **     "how" == PR_SEGMENT_NONE: the segment becomes unmapped
  140. **     "how" == PR_SEGMENT_RDONLY: the segment becomes mapped and readable
  141. **     "how" == PR_SEGMENT_RDWR: the segment becomes mapped read/write
  142. **
  143. ** If a segment can be read then it is also possible to execute code in
  144. ** it.
  145. */
  146. PR_IMPLEMENT(void) PR_MapSegment(PRSegment *seg, PRSegmentAccess how)
  147. {
  148.     if (seg->access == how) return;
  149.     seg->access = how;
  150.  
  151. #ifdef XP_UNIX
  152.     if (seg->flags & _PR_SEG_VM) {
  153.     int prot;
  154.     switch (how) {
  155.       case PR_SEGMENT_NONE:
  156.         prot = PROT_NONE;
  157.         break;
  158.       case PR_SEGMENT_RDONLY:
  159.         prot = PROT_READ;
  160.         break;
  161.       case PR_SEGMENT_RDWR:
  162.         prot = PROT_READ|PROT_WRITE;
  163.         break;
  164.     }
  165.     (void) mprotect(seg->vaddr, seg->size, prot);
  166.     }
  167. #endif
  168. }
  169.  
  170. /*
  171. ** Return the size of the segment
  172. */
  173. PR_IMPLEMENT(size_t) PR_GetSegmentSize(PRSegment *seg)
  174. {
  175.     return seg->size;
  176. }
  177.  
  178. /*
  179. ** Return the virtual address of the segment
  180. */
  181. PR_IMPLEMENT(void*) PR_GetSegmentVaddr(PRSegment *seg)
  182. {
  183.     return seg->vaddr;
  184. }
  185.  
  186. /*
  187. ** Return a segments current access rights
  188. */
  189. PR_IMPLEMENT(PRSegmentAccess) PR_GetSegmentAccess(PRSegment *seg)
  190. {
  191.     return seg->access;
  192. }
  193.