]>
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
20 #include "shared_info.h"
22 init_cygheap NO_COPY
*cygheap
;
23 void NO_COPY
*cygheap_max
= NULL
;
25 static NO_COPY muto
*cygheap_protect
= NULL
;
30 cygheap
= (init_cygheap
*) VirtualAlloc (NULL
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
);
32 api_fatal ("Couldn't reserve space for cygwin's heap, %E");
33 cygheap_max
= cygheap
+ 1;
36 #define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
38 static void *__stdcall
52 lastheap
= cygheap_max
;
53 (char *) cygheap_max
+= sbs
;
54 void *heapalign
= (void *) pagetrunc (lastheap
);
57 needalloc
= sbs
&& ((heapalign
== lastheap
) || heapalign
!= pagetrunc (cygheap_max
));
58 if (needalloc
&& !VirtualAlloc (lastheap
, (DWORD
) sbs
?: 1, MEM_COMMIT
, PAGE_READWRITE
))
59 api_fatal ("couldn't commit memory for cygwin heap, %E");
64 extern "C" void __stdcall
67 cygheap_protect
= new_muto (FALSE
, "cygheap_protect");
71 /* Copyright (C) 1997, 2000 DJ Delorie */
74 char *buckets
[NBUCKETS
] = {0};
76 #define N0 ((_cmalloc_entry *) NULL)
77 #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
79 static void *_cmalloc (int size
) __attribute ((regparm(1)));
80 static void *__stdcall
_crealloc (void *ptr
, int size
) __attribute ((regparm(2)));
82 static void *__stdcall
88 /* Calculate "bit bucket" and size as a power of two. */
89 for (b
= 3, sz
= 8; sz
&& sz
< (size
+ 4); b
++, sz
<<= 1)
92 cygheap_protect
->acquire ();
95 rvc
= (_cmalloc_entry
*) buckets
[b
];
96 buckets
[b
] = rvc
->ptr
;
101 size
= sz
+ sizeof (_cmalloc_entry
);
102 rvc
= (_cmalloc_entry
*) _csbrk (size
);
105 rvc
->prev
= cygheap
->chain
;
106 cygheap
->chain
= rvc
;
108 cygheap_protect
->release ();
112 static void __stdcall
115 cygheap_protect
->acquire ();
116 _cmalloc_entry
*rvc
= to_cmalloc (ptr
);
118 rvc
->ptr
= buckets
[b
];
119 buckets
[b
] = (char *) rvc
;
120 cygheap_protect
->release ();
123 static void *__stdcall
124 _crealloc (void *ptr
, int size
)
128 newptr
= _cmalloc (size
);
131 int oldsize
= 1 << to_cmalloc (ptr
)->b
;
134 newptr
= _cmalloc (size
);
135 memcpy (newptr
, ptr
, oldsize
);
141 /* End Copyright (C) 1997 DJ Delorie */
143 #define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
148 struct cygheap_entry
*next
;
152 #define N ((cygheap_entry *) NULL)
153 #define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
155 /* Called by fork or spawn to reallocate cygwin heap */
156 extern "C" void __stdcall
157 cygheap_fixup_in_child (HANDLE parent
, bool execed
)
160 n
= (DWORD
) cygheap_max
- (DWORD
) cygheap
;
162 /* Reserve cygwin heap in same spot as parent */
163 if (!VirtualAlloc (cygheap
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
))
164 api_fatal ("Couldn't reserve space for cygwin's heap (%p) in child, cygheap, %E", cygheap
);
166 /* Allocate same amount of memory as parent */
167 if (!VirtualAlloc (cygheap
, n
, MEM_COMMIT
, PAGE_READWRITE
))
168 api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
171 /* Copy memory from the parent */
173 if (!ReadProcessMemory (parent
, cygheap
, cygheap
, n
, &m
) || m
!= n
)
174 api_fatal ("Couldn't read parent's cygwin heap %d bytes != %d, %E",
181 /* Walk the allocated memory chain looking for orphaned memory from
183 for (_cmalloc_entry
*rvc
= cygheap
->chain
; rvc
; rvc
= rvc
->prev
)
185 cygheap_entry
*ce
= (cygheap_entry
*) rvc
->data
;
186 if (rvc
->b
>= NBUCKETS
|| ce
->type
<= HEAP_1_START
)
188 else if (ce
->type
< HEAP_1_MAX
)
189 ce
->type
+= HEAP_1_MAX
; /* Mark for freeing after next exec */
191 _cfree (ce
); /* Marked by parent for freeing in child */
197 creturn (cygheap_types x
, cygheap_entry
* c
, int len
)
205 if (cygheap_max
< ((char *) c
+ len
))
206 cygheap_max
= (char *) c
+ len
;
208 return (void *) c
->data
;
211 extern "C" void *__stdcall
212 cmalloc (cygheap_types x
, DWORD n
)
216 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
));
218 system_printf ("cmalloc returned NULL");
219 return creturn (x
, c
, n
);
222 extern "C" void *__stdcall
223 crealloc (void *s
, DWORD n
)
227 return cmalloc (HEAP_STR
, n
); // kludge
229 assert (!inheap (s
));
230 cygheap_entry
*c
= tocygheap (s
);
231 cygheap_types t
= (cygheap_types
) c
->type
;
232 c
= (cygheap_entry
*) _crealloc (c
, sizeof_cygheap (n
));
234 system_printf ("crealloc returned NULL");
235 return creturn (t
, c
, n
);
238 extern "C" void __stdcall
242 assert (!inheap (s
));
243 (void) _cfree (tocygheap (s
));
247 extern "C" void *__stdcall
248 ccalloc (cygheap_types x
, DWORD n
, DWORD size
)
252 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
* size
));
254 memset (c
->data
, 0, n
* size
);
256 system_printf ("ccalloc returned NULL");
257 return creturn (x
, c
, n
);
260 extern "C" char *__stdcall
261 cstrdup (const char *s
)
264 char *p
= (char *) cmalloc (HEAP_STR
, strlen (s
) + 1);
272 extern "C" char *__stdcall
273 cstrdup1 (const char *s
)
276 char *p
= (char *) cmalloc (HEAP_1_STR
, strlen (s
) + 1);
284 cygheap_root::cygheap_root (cygheap_root
&nroot
)
286 rootlen
= nroot
.rootlen
;
287 root
= nroot
.root
? cstrdup (nroot
.root
) : NULL
;
290 cygheap_root::~cygheap_root ()
297 cygheap_root::operator =(const char *new_root
)
305 if (new_root
&& *new_root
)
307 root
= cstrdup (new_root
);
308 rootlen
= strlen (root
);
309 if (rootlen
>= 1 && root
[rootlen
- 1] == '/')
310 root
[--rootlen
] = '\0';
320 cygheap_user::~cygheap_user ()
335 cygheap_user::set_name (const char *new_name
)
339 pname
= cstrdup (new_name
? new_name
: "");
343 cygheap_user::set_logsrv (const char *new_logsrv
)
347 plogsrv
= (new_logsrv
&& *new_logsrv
) ? cstrdup (new_logsrv
) : NULL
;
351 cygheap_user::set_domain (const char *new_domain
)
355 pdomain
= (new_domain
&& *new_domain
) ? cstrdup (new_domain
) : NULL
;
359 cygheap_user::set_sid (PSID new_sid
)
371 psid
= cmalloc (HEAP_STR
, MAX_SID_LEN
);
372 return CopySid (MAX_SID_LEN
, psid
, new_sid
);
This page took 0.054407 seconds and 6 git commands to generate.