Blame include/objalloc.h

Packit bbfece
/* objalloc.h -- routines to allocate memory for objects
Packit bbfece
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit bbfece
   Written by Ian Lance Taylor, Cygnus Solutions.
Packit bbfece
Packit bbfece
This program is free software; you can redistribute it and/or modify it
Packit bbfece
under the terms of the GNU General Public License as published by the
Packit bbfece
Free Software Foundation; either version 2, or (at your option) any
Packit bbfece
later version.
Packit bbfece
Packit bbfece
This program is distributed in the hope that it will be useful,
Packit bbfece
but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bbfece
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit bbfece
GNU General Public License for more details.
Packit bbfece
Packit bbfece
You should have received a copy of the GNU General Public License
Packit bbfece
along with this program; if not, write to the Free Software
Packit bbfece
Foundation, 51 Franklin Street - Fifth Floor,
Packit bbfece
Boston, MA 02110-1301, USA.  */
Packit bbfece
Packit bbfece
#ifndef OBJALLOC_H
Packit bbfece
#define OBJALLOC_H
Packit bbfece
Packit bbfece
#include "ansidecl.h"
Packit bbfece
Packit bbfece
/* These routines allocate space for an object.  The assumption is
Packit bbfece
   that the object will want to allocate space as it goes along, but
Packit bbfece
   will never want to free any particular block.  There is a function
Packit bbfece
   to free a block, which also frees all more recently allocated
Packit bbfece
   blocks.  There is also a function to free all the allocated space.
Packit bbfece
Packit bbfece
   This is essentially a specialization of obstacks.  The main
Packit bbfece
   difference is that a block may not be allocated a bit at a time.
Packit bbfece
   Another difference is that these routines are always built on top
Packit bbfece
   of malloc, and always pass an malloc failure back to the caller,
Packit bbfece
   unlike more recent versions of obstacks.  */
Packit bbfece
Packit bbfece
/* This is what an objalloc structure looks like.  Callers should not
Packit bbfece
   refer to these fields, nor should they allocate these structure
Packit bbfece
   themselves.  Instead, they should only create them via
Packit bbfece
   objalloc_init, and only access them via the functions and macros
Packit bbfece
   listed below.  The structure is only defined here so that we can
Packit bbfece
   access it via macros.  */
Packit bbfece
Packit bbfece
struct objalloc
Packit bbfece
{
Packit bbfece
  char *current_ptr;
Packit bbfece
  unsigned int current_space;
Packit bbfece
  void *chunks;
Packit bbfece
};
Packit bbfece
Packit bbfece
/* Work out the required alignment.  */
Packit bbfece
Packit bbfece
struct objalloc_align { char x; double d; };
Packit bbfece
Packit bbfece
#if defined (__STDC__) && __STDC__
Packit bbfece
#ifndef offsetof
Packit bbfece
#include <stddef.h>
Packit bbfece
#endif
Packit bbfece
#endif
Packit bbfece
#ifndef offsetof
Packit bbfece
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
Packit bbfece
#endif
Packit bbfece
#define OBJALLOC_ALIGN offsetof (struct objalloc_align, d)
Packit bbfece
Packit bbfece
/* Create an objalloc structure.  Returns NULL if malloc fails.  */
Packit bbfece
Packit bbfece
extern struct objalloc *objalloc_create (void);
Packit bbfece
Packit bbfece
/* Allocate space from an objalloc structure.  Returns NULL if malloc
Packit bbfece
   fails.  */
Packit bbfece
Packit bbfece
extern void *_objalloc_alloc (struct objalloc *, unsigned long);
Packit bbfece
Packit bbfece
/* The macro version of objalloc_alloc.  We only define this if using
Packit bbfece
   gcc, because otherwise we would have to evaluate the arguments
Packit bbfece
   multiple times, or use a temporary field as obstack.h does.  */
Packit bbfece
Packit bbfece
#if defined (__GNUC__) && defined (__STDC__) && __STDC__
Packit bbfece
Packit bbfece
/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
Packit bbfece
   does not implement __extension__.  But that compiler doesn't define
Packit bbfece
   __GNUC_MINOR__.  */
Packit bbfece
#if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
Packit bbfece
#define __extension__
Packit bbfece
#endif
Packit bbfece
Packit bbfece
#define objalloc_alloc(o, l)						\
Packit bbfece
  __extension__								\
Packit bbfece
  ({ struct objalloc *__o = (o);					\
Packit bbfece
     unsigned long __len = (l);						\
Packit bbfece
     if (__len == 0)							\
Packit bbfece
       __len = 1;							\
Packit bbfece
     __len = (__len + OBJALLOC_ALIGN - 1) &~ (OBJALLOC_ALIGN - 1);	\
Packit bbfece
     (__len != 0 && __len <= __o->current_space				\
Packit bbfece
      ? (__o->current_ptr += __len,					\
Packit bbfece
	 __o->current_space -= __len,					\
Packit bbfece
	 (void *) (__o->current_ptr - __len))				\
Packit bbfece
      : _objalloc_alloc (__o, __len)); })
Packit bbfece
Packit bbfece
#else /* ! __GNUC__ */
Packit bbfece
Packit bbfece
#define objalloc_alloc(o, l) _objalloc_alloc ((o), (l))
Packit bbfece
Packit bbfece
#endif /* ! __GNUC__ */
Packit bbfece
Packit bbfece
/* Free an entire objalloc structure.  */
Packit bbfece
Packit bbfece
extern void objalloc_free (struct objalloc *);
Packit bbfece
Packit bbfece
/* Free a block allocated by objalloc_alloc.  This also frees all more
Packit bbfece
   recently allocated blocks.  */
Packit bbfece
Packit bbfece
extern void objalloc_free_block (struct objalloc *, void *);
Packit bbfece
Packit bbfece
#endif /* OBJALLOC_H */