]>
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};
81 struct _cmalloc_entry
*prev
;
86 #define N0 ((_cmalloc_entry *) NULL)
87 #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
88 #define cygheap_chain ((_cmalloc_entry **)cygheap)
90 static void *_cmalloc (int size
) __attribute ((regparm(1)));
91 static void *__stdcall
_crealloc (void *ptr
, int size
) __attribute ((regparm(2)));
93 static void *__stdcall
99 /* Calculate "bit bucket" and size as a power of two. */
100 for (b
= 3, sz
= 8; sz
&& sz
< (size
+ 4); b
++, sz
<<= 1)
103 cygheap_protect
->acquire ();
106 rvc
= (_cmalloc_entry
*) buckets
[b
];
107 buckets
[b
] = rvc
->ptr
;
112 size
= sz
+ sizeof (_cmalloc_entry
);
113 rvc
= (_cmalloc_entry
*) _csbrk (size
);
116 rvc
->prev
= *cygheap_chain
;
117 *cygheap_chain
= rvc
;
119 cygheap_protect
->release ();
123 static void __stdcall
126 cygheap_protect
->acquire ();
127 _cmalloc_entry
*rvc
= to_cmalloc (ptr
);
129 rvc
->ptr
= buckets
[b
];
130 buckets
[b
] = (char *) rvc
;
131 cygheap_protect
->release ();
134 static void *__stdcall
135 _crealloc (void *ptr
, int size
)
139 newptr
= _cmalloc (size
);
142 int oldsize
= 1 << to_cmalloc (ptr
)->b
;
145 newptr
= _cmalloc (size
);
146 memcpy (newptr
, ptr
, oldsize
);
152 /* End Copyright (C) 1997 DJ Delorie */
154 #define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
159 struct cygheap_entry
*next
;
163 #define N ((cygheap_entry *) NULL)
164 #define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
166 /* Called by fork or spawn to reallocate cygwin heap */
167 extern "C" void __stdcall
168 cygheap_fixup_in_child (HANDLE parent
, bool execed
)
171 n
= (DWORD
) cygheap_max
- (DWORD
) cygheap
;
173 /* Reserve cygwin heap in same spot as parent */
174 if (!VirtualAlloc (cygheap
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
))
175 api_fatal ("Couldn't reserve space for cygwin's heap in child, %E");
177 /* Allocate same amount of memory as parent */
178 if (!VirtualAlloc (cygheap
, n
, MEM_COMMIT
, PAGE_READWRITE
))
179 api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
182 /* Copy memory from the parent */
184 if (!ReadProcessMemory (parent
, cygheap
, cygheap
, n
, &m
) || m
!= n
)
185 api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
189 return; /* Forked. Nothing extra to do. */
191 /* Walk the allocated memory chain looking for orphaned memory from
193 for (_cmalloc_entry
*rvc
= *cygheap_chain
; rvc
; rvc
= rvc
->prev
)
195 cygheap_entry
*ce
= (cygheap_entry
*) rvc
->data
;
196 if (rvc
->b
>= NBUCKETS
|| ce
->type
<= HEAP_1_START
)
198 else if (ce
->type
< HEAP_1_MAX
)
199 ce
->type
+= HEAP_1_MAX
; /* Mark for freeing after next exec */
201 _cfree (ce
); /* Marked by parent for freeing in child */
206 creturn (cygheap_types x
, cygheap_entry
* c
, int len
)
214 if (cygheap_max
< ((char *) c
+ len
))
215 cygheap_max
= (char *) c
+ len
;
217 return (void *) c
->data
;
220 extern "C" void *__stdcall
221 cmalloc (cygheap_types x
, DWORD n
)
225 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
));
227 system_printf ("cmalloc returned NULL");
228 return creturn (x
, c
, n
);
231 extern "C" void *__stdcall
232 crealloc (void *s
, DWORD n
)
236 return cmalloc (HEAP_STR
, n
); // kludge
238 assert (!inheap (s
));
239 cygheap_entry
*c
= tocygheap (s
);
240 cygheap_types t
= (cygheap_types
) c
->type
;
241 c
= (cygheap_entry
*) _crealloc (c
, sizeof_cygheap (n
));
243 system_printf ("crealloc returned NULL");
244 return creturn (t
, c
, n
);
247 extern "C" void __stdcall
251 assert (!inheap (s
));
252 (void) _cfree (tocygheap (s
));
256 extern "C" void *__stdcall
257 ccalloc (cygheap_types x
, DWORD n
, DWORD size
)
261 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
* size
));
263 memset (c
->data
, 0, n
* size
);
265 system_printf ("ccalloc returned NULL");
266 return creturn (x
, c
, n
);
269 extern "C" char *__stdcall
270 cstrdup (const char *s
)
273 char *p
= (char *) cmalloc (HEAP_STR
, strlen (s
) + 1);
281 extern "C" char *__stdcall
282 cstrdup1 (const char *s
)
285 char *p
= (char *) cmalloc (HEAP_1_STR
, strlen (s
) + 1);
This page took 0.051195 seconds and 6 git commands to generate.