1 /** Zone memory management. -*- Mode: ObjC -*-
2    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
3 
4    Written by: Yoo C. Chung <wacko@laplace.snu.ac.kr>
5    Date: January 1997
6 
7    This file is part of the GNUstep Base Library.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2 of the License, or (at your option) any later version.
13 
14    This library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Library General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with this library; if not, write to the Free
21    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22    Boston, MA 02111 USA.
23 
24     AutogsdocSource:	NSZone.m
25     AutogsdocSource:	NSPage.m
26 
27    */
28 
29 #ifndef __NSZone_h_GNUSTEP_BASE_INCLUDE
30 #define __NSZone_h_GNUSTEP_BASE_INCLUDE
31 #import	"../GNUstepBase/GSVersionMacros.h"
32 
33 /**
34  * Primary structure representing an <code>NSZone</code>.  Technically it
35  * consists of a set of function pointers for zone upkeep functions plus some
36  * other things-
37 <example>
38 {
39   // Functions for zone.
40   void *(*malloc)(struct _NSZone *zone, size_t size);
41   void *(*realloc)(struct _NSZone *zone, void *ptr, size_t size);
42   void (*free)(struct _NSZone *zone, void *ptr);
43   void (*recycle)(struct _NSZone *zone);
44   BOOL (*check)(struct _NSZone *zone);
45   BOOL (*lookup)(struct _NSZone *zone, void *ptr);
46 
47   // Zone statistics (not always maintained).
48   struct NSZoneStats (*stats)(struct _NSZone *zone);
49 
50   size_t gran;    // Zone granularity (passed in on initialization)
51   NSString *name; // Name of zone (default is 'nil')
52   NSZone *next;   // Pointer used for internal management of multiple zones.
53 }</example>
54  */
55 typedef struct _NSZone NSZone;
56 
57 #import	"NSObjCRuntime.h"
58 
59 @class NSString;
60 
61 #if	defined(__cplusplus)
62 extern "C" {
63 #endif
64 
65 struct _NSZone
66 {
67   /* Functions for zone. */
68   void *(*malloc)(struct _NSZone *zone, size_t size);
69   void *(*realloc)(struct _NSZone *zone, void *ptr, size_t size);
70   void (*free)(struct _NSZone *zone, void *ptr);
71   void (*recycle)(struct _NSZone *zone);
72   BOOL (*check)(struct _NSZone *zone);
73   BOOL (*lookup)(struct _NSZone *zone, void *ptr);
74   struct NSZoneStats (*stats)(struct _NSZone *zone);
75 
76   size_t gran; // Zone granularity
77   __unsafe_unretained NSString *name; // Name of zone (default is 'nil')
78   NSZone *next;
79 };
80 
81 /**
82  * Creates a new zone of start bytes, which will grow and shrink by
83  * granularity bytes.  If canFree is 0, memory in zone is allocated but
84  * never freed, meaning allocation will be very fast.  The whole zone can
85  * still be freed with NSRecycleZone(), and you should still call NSZoneFree
86  * on memory in the zone that is no longer needed, since a count of allocated
87  * pointers is kept and must reach zero before freeing the zone.<br />
88  * If Garbage Collection is enabled, this function does nothing other than
89  * log a warning and return the same value as the NSDefaultMallocZone()
90  * function.
91  */
92 GS_EXPORT NSZone*
93 NSCreateZone (NSUInteger start, NSUInteger gran, BOOL canFree);
94 
95 /** Returns the default zone for memory allocation.  Memory created in this
96  * zone is the same as memory allocates using the system malloc() function.
97  */
98 GS_EXPORT NSZone*
99 NSDefaultMallocZone (void);
100 
101 /**
102  * Searches and finds the zone ptr was allocated from.  The speed depends
103  * upon the number of zones and their size.<br />
104  * If Garbage Collection is enabled, this function always returns the
105  * same as the NSDefaultMallocZone() function.
106  */
107 GS_EXPORT NSZone*
108 NSZoneFromPointer (void *ptr);
109 
110 /**
111  * Allocates and returns memory for elems items of size bytes, in the
112  * given zone.  Returns NULL if allocation of size 0 requested.  Raises
113  * <code>NSMallocException</code> if not enough free memory in zone to
114  * allocate and no more can be obtained from system, unless using the
115  * default zone, in which case NULL is returned.<br />
116  * If Garbage Collection is enabled, this function always allocates
117  * non-scanned, non-collectable memory in the NSDefaultMallocZone() and
118  * the zone argument is ignored.
119  */
120 GS_EXPORT void*
121 NSZoneMalloc (NSZone *zone, NSUInteger size);
122 
123 /**
124  * Allocates and returns cleared memory for elems items of size bytes, in the
125  * given zone.  Returns NULL if allocation of size 0 requested.  Raises
126  * <code>NSMallocException</code> if not enough free memory in zone to
127  * allocate and no more can be obtained from system, unless using the
128  * default zone, in which case NULL is returned.<br />
129  * If Garbage Collection is enabled, this function always allocates
130  * non-scanned, non-collectable memory in the NSDefaultMallocZone() and
131  * the zone argument is ignored.
132  */
133 GS_EXPORT void*
134 NSZoneCalloc (NSZone *zone, NSUInteger elems, NSUInteger bytes);
135 
136 /**
137  * Reallocates the chunk of memory in zone pointed to by ptr to a new one of
138  * size bytes.  Existing contents in ptr are copied over.  Raises an
139  * <code>NSMallocException</code> if insufficient memory is available in the
140  * zone and no more memory can be obtained from the system, unless using the
141  * default zone, in which case NULL is returned.<br />
142  * If Garbage Collection is enabled, the zone argument is ignored.
143  */
144 GS_EXPORT void*
145 NSZoneRealloc (NSZone *zone, void *ptr, NSUInteger size);
146 
147 /**
148  * Return memory for an entire zone to system.  In fact, this will not be done
149  * unless all memory in the zone has been explicitly freed (by calls to
150  * NSZoneFree()).  For "non-freeable" zones, the number of NSZoneFree() calls
151  * must simply equal the number of allocation calls.  The default zone, on the
152  * other hand, cannot be recycled.<br />
153  * If Garbage Collection is enabled, this function has not effect.
154  */
155 GS_EXPORT void
156 NSRecycleZone (NSZone *zone);
157 
158 /**
159  * Frees memory pointed to by ptr (which should have been allocated by a
160  * previous call to NSZoneMalloc(), NSZoneCalloc(), or NSZoneRealloc()) and
161  * returns it to zone.  Note, if this is a nonfreeable zone, the memory is
162  * not actually freed, but the count of number of free()s is updated.<br />
163  * If Garbage Collection is enabled, the zone argument is ignored and this
164  * function causes ptr to be deallocated immediately.
165  */
166 GS_EXPORT void
167 NSZoneFree (NSZone *zone, void *ptr);
168 
169 /**
170  * Sets name of the given zone (useful for debugging and logging).
171  */
172 GS_EXPORT void
173 NSSetZoneName (NSZone *zone, NSString *name);
174 
175 /**
176  * Returns the name of the given zone (useful for debugging and logging).
177  */
178 GS_EXPORT NSString*
179 NSZoneName (NSZone *zone);
180 
181 #if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
182 
183 /** Deprecated ...<br />
184  * Checks integrity of a zone.  Not defined by OpenStep or OS X.
185  */
186 BOOL
187 NSZoneCheck (NSZone *zone);
188 
189 /**
190  *  <code>NSZoneStats</code> is the structure returned by the NSZoneStats()
191  *  function that summarizes the current usage of a zone.  It is similar to
192  *  the structure <em>mstats</em> in the GNU C library.  It has 5 fields of
193  *  type <code>size_t</code>-
194  *  <deflist>
195  *    <term><code>bytes_total</code></term>
196  *    <desc>
197  *    This is the total size of memory managed by the zone, in bytes.</desc>
198  *    <term><code>chunks_used</code></term>
199  *    <desc>This is the number of memory chunks in use in the zone.</desc>
200  *    <term><code>bytes_used</code></term>
201  *    <desc>This is the number of bytes in use.</desc>
202  *    <term><code>chunks_free</code></term>
203  *    <desc>This is the number of memory chunks that are not in use.</desc>
204  *    <term><code>bytes_free</code></term>
205  *    <desc>
206  *    This is the number of bytes managed by the zone that are not in use.
207  *    </desc>
208  *  </deflist>
209  */
210 struct NSZoneStats
211 {
212   size_t bytes_total;
213   size_t chunks_used;
214   size_t bytes_used;
215   size_t chunks_free;
216   size_t bytes_free;
217 };
218 
219 /** Deprecated ...<br />
220  *  Obtain statistics about the zone.  Implementation emphasis is on
221  *  correctness, not speed.  Not defined by OpenStep or OS X.
222  */
223 struct NSZoneStats
224 NSZoneStats (NSZone *zone);
225 
226 /**
227  * Try to get more memory - the normal process has failed.
228  * If we can't do anything, just return a null pointer.
229  * Try to do some logging if possible.
230  */
231 void*
232 GSOutOfMemory(NSUInteger size, BOOL retry);
233 
234 /**
235  * Called during +initialize to tell the class that instances created
236  * in future should have the specified instance variable as a weak
237  * pointer for garbage collection.<br />
238  * NB. making a pointer weak does not mean that it is automatically
239  * zeroed when the object it points to is garbage collected. To get that
240  * behavior you must asign values to the pointer using the
241  * GSAssignZeroingWeakPointer() function.<br />
242  * This function has no effect if the system is
243  * not built for garbage collection.
244  */
245 GS_EXPORT void
246 GSMakeWeakPointer(Class theClass, const char *iVarName);
247 
248 /**
249  * This function must be used to assign a value to a zeroing weak pointer.<br />
250  * A zeroing weak pointer is one where, when the garbage collector collects
251  * the object pointed to, it also clears the weak pointer.<br />
252  * Assigning zero (nil) will always succeed and has the effect of telling the
253  * garbage collector that it no longer needs to track the previously assigned
254  * object.  Apart from that case, a source needs to be garbage collectable for
255  * this function to work, and using a non-garbage collectable value will
256  * cause the function to return NO.<br />
257  * If the destination object (the weak pointer watching the source object)
258  * belongs to a chunk of memory which may be collected before the source
259  * object is collected, it is important that it is finalised and the
260  * finalisation code assigns zero to the pointer.<br />
261  * If garbage collection is not in use, this function performs a simple
262  * assignment returning YES, unless destination is null in which case it
263  * returns NO.
264  */
265 GS_EXPORT BOOL
266 GSAssignZeroingWeakPointer(void **destination, void *source);
267 
268 #endif
269 
270 GS_EXPORT NSUInteger
271 NSPageSize (void) __attribute__ ((const));
272 
273 GS_EXPORT NSUInteger
274 NSLogPageSize (void) __attribute__ ((const));
275 
276 GS_EXPORT NSUInteger
277 NSRoundDownToMultipleOfPageSize (NSUInteger bytes) __attribute__ ((const));
278 
279 GS_EXPORT NSUInteger
280 NSRoundUpToMultipleOfPageSize (NSUInteger bytes) __attribute__ ((const));
281 
282 GS_EXPORT NSUInteger
283 NSRealMemoryAvailable (void);
284 
285 GS_EXPORT void*
286 NSAllocateMemoryPages (NSUInteger bytes);
287 
288 GS_EXPORT void
289 NSDeallocateMemoryPages (void *ptr, NSUInteger bytes);
290 
291 GS_EXPORT void
292 NSCopyMemoryPages (const void *src, void *dest, NSUInteger bytes);
293 
294 #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, OS_API_LATEST)
295 
296 enum {
297   NSScannedOption = (1<<0),
298   NSCollectorDisabledOption = (1<<1)
299 };
300 
301 /** Allocate memory.  If garbage collection is not enabled this uses the
302  * default malloc zone and the options are ignored.<br />
303  * If garbage collection is enabled, the allocate memory is normally not
304  * scanned for pointers but is itsself garbage collectable.  The options
305  * argument is a bitmask in which NSScannedOption sets the memory to be
306  * scanned for pointers by the garbage collector, and
307  * NSCollectorDisabledOption causes the memory to be excempt from being
308  * garbage collected itsself.<br />
309  * In any case the memory returned is zero'ed.
310  */
311 GS_EXPORT void *
312 NSAllocateCollectable(NSUInteger size, NSUInteger options);
313 
314 /** Reallocate memory to be of a different size and/or to have different
315  * options settings.  The behavior of options is as for
316  * the NSAllocateCollectable() function.
317  */
318 GS_EXPORT void *
319 NSReallocateCollectable(void *ptr, NSUInteger size, NSUInteger options);
320 
321 #endif
322 
NSMakeCollectable(const void * cf)323 static inline id NSMakeCollectable(const void *cf) {
324 #if __has_feature(objc_arc)
325     return nil;
326 #else
327     return (id)cf; // Unimplemented; garbage collection is deprecated.
328 #endif
329 }
330 
331 #if	defined(__cplusplus)
332 }
333 #endif
334 
335 #endif /* not __NSZone_h_GNUSTEP_BASE_INCLUDE */
336