]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/cygheap.cc
1 /* cygheap.cc: Cygwin heap manager.
3 Copyright 2000, 2001 Red Hat, Inc.
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 "child_info.h"
24 #include "shared_info.h"
26 init_cygheap NO_COPY
*cygheap
;
27 void NO_COPY
*cygheap_max
= NULL
;
29 static NO_COPY muto
*cygheap_protect
= NULL
;
34 struct cygheap_entry
*next
;
39 char *buckets
[NBUCKETS
] = {0};
41 #define N0 ((_cmalloc_entry *) NULL)
42 #define to_cmalloc(s) ((_cmalloc_entry *) (((char *) (s)) - (int) (N0->data)))
44 #define CFMAP_OPTIONS (SEC_RESERVE | PAGE_READWRITE)
45 #define MVMAP_OPTIONS (FILE_MAP_WRITE)
48 static void __stdcall
_cfree (void *ptr
) __attribute__((regparm(1)));
56 cygheap
= (init_cygheap
*) VirtualAlloc (NULL
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
);
58 api_fatal ("Couldn't reserve space for cygwin's heap, %E");
63 h
= CreateFileMapping (INVALID_HANDLE_VALUE
, &sec_none
, PAGE_READWRITE
,
64 0, CYGHEAPSIZE
, NULL
);
66 api_fatal ("CreateFileMapping failed, %E");
67 cygheap
= (init_cygheap
*) MapViewOfFile (h
, FILE_MAP_WRITE
, 0, 0, 0);
69 api_fatal ("Couldn't allocate shared memory for cygwin heap, %E");
72 cygheap_max
= cygheap
+ 1;
76 cygheap_setup_for_child (child_info
*ci
)
79 cygheap_protect
->acquire ();
80 unsigned n
= (char *) cygheap_max
- (char *) cygheap
;
81 ci
->cygheap_h
= CreateFileMapping (INVALID_HANDLE_VALUE
, &sec_none
,
82 CFMAP_OPTIONS
, 0, CYGHEAPSIZE
, NULL
);
83 newcygheap
= MapViewOfFileEx (ci
->cygheap_h
, MVMAP_OPTIONS
, 0, 0, 0, NULL
);
84 if (!VirtualAlloc (newcygheap
, n
, MEM_COMMIT
, PAGE_READWRITE
))
85 api_fatal ("couldn't allocate new cygwin heap for child, %E");
86 memcpy (newcygheap
, cygheap
, n
);
87 UnmapViewOfFile (newcygheap
);
88 ci
->cygheap
= cygheap
;
89 ci
->cygheap_max
= cygheap_max
;
90 ProtectHandle1 (ci
->cygheap_h
, passed_cygheap_h
);
91 cygheap_protect
->release ();
96 cygheap_setup_for_child_cleanup (child_info
*ci
)
98 ForceCloseHandle1 (ci
->cygheap_h
, passed_cygheap_h
);
101 /* Called by fork or spawn to reallocate cygwin heap */
103 cygheap_fixup_in_child (child_info
*ci
, bool execed
)
105 cygheap
= ci
->cygheap
;
106 cygheap_max
= ci
->cygheap_max
;
107 void *addr
= iswinnt
? cygheap
: NULL
;
109 newaddr
= MapViewOfFileEx (ci
->cygheap_h
, MVMAP_OPTIONS
, 0, 0, 0, addr
);
110 if (!iswinnt
|| newaddr
!= addr
)
112 DWORD n
= (DWORD
) cygheap_max
- (DWORD
) cygheap
;
113 /* Reserve cygwin heap in same spot as parent */
114 if (!VirtualAlloc (cygheap
, CYGHEAPSIZE
, MEM_RESERVE
, PAGE_NOACCESS
))
115 api_fatal ("Couldn't reserve space for cygwin's heap (%p) in child, cygheap, %E", cygheap
);
117 /* Allocate same amount of memory as parent */
118 if (!VirtualAlloc (cygheap
, n
, MEM_COMMIT
, PAGE_READWRITE
))
119 api_fatal ("Couldn't allocate space for child's heap %p, size %d, %E",
121 memcpy (cygheap
, newaddr
, n
);
122 UnmapViewOfFile (newaddr
);
125 ForceCloseHandle1 (ci
->cygheap_h
, passed_cygheap_h
);
131 /* Walk the allocated memory chain looking for orphaned memory from
133 for (_cmalloc_entry
*rvc
= cygheap
->chain
; rvc
; rvc
= rvc
->prev
)
135 cygheap_entry
*ce
= (cygheap_entry
*) rvc
->data
;
136 if (rvc
->b
>= NBUCKETS
|| ce
->type
<= HEAP_1_START
)
138 else if (ce
->type
< HEAP_1_MAX
)
139 ce
->type
+= HEAP_1_MAX
; /* Mark for freeing after next exec */
141 _cfree (ce
); /* Marked by parent for freeing in child */
146 #define pagetrunc(x) ((void *) (((DWORD) (x)) & ~(4096 - 1)))
148 static void *__stdcall
162 lastheap
= cygheap_max
;
163 (char *) cygheap_max
+= sbs
;
164 void *heapalign
= (void *) pagetrunc (lastheap
);
167 needalloc
= sbs
&& ((heapalign
== lastheap
) || heapalign
!= pagetrunc (cygheap_max
));
168 if (needalloc
&& !VirtualAlloc (lastheap
, (DWORD
) sbs
?: 1, MEM_COMMIT
, PAGE_READWRITE
))
169 api_fatal ("couldn't commit memory for cygwin heap, %E");
174 extern "C" void __stdcall
177 cygheap_protect
= new_muto (FALSE
, "cygheap_protect");
180 cygheap
->fdtab
.init ();
183 /* Copyright (C) 1997, 2000 DJ Delorie */
185 static void *_cmalloc (int size
) __attribute ((regparm(1)));
186 static void *__stdcall
_crealloc (void *ptr
, int size
) __attribute ((regparm(2)));
188 static void *__stdcall
194 /* Calculate "bit bucket" and size as a power of two. */
195 for (b
= 3, sz
= 8; sz
&& sz
< (size
+ sizeof (_cmalloc_entry
));
199 cygheap_protect
->acquire ();
202 rvc
= (_cmalloc_entry
*) buckets
[b
];
203 buckets
[b
] = rvc
->ptr
;
208 size
= sz
+ sizeof (_cmalloc_entry
);
209 rvc
= (_cmalloc_entry
*) _csbrk (size
);
212 rvc
->prev
= cygheap
->chain
;
213 cygheap
->chain
= rvc
;
215 cygheap_protect
->release ();
219 static void __stdcall
222 cygheap_protect
->acquire ();
223 _cmalloc_entry
*rvc
= to_cmalloc (ptr
);
225 rvc
->ptr
= buckets
[b
];
226 buckets
[b
] = (char *) rvc
;
227 cygheap_protect
->release ();
230 static void *__stdcall
_crealloc (void *ptr
, int size
) __attribute__((regparm(2)));
231 static void *__stdcall
232 _crealloc (void *ptr
, int size
)
236 newptr
= _cmalloc (size
);
239 int oldsize
= 1 << to_cmalloc (ptr
)->b
;
242 newptr
= _cmalloc (size
);
243 memcpy (newptr
, ptr
, oldsize
);
249 /* End Copyright (C) 1997 DJ Delorie */
251 #define sizeof_cygheap(n) ((n) + sizeof(cygheap_entry))
253 #define N ((cygheap_entry *) NULL)
254 #define tocygheap(s) ((cygheap_entry *) (((char *) (s)) - (int) (N->data)))
257 creturn (cygheap_types x
, cygheap_entry
* c
, int len
)
265 char *cend
= ((char *) c
+ sizeof (*c
) + len
);
266 if (cygheap_max
< cend
)
269 return (void *) c
->data
;
272 extern "C" void *__stdcall
273 cmalloc (cygheap_types x
, DWORD n
)
277 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
));
279 system_printf ("cmalloc returned NULL");
280 return creturn (x
, c
, n
);
283 extern "C" void *__stdcall
284 crealloc (void *s
, DWORD n
)
288 return cmalloc (HEAP_STR
, n
); // kludge
290 assert (!inheap (s
));
291 cygheap_entry
*c
= tocygheap (s
);
292 cygheap_types t
= (cygheap_types
) c
->type
;
293 c
= (cygheap_entry
*) _crealloc (c
, sizeof_cygheap (n
));
295 system_printf ("crealloc returned NULL");
296 return creturn (t
, c
, n
);
299 extern "C" void __stdcall
303 assert (!inheap (s
));
304 (void) _cfree (tocygheap (s
));
308 extern "C" void *__stdcall
309 ccalloc (cygheap_types x
, DWORD n
, DWORD size
)
313 c
= (cygheap_entry
*) _cmalloc (sizeof_cygheap (n
* size
));
315 memset (c
->data
, 0, n
* size
);
317 system_printf ("ccalloc returned NULL");
318 return creturn (x
, c
, n
);
321 extern "C" char *__stdcall
322 cstrdup (const char *s
)
325 char *p
= (char *) cmalloc (HEAP_STR
, strlen (s
) + 1);
333 extern "C" char *__stdcall
334 cstrdup1 (const char *s
)
337 char *p
= (char *) cmalloc (HEAP_1_STR
, strlen (s
) + 1);
346 cygheap_root::set (const char *posix
, const char *native
)
348 if (*posix
== '/' && posix
[1] == '\0')
358 m
= (struct cygheap_root_mount_info
*) ccalloc (HEAP_MOUNT
, 1, sizeof (*m
));
359 strcpy (m
->posix_path
, posix
);
360 m
->posix_pathlen
= strlen (posix
);
361 if (m
->posix_pathlen
>= 1 && m
->posix_path
[m
->posix_pathlen
- 1] == '/')
362 m
->posix_path
[--m
->posix_pathlen
] = '\0';
364 strcpy (m
->native_path
, native
);
365 m
->native_pathlen
= strlen (native
);
366 if (m
->native_pathlen
>= 1 && m
->native_path
[m
->native_pathlen
- 1] == '\\')
367 m
->native_path
[--m
->native_pathlen
] = '\0';
370 cygheap_user::~cygheap_user ()
385 cygheap_user::set_name (const char *new_name
)
389 pname
= cstrdup (new_name
? new_name
: "");
393 cygheap_user::set_logsrv (const char *new_logsrv
)
397 plogsrv
= (new_logsrv
&& *new_logsrv
) ? cstrdup (new_logsrv
) : NULL
;
401 cygheap_user::set_domain (const char *new_domain
)
405 pdomain
= (new_domain
&& *new_domain
) ? cstrdup (new_domain
) : NULL
;
409 cygheap_user::set_sid (PSID new_sid
)
421 psid
= cmalloc (HEAP_STR
, MAX_SID_LEN
);
422 return CopySid (MAX_SID_LEN
, psid
, new_sid
);
This page took 0.058709 seconds and 6 git commands to generate.