bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Use malloca instead alloca


From: Ondřej Bílka
Subject: Re: [PATCH] Use malloca instead alloca
Date: Sun, 30 Dec 2012 10:40:34 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Sat, Dec 29, 2012 at 05:23:17PM +0100, Ondřej Bílka wrote:
> On Sat, Dec 29, 2012 at 03:29:36PM +0100, Petr Baudis wrote:
> > 
> > So it is still unsafe to call malloca() in a loop. This is also
> > something that should be documented. Or can't we do better? I think even
> > having an alternative 2-parameter call would be worth considering so
> > that users that need this can use a local variable to keep track of
> > stack usage, as per include/alloca.h.
> I do not know how to portably do that. 
> 
> For platform specific way best solution is to read where bottom of stack is
> and allocate only when at least say 32768 bytes are left.
> > 
And when knowing stack boundaries I could also recognize stack pointer
by single comparison.

It needs to define _STACK_TOP,_STACK_CUP, _STACK_SIZE macros for stack 
parameters. 
I can find them by pthread_attr_getstack but this call is slow. 

/* Safe automatic memory allocation.
   Copyright (C) 2012 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

#ifndef _MALLOCA_H
#define _MALLOCA_H

#include <alloca.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

  /* malloca(N) is a safe variant of alloca(N).  It allocates N bytes of
     memory allocated on the stack while allocation keeps at least 32768
     bytes of stack space and heap otherwise. When memory cannot be
     allocated from heap malloca aborts.
     It must be freed using freea() before the function returns. */

#if _STACK_GROWS_DOWN
#define _ALLOCA_FITS(n) _STACK_CUR - (n) - 32768 > _STACK_TOP
  /* We use & instead && because gcc simplification made by gcc.*/
#define _STACK_PTR(p) ( _STACK_TOP < (p) & (p) < _STACK_TOP + _STACK_SIZE )
#else
#if _STACK_GROWS_UP
#define _ALLOCA_FITS(n) _STACK_CUR + (n) + 32768 < _STACK_TOP
#define _STACK_PTR(p) ( _STACK_TOP - _STACK_SIZE < (p) & (p) < _STACK_TOP )
#else
#define _ALLOCA_FITS(n) 0
#define _STACK_PTR(x)   0
#endif

#define malloca(n) ({                             \
  size_t  __n__ = (n);                            \
  void  * __r__ = NULL;                           \
  if (ALLOCA_FITS (__n__))                        \
    __r__ = alloca (__n__);                       \
  else                                            \
    {                                             \
      __r__ = malloc (__n__);                     \
      if (!__r__ )                                \
            abort();                              \
    }                                             \
  __r__;                                          \
})

static inline freea(void * __r)
{
  if (__r && !_STACK_PTR(__r))
    free (__r);
}

#endif
#ifdef __cplusplus
}
#endif


#endif /* _MALLOCA_H */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]