15796c8dcSSimon Schubert /* objalloc.h -- routines to allocate memory for objects 2*ef5ccd6cSJohn Marino Copyright 1997-2012 Free Software Foundation, Inc. 35796c8dcSSimon Schubert Written by Ian Lance Taylor, Cygnus Solutions. 45796c8dcSSimon Schubert 55796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify it 65796c8dcSSimon Schubert under the terms of the GNU General Public License as published by the 75796c8dcSSimon Schubert Free Software Foundation; either version 2, or (at your option) any 85796c8dcSSimon Schubert later version. 95796c8dcSSimon Schubert 105796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 115796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 125796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 135796c8dcSSimon Schubert GNU General Public License for more details. 145796c8dcSSimon Schubert 155796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 165796c8dcSSimon Schubert along with this program; if not, write to the Free Software 175796c8dcSSimon Schubert Foundation, 51 Franklin Street - Fifth Floor, 185796c8dcSSimon Schubert Boston, MA 02110-1301, USA. */ 195796c8dcSSimon Schubert 205796c8dcSSimon Schubert #ifndef OBJALLOC_H 215796c8dcSSimon Schubert #define OBJALLOC_H 225796c8dcSSimon Schubert 235796c8dcSSimon Schubert #include "ansidecl.h" 245796c8dcSSimon Schubert 255796c8dcSSimon Schubert /* These routines allocate space for an object. The assumption is 265796c8dcSSimon Schubert that the object will want to allocate space as it goes along, but 275796c8dcSSimon Schubert will never want to free any particular block. There is a function 285796c8dcSSimon Schubert to free a block, which also frees all more recently allocated 295796c8dcSSimon Schubert blocks. There is also a function to free all the allocated space. 305796c8dcSSimon Schubert 315796c8dcSSimon Schubert This is essentially a specialization of obstacks. The main 325796c8dcSSimon Schubert difference is that a block may not be allocated a bit at a time. 335796c8dcSSimon Schubert Another difference is that these routines are always built on top 345796c8dcSSimon Schubert of malloc, and always pass an malloc failure back to the caller, 355796c8dcSSimon Schubert unlike more recent versions of obstacks. */ 365796c8dcSSimon Schubert 375796c8dcSSimon Schubert /* This is what an objalloc structure looks like. Callers should not 385796c8dcSSimon Schubert refer to these fields, nor should they allocate these structure 395796c8dcSSimon Schubert themselves. Instead, they should only create them via 405796c8dcSSimon Schubert objalloc_init, and only access them via the functions and macros 415796c8dcSSimon Schubert listed below. The structure is only defined here so that we can 425796c8dcSSimon Schubert access it via macros. */ 435796c8dcSSimon Schubert 445796c8dcSSimon Schubert struct objalloc 455796c8dcSSimon Schubert { 465796c8dcSSimon Schubert char *current_ptr; 475796c8dcSSimon Schubert unsigned int current_space; 485796c8dcSSimon Schubert void *chunks; 495796c8dcSSimon Schubert }; 505796c8dcSSimon Schubert 515796c8dcSSimon Schubert /* Work out the required alignment. */ 525796c8dcSSimon Schubert 535796c8dcSSimon Schubert struct objalloc_align { char x; double d; }; 545796c8dcSSimon Schubert 555796c8dcSSimon Schubert #if defined (__STDC__) && __STDC__ 565796c8dcSSimon Schubert #ifndef offsetof 575796c8dcSSimon Schubert #include <stddef.h> 585796c8dcSSimon Schubert #endif 595796c8dcSSimon Schubert #endif 605796c8dcSSimon Schubert #ifndef offsetof 615796c8dcSSimon Schubert #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 625796c8dcSSimon Schubert #endif 635796c8dcSSimon Schubert #define OBJALLOC_ALIGN offsetof (struct objalloc_align, d) 645796c8dcSSimon Schubert 655796c8dcSSimon Schubert /* Create an objalloc structure. Returns NULL if malloc fails. */ 665796c8dcSSimon Schubert 675796c8dcSSimon Schubert extern struct objalloc *objalloc_create (void); 685796c8dcSSimon Schubert 695796c8dcSSimon Schubert /* Allocate space from an objalloc structure. Returns NULL if malloc 705796c8dcSSimon Schubert fails. */ 715796c8dcSSimon Schubert 725796c8dcSSimon Schubert extern void *_objalloc_alloc (struct objalloc *, unsigned long); 735796c8dcSSimon Schubert 745796c8dcSSimon Schubert /* The macro version of objalloc_alloc. We only define this if using 755796c8dcSSimon Schubert gcc, because otherwise we would have to evaluate the arguments 765796c8dcSSimon Schubert multiple times, or use a temporary field as obstack.h does. */ 775796c8dcSSimon Schubert 785796c8dcSSimon Schubert #if defined (__GNUC__) && defined (__STDC__) && __STDC__ 795796c8dcSSimon Schubert 805796c8dcSSimon Schubert /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and 815796c8dcSSimon Schubert does not implement __extension__. But that compiler doesn't define 825796c8dcSSimon Schubert __GNUC_MINOR__. */ 835796c8dcSSimon Schubert #if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__) 845796c8dcSSimon Schubert #define __extension__ 855796c8dcSSimon Schubert #endif 865796c8dcSSimon Schubert 875796c8dcSSimon Schubert #define objalloc_alloc(o, l) \ 885796c8dcSSimon Schubert __extension__ \ 895796c8dcSSimon Schubert ({ struct objalloc *__o = (o); \ 905796c8dcSSimon Schubert unsigned long __len = (l); \ 915796c8dcSSimon Schubert if (__len == 0) \ 925796c8dcSSimon Schubert __len = 1; \ 935796c8dcSSimon Schubert __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1); \ 94*ef5ccd6cSJohn Marino (__len != 0 && __len <= __o->current_space \ 955796c8dcSSimon Schubert ? (__o->current_ptr += __len, \ 965796c8dcSSimon Schubert __o->current_space -= __len, \ 975796c8dcSSimon Schubert (void *) (__o->current_ptr - __len)) \ 985796c8dcSSimon Schubert : _objalloc_alloc (__o, __len)); }) 995796c8dcSSimon Schubert 1005796c8dcSSimon Schubert #else /* ! __GNUC__ */ 1015796c8dcSSimon Schubert 1025796c8dcSSimon Schubert #define objalloc_alloc(o, l) _objalloc_alloc ((o), (l)) 1035796c8dcSSimon Schubert 1045796c8dcSSimon Schubert #endif /* ! __GNUC__ */ 1055796c8dcSSimon Schubert 1065796c8dcSSimon Schubert /* Free an entire objalloc structure. */ 1075796c8dcSSimon Schubert 1085796c8dcSSimon Schubert extern void objalloc_free (struct objalloc *); 1095796c8dcSSimon Schubert 1105796c8dcSSimon Schubert /* Free a block allocated by objalloc_alloc. This also frees all more 1115796c8dcSSimon Schubert recently allocated blocks. */ 1125796c8dcSSimon Schubert 1135796c8dcSSimon Schubert extern void objalloc_free_block (struct objalloc *, void *); 1145796c8dcSSimon Schubert 1155796c8dcSSimon Schubert #endif /* OBJALLOC_H */ 116