(timeout-event-p): Function deleted.
[emacs.git] / src / w32heap.c
blob050bee1495133758eb970477286b12e1d0a98d45
1 /* Heap management routines for GNU Emacs on Windows NT.
2 Copyright (C) 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Geoff Voelker (voelker@cs.washington.edu) 7-29-94
24 #include "config.h"
26 #include <stdlib.h>
27 #include <stdio.h>
29 #include "ntheap.h"
31 /* This gives us the page size and the size of the allocation unit on NT. */
32 SYSTEM_INFO sysinfo_cache;
33 unsigned long syspage_mask = 0;
35 /* These are defined to get Emacs to compile, but are not used. */
36 int edata;
37 int etext;
39 /* The major and minor versions of NT. */
40 int nt_major_version;
41 int nt_minor_version;
43 /* Cache information describing the NT system for later use. */
44 void
45 cache_system_info (void)
47 union
49 struct info
51 char major;
52 char minor;
53 short platform;
54 } info;
55 DWORD data;
56 } version;
58 /* Cache the version of the operating system. */
59 version.data = GetVersion ();
60 nt_major_version = version.info.major;
61 nt_minor_version = version.info.minor;
63 /* Cache page size, allocation unit, processor type, etc. */
64 GetSystemInfo (&sysinfo_cache);
65 syspage_mask = sysinfo_cache.dwPageSize - 1;
68 /* Round ADDRESS up to be aligned with ALIGN. */
69 unsigned char *
70 round_to_next (unsigned char *address, unsigned long align)
72 unsigned long tmp;
74 tmp = (unsigned long) address;
75 tmp = (tmp + align - 1) / align;
77 return (unsigned char *) (tmp * align);
80 /* Info for keeping track of our heap. */
81 unsigned char *data_region_base = NULL;
82 unsigned char *data_region_end = NULL;
83 unsigned char *real_data_region_end = NULL;
84 unsigned long data_region_size = 0;
85 unsigned long reserved_heap_size = 0;
87 /* The start of the data segment. */
88 unsigned char *
89 get_data_start (void)
91 return data_region_base;
94 /* The end of the data segment. */
95 unsigned char *
96 get_data_end (void)
98 return data_region_end;
101 #ifndef WINDOWS95
102 static char *
103 allocate_heap (void)
105 unsigned long base = 0x00030000;
106 unsigned long end = 0x00D00000;
108 reserved_heap_size = end - base;
110 return VirtualAlloc ((void *) base,
111 get_reserved_heap_size (),
112 MEM_RESERVE,
113 PAGE_NOACCESS);
115 #else
116 static char *
117 allocate_heap (void)
119 unsigned long start = 0x400000;
120 unsigned long stop = 0xD00000;
121 unsigned long increment = 0x100000;
122 char *ptr, *begin = NULL, *end = NULL;
123 int i;
125 for (i = start; i < stop; i += increment)
127 ptr = VirtualAlloc ((void *) i, increment, MEM_RESERVE, PAGE_NOACCESS);
128 if (ptr)
129 begin = begin ? begin : ptr;
130 else if (begin)
132 end = ptr;
133 break;
137 if (begin && !end)
138 end = (char *) i;
140 if (!begin)
141 /* We couldn't allocate any memory for the heap. Exit. */
142 exit (-2);
144 reserved_heap_size = end - begin;
145 return begin;
147 #endif
150 /* Emulate Unix sbrk. */
151 void *
152 sbrk (unsigned long increment)
154 void *result;
155 long size = (long) increment;
157 /* Allocate our heap if we haven't done so already. */
158 if (!data_region_base)
160 data_region_base = allocate_heap ();
161 if (!data_region_base)
162 return NULL;
164 /* Ensure that the addresses don't use the upper 8 bits since
165 the Lisp type goes there (yucko). */
166 if (((unsigned long) data_region_base & 0xFF000000) != 0)
168 printf ("Error: The heap was allocated in upper memory.\n");
169 exit (1);
172 data_region_end = data_region_base;
173 real_data_region_end = data_region_end;
174 data_region_size = get_reserved_heap_size ();
177 result = data_region_end;
179 /* If size is negative, shrink the heap by decommitting pages. */
180 if (size < 0)
182 int new_size;
183 unsigned char *new_data_region_end;
185 size = -size;
187 /* Sanity checks. */
188 if ((data_region_end - size) < data_region_base)
189 return NULL;
191 /* We can only decommit full pages, so allow for
192 partial deallocation [cga]. */
193 new_data_region_end = (data_region_end - size);
194 new_data_region_end = (unsigned char *)
195 ((long) (new_data_region_end + syspage_mask) & ~syspage_mask);
196 new_size = real_data_region_end - new_data_region_end;
197 real_data_region_end = new_data_region_end;
198 if (new_size > 0)
200 /* Decommit size bytes from the end of the heap. */
201 if (!VirtualFree (real_data_region_end, new_size, MEM_DECOMMIT))
202 return NULL;
205 data_region_end -= size;
207 /* If size is positive, grow the heap by committing reserved pages. */
208 else if (size > 0)
210 /* Sanity checks. */
211 if ((data_region_end + size) >
212 (data_region_base + get_reserved_heap_size ()))
213 return NULL;
215 /* Commit more of our heap. */
216 if (VirtualAlloc (data_region_end, size, MEM_COMMIT,
217 PAGE_READWRITE) == NULL)
218 return NULL;
219 data_region_end += size;
221 /* We really only commit full pages, so record where
222 the real end of committed memory is [cga]. */
223 real_data_region_end = (unsigned char *)
224 ((long) (data_region_end + syspage_mask) & ~syspage_mask);
227 return result;
230 /* Recreate the heap from the data that was dumped to the executable.
231 EXECUTABLE_PATH tells us where to find the executable. */
232 void
233 recreate_heap (char *executable_path)
235 unsigned char *tmp;
237 /* First reserve the upper part of our heap. (We reserve first
238 because there have been problems in the past where doing the
239 mapping first has loaded DLLs into the VA space of our heap.) */
240 tmp = VirtualAlloc ((void *) get_heap_end (),
241 get_reserved_heap_size () - get_committed_heap_size (),
242 MEM_RESERVE,
243 PAGE_NOACCESS);
244 if (!tmp)
245 exit (1);
247 /* We read in the data for the .bss section from the executable
248 first and map in the heap from the executable second to prevent
249 any funny interactions between file I/O and file mapping. */
250 read_in_bss (executable_path);
251 map_in_heap (executable_path);
254 /* Round the heap up to the given alignment. */
255 void
256 round_heap (unsigned long align)
258 unsigned long needs_to_be;
259 unsigned long need_to_alloc;
261 needs_to_be = (unsigned long) round_to_next (get_heap_end (), align);
262 need_to_alloc = needs_to_be - (unsigned long) get_heap_end ();
264 if (need_to_alloc)
265 sbrk (need_to_alloc);