]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/cygheap.cc
1 /* cygheap.cc: Cygwin heap manager.
3 Copyright 2000 Cygnus Solutions.
5 This file is part of Cygwin.
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
21 void NO_COPY
*cygheap
= NULL
;
22 void NO_COPY
*cygheap_max
= NULL
;
24 static NO_COPY muto
*cygheap_protect
= NULL
;
26 extern "C" void __stdcall
29 cygheap_protect
= new_muto (FALSE
, "cygheap_protect");
35 cygheap
= VirtualAlloc (NULL
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
);
37 api_fatal ("Couldn't reserve space for cygwin's heap, %E");
38 cygheap_max
= (((char **) cygheap
) + 1);
41 #define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
43 static void *__stdcall
57 lastheap
= cygheap_max
;
58 (char *) cygheap_max
+= sbs
;
59 void *heapalign
= (void *) pagetrunc (lastheap
);
62 needalloc
= sbs
&& ((heapalign
== lastheap
) || heapalign
!= pagetrunc (cygheap_max
));
63 if (needalloc
&& !VirtualAlloc (lastheap
, (DWORD
) sbs
, MEM_COMMIT
, PAGE_READWRITE
))
64 api_fatal ("couldn't commit memory for cygwin heap, %E");
69 /* Copyright (C) 1997, 2000 DJ Delorie */
72 char *buckets
[NBUCKETS
] = {0};
73 int bucket2size
[NBUCKETS
] = {0};
76 size2bucket (int size
)
84 size
= (size
+ 3) & ~3;
86 for (i
= 0; i
< 5; i
++)
88 if (bucket2size
[rv
& bit
] >= size
)
99 for (b
= 0; b
< NBUCKETS
; b
++)
100 bucket2size
[b
] = (1 << b
);
103 struct _cmalloc_entry
110 struct _cmalloc_entry
*prev
;
115 #define N0 ((_cmalloc_entry *) NULL)
116 #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
117 #define cygheap_chain ((_cmalloc_entry **)cygheap)
119 static void *__stdcall
125 if (bucket2size
[0] == 0)
128 b
= size2bucket (size
);
129 cygheap_protect
->acquire ();
132 rvc
= (_cmalloc_entry
*) buckets
[b
];
133 buckets
[b
] = rvc
->ptr
;
138 size
= bucket2size
[b
] + sizeof (_cmalloc_entry
);
139 rvc
= (_cmalloc_entry
*) _csbrk (size
);
142 rvc
->prev
= *cygheap_chain
;
143 *cygheap_chain
= rvc
;
145 cygheap_protect
->release ();
149 static void __stdcall
152 cygheap_protect
->acquire ();
153 _cmalloc_entry
*rvc
= to_cmalloc (ptr
);
155 rvc
->ptr
= buckets
[b
];
156 buckets
[b
] = (char *) rvc
;
157 cygheap_protect
->release ();
160 static void *__stdcall
161 _crealloc (void *ptr
, int size
)
165 newptr
= _cmalloc (size
);
168 int oldsize
= bucket2size
[to_cmalloc (ptr
)->b
];
171 newptr
= _cmalloc (size
);
172 memcpy (newptr
, ptr
, oldsize
);
178 /* End Copyright (C) 1997 DJ Delorie */
180 #define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
185 struct cygheap_entry
*next
;
189 #define N ((cygheap_entry *) NULL)
190 #define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
192 /* Called by fork or spawn to reallocate cygwin heap */
193 extern "C" void __stdcall
194 cygheap_fixup_in_child (HANDLE parent
, bool execed
)
197 n
= (DWORD
) cygheap_max
- (DWORD
) cygheap
;
199 /* Reserve cygwin heap in same spot as parent */
200 if (!VirtualAlloc (cygheap
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
))
201 api_fatal ("Couldn't reserve space for cygwin's heap in child, %E");
203 /* Allocate same amount of memory as parent */
204 if (!VirtualAlloc (cygheap
, n
, MEM_COMMIT
, PAGE_READWRITE
))
205 api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
208 /* Copy memory from the parent */
210 n
= (DWORD
) pagetrunc (n
+ 4095);
211 if (!ReadProcessMemory (parent
, cygheap
, cygheap
, n
, &m
) ||
213 api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
217 return; /* Forked. Nothing extra to do. */
219 /* Walk the allocated memory chain looking for orphaned memory from
221 for (_cmalloc_entry
*rvc
= *cygheap_chain
; rvc
; rvc
= rvc
->prev
)
223 cygheap_entry
*ce
= (cygheap_entry
*) rvc
->data
;
224 if (rvc
->b
>= NBUCKETS
|| ce
->type
<= HEAP_1_START
)
226 else if (ce
->type
< HEAP_1_MAX
)
227 ce
->type
+= HEAP_1_MAX
; /* Mark for freeing after next exec */
229 _cfree (ce
); /* Marked by parent for freeing in child */
233 static void *__stdcall
234 creturn (cygheap_types x
, cygheap_entry
* c
, int len
)
242 if (cygheap_max
< ((char *) c
+ len
))
243 cygheap_max
= (char *) c
+ len
;
245 return (void *) c
->data
;
248 extern "C" void *__stdcall
249 cmalloc (cygheap_types x
, DWORD n
)
253 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
));
255 system_printf ("cmalloc returned NULL");
256 return creturn (x
, c
, n
);
259 extern "C" void *__stdcall
260 crealloc (void *s
, DWORD n
)
264 return cmalloc (HEAP_STR
, n
); // kludge
266 assert (!inheap (s
));
267 cygheap_entry
*c
= tocygheap (s
);
268 cygheap_types t
= (cygheap_types
) c
->type
;
269 c
= (cygheap_entry
*) _crealloc (c
, sizeof_cygheap (n
));
271 system_printf ("crealloc returned NULL");
272 return creturn (t
, c
, n
);
275 extern "C" void __stdcall
279 assert (!inheap (s
));
280 (void) _cfree (tocygheap (s
));
284 extern "C" void *__stdcall
285 ccalloc (cygheap_types x
, DWORD n
, DWORD size
)
289 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
* size
));
291 memset (c
->data
, 0, size
);
293 system_printf ("ccalloc returned NULL");
294 return creturn (x
, c
, n
);
297 extern "C" char *__stdcall
298 cstrdup (const char *s
)
301 char *p
= (char *) cmalloc (HEAP_STR
, strlen (s
) + 1);
309 extern "C" char *__stdcall
310 cstrdup1 (const char *s
)
313 char *p
= (char *) cmalloc (HEAP_1_STR
, strlen (s
) + 1);
This page took 0.051693 seconds and 6 git commands to generate.