source: proiecte/swift/trunk/lib/hoard-371/src/heaplayers/sbrk.c @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 2.8 KB
Line 
1#include <assert.h>
2#include <windows.h>
3#include <process.h>
4
5/* Sbrk implementation for Win32 by Emery Berger, http://www.cs.utexas.edu/users/emery */
6
7void * sbrk (long size) {
8
9/* Reserve up to 1 GB of RAM */
10/*
11    We pre-reserve a very large chunk of memory
12    and commit pages as we go. */
13
14#define PRE_RESERVE 1024 * 1024 * 1024
15
16  static long remainingReserved = PRE_RESERVE;
17
18  static int initialized = 0;
19  static char * currentPosition = NULL;
20  static char * nextPage = NULL;
21  static long remainingCommitted = 0;
22  static long pageSize;
23  void * p;
24 
25  if (!initialized) {
26
27    /*
28      Do one-time initialization stuff:
29      get the page size from the system,
30      reserve a large range of memory,
31      and initialize the appropriate variables.
32
33    */
34
35    SYSTEM_INFO sSysInfo;
36    LPVOID base;
37    GetSystemInfo(&sSysInfo);
38   
39    pageSize = sSysInfo.dwPageSize;
40   
41    /* Reserve pages in the process's virtual address space. */
42   
43#if 1
44    base = VirtualAlloc(NULL, remainingReserved, MEM_RESERVE, PAGE_NOACCESS);
45#else
46    base = VirtualAlloc(NULL, remainingReserved, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
47        remainingCommitted =  PRE_RESERVE;
48#endif
49
50    if (base == NULL )
51      exit (1); /* VirtualAlloc reserve failed */
52
53    currentPosition = nextPage = (char *) base;
54    initialized = 1;
55  }
56
57  if (size < 0) {
58
59#if 0
60  /* Uncommit pages if possible.
61       Round the size down to a multiple of the page size,
62       and decommit those pages.
63    */
64
65
66    int bytesToUncommit = (-size & ~(pageSize - 1));
67
68    if (bytesToUncommit > PRE_RESERVE - remainingReserved) {
69      /* Error -- the user has tried to free memory that we never
70         even reserved. */
71      return currentPosition;
72    }
73
74    if (bytesToUncommit > 0) {
75
76      int result = VirtualFree (nextPage - bytesToUncommit, bytesToUncommit, MEM_DECOMMIT);
77      if (result == 0) {
78        /* Error -- don't change a thing. */
79        return currentPosition;
80      }
81      remainingCommitted -= bytesToUncommit;
82    }
83
84    currentPosition -= size;
85    remainingReserved += size;
86#endif
87    return currentPosition;
88
89  }
90
91  if (size > 0) {
92    void * p;
93    if (size > remainingCommitted) {
94
95      /* Commit some more pages.
96         We round up to an even number of pages.
97         Note that page size must be a power of two.
98      */
99
100      int bytesToCommit = (size - remainingCommitted + pageSize - 1) & ~(pageSize - 1); 
101      int * result;
102
103      result = VirtualAlloc((LPVOID) nextPage, bytesToCommit, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
104
105      if (result == NULL )
106        exit (1); /* VirtualAlloc commit failed */
107
108      nextPage += bytesToCommit;
109      remainingCommitted += bytesToCommit;
110    }
111     
112    p = currentPosition;
113    currentPosition += size;
114    remainingCommitted -= size;
115    remainingReserved -= size;
116    return p;
117  }
118
119  assert (size == 0);
120  return currentPosition;
121
122}
Note: See TracBrowser for help on using the repository browser.