12a6b7db3Sskrll /* objalloc.h -- routines to allocate memory for objects 2*dd7241dfSchristos Copyright (C) 1997-2024 Free Software Foundation, Inc. 32a6b7db3Sskrll Written by Ian Lance Taylor, Cygnus Solutions. 42a6b7db3Sskrll 52a6b7db3Sskrll This program is free software; you can redistribute it and/or modify it 62a6b7db3Sskrll under the terms of the GNU General Public License as published by the 72a6b7db3Sskrll Free Software Foundation; either version 2, or (at your option) any 82a6b7db3Sskrll later version. 92a6b7db3Sskrll 102a6b7db3Sskrll This program is distributed in the hope that it will be useful, 112a6b7db3Sskrll but WITHOUT ANY WARRANTY; without even the implied warranty of 122a6b7db3Sskrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 132a6b7db3Sskrll GNU General Public License for more details. 142a6b7db3Sskrll 152a6b7db3Sskrll You should have received a copy of the GNU General Public License 162a6b7db3Sskrll along with this program; if not, write to the Free Software 172a6b7db3Sskrll Foundation, 51 Franklin Street - Fifth Floor, 182a6b7db3Sskrll Boston, MA 02110-1301, USA. */ 192a6b7db3Sskrll 202a6b7db3Sskrll #ifndef OBJALLOC_H 212a6b7db3Sskrll #define OBJALLOC_H 222a6b7db3Sskrll 232a6b7db3Sskrll #include "ansidecl.h" 242a6b7db3Sskrll 252a6b7db3Sskrll /* These routines allocate space for an object. The assumption is 262a6b7db3Sskrll that the object will want to allocate space as it goes along, but 272a6b7db3Sskrll will never want to free any particular block. There is a function 282a6b7db3Sskrll to free a block, which also frees all more recently allocated 292a6b7db3Sskrll blocks. There is also a function to free all the allocated space. 302a6b7db3Sskrll 312a6b7db3Sskrll This is essentially a specialization of obstacks. The main 322a6b7db3Sskrll difference is that a block may not be allocated a bit at a time. 332a6b7db3Sskrll Another difference is that these routines are always built on top 342a6b7db3Sskrll of malloc, and always pass an malloc failure back to the caller, 352a6b7db3Sskrll unlike more recent versions of obstacks. */ 362a6b7db3Sskrll 372a6b7db3Sskrll /* This is what an objalloc structure looks like. Callers should not 382a6b7db3Sskrll refer to these fields, nor should they allocate these structure 392a6b7db3Sskrll themselves. Instead, they should only create them via 402a6b7db3Sskrll objalloc_init, and only access them via the functions and macros 412a6b7db3Sskrll listed below. The structure is only defined here so that we can 422a6b7db3Sskrll access it via macros. */ 432a6b7db3Sskrll 442a6b7db3Sskrll struct objalloc 452a6b7db3Sskrll { 462a6b7db3Sskrll char *current_ptr; 472a6b7db3Sskrll unsigned int current_space; 482a6b7db3Sskrll void *chunks; 492a6b7db3Sskrll }; 502a6b7db3Sskrll 512a6b7db3Sskrll /* Work out the required alignment. */ 522a6b7db3Sskrll 532a6b7db3Sskrll struct objalloc_align { char x; double d; }; 542a6b7db3Sskrll 552a6b7db3Sskrll #if defined (__STDC__) && __STDC__ 562a6b7db3Sskrll #ifndef offsetof 572a6b7db3Sskrll #include <stddef.h> 582a6b7db3Sskrll #endif 592a6b7db3Sskrll #endif 602a6b7db3Sskrll #ifndef offsetof 612a6b7db3Sskrll #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 622a6b7db3Sskrll #endif 632a6b7db3Sskrll #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) 642a6b7db3Sskrll 652a6b7db3Sskrll /* Create an objalloc structure. Returns NULL if malloc fails. */ 662a6b7db3Sskrll 672a6b7db3Sskrll extern struct objalloc *objalloc_create (void); 682a6b7db3Sskrll 692a6b7db3Sskrll /* Allocate space from an objalloc structure. Returns NULL if malloc 702a6b7db3Sskrll fails. */ 712a6b7db3Sskrll 722a6b7db3Sskrll extern void *_objalloc_alloc (struct objalloc *, unsigned long); 732a6b7db3Sskrll 742a6b7db3Sskrll /* The macro version of objalloc_alloc. We only define this if using 752a6b7db3Sskrll gcc, because otherwise we would have to evaluate the arguments 762a6b7db3Sskrll multiple times, or use a temporary field as obstack.h does. */ 772a6b7db3Sskrll 782a6b7db3Sskrll #if defined (__GNUC__) && defined (__STDC__) && __STDC__ 792a6b7db3Sskrll 802a6b7db3Sskrll /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 812a6b7db3Sskrll does not implement __extension__. But that compiler doesn't define 822a6b7db3Sskrll __GNUC_MINOR__. */ 832a6b7db3Sskrll #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 842a6b7db3Sskrll #define __extension__ 852a6b7db3Sskrll #endif 862a6b7db3Sskrll 872a6b7db3Sskrll #define objalloc_alloc(o, l) \ 882a6b7db3Sskrll __extension__ \ 892a6b7db3Sskrll ({ struct objalloc *__o = (o); \ 902a6b7db3Sskrll unsigned long __len = (l); \ 912a6b7db3Sskrll if (__len == 0) \ 922a6b7db3Sskrll __len = 1; \ 932a6b7db3Sskrll __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ 94d18545deSdrochner (__len != 0 && __len <= __o->current_space \ 952a6b7db3Sskrll ? (__o->current_ptr += __len, \ 962a6b7db3Sskrll __o->current_space -= __len, \ 972a6b7db3Sskrll (void *) (__o->current_ptr - __len)) \ 982a6b7db3Sskrll : _objalloc_alloc (__o, __len)); }) 992a6b7db3Sskrll 1002a6b7db3Sskrll #else /* ! __GNUC__ */ 1012a6b7db3Sskrll 1022a6b7db3Sskrll #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) 1032a6b7db3Sskrll 1042a6b7db3Sskrll #endif /* ! __GNUC__ */ 1052a6b7db3Sskrll 1062a6b7db3Sskrll /* Free an entire objalloc structure. */ 1072a6b7db3Sskrll 1082a6b7db3Sskrll extern void objalloc_free (struct objalloc *); 1092a6b7db3Sskrll 1102a6b7db3Sskrll /* Free a block allocated by objalloc_alloc. This also frees all more 1112a6b7db3Sskrll recently allocated blocks. */ 1122a6b7db3Sskrll 1132a6b7db3Sskrll extern void objalloc_free_block (struct objalloc *, void *); 1142a6b7db3Sskrll 1152a6b7db3Sskrll #endif /* OBJALLOC_H */ 116