]>
sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/heap.cc
1 /* heap.cc: Cygwin heap manager.
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 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
17 #include "shared_info.h"
26 static unsigned page_const
;
28 extern "C" size_t getpagesize ();
30 /* Initialize the heap at process start up. */
35 /* If we're the forkee, we must allocate the heap at exactly the same place
36 as our parent. If not, we don't care where it ends up. */
38 page_const
= system_info
.dwPageSize
;
39 if (cygheap
->heapbase
)
41 DWORD chunk
= cygwin_shared
->heap_chunk_size (); /* allocation chunk */
42 /* total size commited in parent */
43 DWORD allocsize
= (char *) cygheap
->heaptop
- (char *) cygheap
->heapbase
;
44 /* round up by chunk size */
45 DWORD reserve_size
= chunk
* ((allocsize
+ (chunk
- 1)) / chunk
);
47 /* Loop until we've managed to reserve an adequate amount of memory. */
51 p
= (char *) VirtualAlloc (cygheap
->heapbase
, reserve_size
,
52 MEM_RESERVE
, PAGE_READWRITE
);
55 if ((reserve_size
-= page_const
) <= allocsize
)
59 api_fatal ("1. unable to allocate heap %p, heap_chunk_size %d, pid %d, %E",
60 cygheap
->heapbase
, cygwin_shared
->heap_chunk_size (), myself
->pid
);
61 if (p
!= cygheap
->heapbase
)
62 api_fatal ("heap allocated but not at %p", cygheap
->heapbase
);
63 if (! VirtualAlloc (cygheap
->heapbase
, allocsize
, MEM_COMMIT
, PAGE_READWRITE
))
64 api_fatal ("MEM_COMMIT failed, %E");
68 /* Initialize page mask and default heap size. Preallocate a heap
69 * to assure contiguous memory. */
70 cygheap
->heapptr
= cygheap
->heaptop
= cygheap
->heapbase
=
71 VirtualAlloc (NULL
, cygwin_shared
->heap_chunk_size (), MEM_RESERVE
,
73 if (cygheap
->heapbase
== NULL
)
74 api_fatal ("2. unable to allocate heap, heap_chunk_size %d, %E",
75 cygwin_shared
->heap_chunk_size ());
78 debug_printf ("heap base %p, heap top %p", cygheap
->heapbase
,
84 #define pround(n) (((size_t)(n) + page_const) & ~page_const)
86 /* FIXME: This function no longer handles "split heaps". */
91 sigframe
thisframe (mainthread
);
92 char *newtop
, *newbrk
;
93 unsigned commitbytes
, newbrksize
;
96 return cygheap
->heapptr
; /* Just wanted to find current cygheap->heapptr address */
98 newbrk
= (char *) cygheap
->heapptr
+ n
; /* Where new cygheap->heapptr will be */
99 newtop
= (char *) pround (newbrk
); /* Actual top of allocated memory -
102 if (newtop
== cygheap
->heaptop
)
106 { /* Freeing memory */
107 assert (newtop
< cygheap
->heaptop
);
108 n
= (char *) cygheap
->heaptop
- newtop
;
109 if (VirtualFree (newtop
, n
, MEM_DECOMMIT
)) /* Give it back to OS */
110 goto good
; /* Didn't take */
115 assert (newtop
> cygheap
->heaptop
);
117 /* Need to grab more pages from the OS. If this fails it may be because
118 * we have used up previously reserved memory. Or, we're just plumb out
120 commitbytes
= pround (newtop
- (char *) cygheap
->heaptop
);
121 if (VirtualAlloc (cygheap
->heaptop
, commitbytes
, MEM_COMMIT
, PAGE_READWRITE
) != NULL
)
124 /* Couldn't allocate memory. Maybe we can reserve some more.
125 Reserve either the maximum of the standard cygwin_shared->heap_chunk_size () or the requested
126 amount. Then attempt to actually allocate it. */
128 if ((newbrksize
= cygwin_shared
->heap_chunk_size ()) < commitbytes
)
129 newbrksize
= commitbytes
;
131 if ((VirtualAlloc (cygheap
->heaptop
, newbrksize
, MEM_RESERVE
, PAGE_NOACCESS
) != NULL
) &&
132 (VirtualAlloc (cygheap
->heaptop
, commitbytes
, MEM_COMMIT
, PAGE_READWRITE
) != NULL
))
140 void *oldbrk
= cygheap
->heapptr
;
141 cygheap
->heapptr
= newbrk
;
142 cygheap
->heaptop
= newtop
;
This page took 0.044643 seconds and 5 git commands to generate.