1 /* Copyright (C) 1998, 1999 Aladdin Enterprises. All rights reserved. 2 3 This software is provided AS-IS with no warranty, either express or 4 implied. 5 6 This software is distributed under license and may not be copied, 7 modified or distributed except as expressly authorized under the terms 8 of the license contained in the file LICENSE in this distribution. 9 10 For more information about licensing, please refer to 11 http://www.ghostscript.com/licensing/. For information on 12 commercial licensing, go to http://www.artifex.com/licensing/ or 13 contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14 San Rafael, CA 94903, U.S.A., +1(415)492-9861. 15 */ 16 17 /* $Id: gsmemraw.h,v 1.8 2004/08/04 19:36:12 stefan Exp $ */ 18 /* Client interface for "raw memory" allocator */ 19 20 /* Initial version 02/03/1998 by John Desrosiers (soho@crl.com) */ 21 /* Completely rewritten 6/26/1998 by L. Peter Deutsch <ghost@aladdin.com> */ 22 23 #ifndef gsmemraw_INCLUDED 24 # define gsmemraw_INCLUDED 25 26 #if 0 27 28 /* gsmemraw was an abstract base class. 29 * it is no longer in use, instead use the concrete base class is gs_memory_t 30 * since gs_memory_t contains interfaces that must be availiable throughout the system 31 * is is unadvisable to have a class below it without these. 32 */ 33 34 35 /* 36 * This interface provides minimal memory allocation and freeing capability. 37 * It is meant to be used for "wholesale" allocation of blocks -- typically, 38 * but not only, via malloc -- which are then divided up into "retail" 39 * objects. However, since it is a subset (superclass) of the "retail" 40 * interface defined in gsmemory.h, retail allocators implement it as 41 * well, and in fact the malloc interface defined in gsmalloc.h is used for 42 * both wholesale and retail allocation. 43 */ 44 45 /* 46 * Define the structure for reporting memory manager statistics. 47 */ 48 typedef struct gs_memory_status_s { 49 /* 50 * "Allocated" space is the total amount of space acquired from 51 * the parent of the memory manager. It includes space used for 52 * allocated data, space available for allocation, and overhead. 53 */ 54 ulong allocated; 55 /* 56 * "Used" space is the amount of space used by allocated data 57 * plus overhead. 58 */ 59 ulong used; 60 } gs_memory_status_t; 61 62 /* Define the abstract type for the memory manager. */ 63 #ifndef gs_raw_memory_t_DEFINED 64 #define gs_raw_memory_t_DEFINED 65 typedef struct gs_raw_memory_s gs_raw_memory_t; 66 #endif 67 68 /* Define the procedures for raw memory management. Memory managers have no 69 * standard constructor: each implementation defines its own, and is 70 * responsible for calling its superclass' initialization code first. 71 * Similarly, each implementation's destructor (release) must first take 72 * care of its own cleanup and then call the superclass' release. 73 * 74 * The allocation procedures must align objects as strictly as malloc. 75 * Formerly, the procedures were required to align objects as strictly 76 * as the compiler aligned structure members. However, the ANSI C standard 77 * does not require this -- it only requires malloc to align blocks 78 * strictly enough to prevent hardware access faults. Thus, for example, 79 * on the x86, malloc need not align blocks at all. And in fact, we have 80 * found one compiler (Microsoft VC 6) that 8-byte aligns 'double' members 81 * of structures, but whose malloc only 4-byte aligns its blocks. 82 * Ghostscript allocators could enforce the stricter alignment, but the 83 * few dozen lines of code required to implement this were rejected during 84 * code review as introducing too much risk for too little payoff. As a 85 * consequence of this, 86 * 87 * CLIENTS CANNOT ASSUME THAT BLOCKS RETURNED BY ANY OF THE ALLOCATION 88 * PROCEDURES ARE ALIGNED ANY MORE STRICTLY THAN IS REQUIRED BY THE 89 * HARDWARE. 90 * 91 * In particular, clients cannot assume that blocks returned by an allocator 92 * can be processed efficiently in any unit larger than a single byte: there 93 * is no guarantee that accessing any larger quantity will not require two 94 * memory accesses at the hardware level. Clients that want to process data 95 * efficiently in larger units must use ALIGNMENT_MOD to determine the 96 * actual alignment of the data in memory. 97 */ 98 99 /* 100 * Allocate bytes. The bytes are always aligned maximally 101 * if the processor requires alignment. 102 * 103 * Note that the object memory level can allocate bytes as 104 * either movable or immovable: raw memory blocks are 105 * always immovable. 106 */ 107 108 #define gs_memory_t_proc_alloc_bytes(proc, mem_t)\ 109 byte *proc(mem_t *mem, uint nbytes, client_name_t cname) 110 111 #define gs_alloc_bytes_immovable(mem, nbytes, cname)\ 112 ((mem)->procs.alloc_bytes_immovable(mem, nbytes, cname)) 113 114 /* 115 * Resize an object to a new number of elements. At the raw 116 * memory level, the "element" is a byte; for object memory 117 * (gsmemory.h), the object may be an an array of either 118 * bytes or structures. The new size may be larger than, 119 * the same as, or smaller than the old. If the new size is 120 * the same as the old, resize_object returns the same 121 * object; otherwise, it preserves the first min(old_size, 122 * new_size) bytes of the object's contents. 123 */ 124 125 #define gs_memory_t_proc_resize_object(proc, mem_t)\ 126 void *proc(mem_t *mem, void *obj, uint new_num_elements,\ 127 client_name_t cname) 128 129 #define gs_resize_object(mem, obj, newn, cname)\ 130 ((mem)->procs.resize_object(mem, obj, newn, cname)) 131 132 /* 133 * Free an object (at the object memory level, this includes 134 * everything except strings). Note: data == 0 must be 135 * allowed, and must be a no-op. 136 */ 137 138 #define gs_memory_t_proc_free_object(proc, mem_t)\ 139 void proc(mem_t *mem, void *data, client_name_t cname) 140 141 #define gs_free_object(mem, data, cname)\ 142 ((mem)->procs.free_object(mem, data, cname)) 143 144 /* 145 * Report status (assigned, used). 146 */ 147 148 #define gs_memory_t_proc_status(proc, mem_t)\ 149 void proc(mem_t *mem, gs_memory_status_t *status) 150 151 #define gs_memory_status(mem, pst)\ 152 ((mem)->procs.status(mem, pst)) 153 154 /* 155 * Return the stable allocator for this allocator. The 156 * stable allocator allocates from the same heap and in 157 * the same VM space, but is not subject to save and restore. 158 * (It is the client's responsibility to avoid creating 159 * dangling pointers.) 160 * 161 * Note that the stable allocator may be the same allocator 162 * as this one. 163 */ 164 165 #define gs_memory_t_proc_stable(proc, mem_t)\ 166 mem_t *proc(mem_t *mem) 167 168 #define gs_memory_stable(mem)\ 169 ((mem)->procs.stable(mem)) 170 171 /* 172 * Free one or more of: data memory acquired by the allocator 173 * (FREE_ALL_DATA), overhead structures other than the 174 * allocator itself (FREE_ALL_STRUCTURES), and the allocator 175 * itself (FREE_ALL_ALLOCATOR). Note that this requires 176 * allocators to keep track of all the memory they have ever 177 * acquired, and where they acquired it. Note that this 178 * operation propagates to the stable allocator (if 179 * different). 180 */ 181 182 #define FREE_ALL_DATA 1 183 #define FREE_ALL_STRUCTURES 2 184 #define FREE_ALL_ALLOCATOR 4 185 #define FREE_ALL_EVERYTHING\ 186 (FREE_ALL_DATA | FREE_ALL_STRUCTURES | FREE_ALL_ALLOCATOR) 187 188 #define gs_memory_t_proc_free_all(proc, mem_t)\ 189 void proc(mem_t *mem, uint free_mask, client_name_t cname) 190 191 #define gs_memory_free_all(mem, free_mask, cname)\ 192 ((mem)->procs.free_all(mem, free_mask, cname)) 193 /* Backward compatibility */ 194 #define gs_free_all(mem)\ 195 gs_memory_free_all(mem, FREE_ALL_DATA, "(free_all)") 196 197 /* 198 * Consolidate free space. This may be used as part of (or 199 * as an alternative to) garbage collection, or before 200 * giving up on an attempt to allocate. 201 */ 202 203 #define gs_memory_t_proc_consolidate_free(proc, mem_t)\ 204 void proc(mem_t *mem) 205 206 #define gs_consolidate_free(mem)\ 207 ((mem)->procs.consolidate_free(mem)) 208 209 /* Define the members of the procedure structure. */ 210 #define gs_raw_memory_procs(mem_t)\ 211 gs_memory_t_proc_alloc_bytes((*alloc_bytes_immovable), mem_t);\ 212 gs_memory_t_proc_resize_object((*resize_object), mem_t);\ 213 gs_memory_t_proc_free_object((*free_object), mem_t);\ 214 gs_memory_t_proc_stable((*stable), mem_t);\ 215 gs_memory_t_proc_status((*status), mem_t);\ 216 gs_memory_t_proc_free_all((*free_all), mem_t);\ 217 gs_memory_t_proc_consolidate_free((*consolidate_free), mem_t) 218 219 /* 220 * Define an abstract raw-memory allocator instance. 221 * Subclasses may have additional state. 222 */ 223 typedef struct gs_raw_memory_procs_s { 224 gs_raw_memory_procs(gs_raw_memory_t); 225 } gs_raw_memory_procs_t; 226 227 228 229 struct gs_raw_memory_s { 230 gs_raw_memory_t *stable_memory; /* cache the stable allocator */ 231 gs_raw_memory_procs_t procs; 232 }; 233 234 #endif /* 0 */ 235 #endif /* gsmemraw_INCLUDED */ 236