This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Use malloca instead alloca
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Paul Eggert <eggert at cs dot ucla dot edu>
- Cc: GNU C Library <libc-alpha at sourceware dot org>,bug-gnulib <bug-gnulib at gnu dot org>
- Date: Fri, 28 Dec 2012 18:38:23 +0100
- Subject: Re: [PATCH] Use malloca instead alloca
- References: <20121228132908.GA23510@domone><50DDD217.4050707@cs.ucla.edu>
On Fri, Dec 28, 2012 at 09:08:39AM -0800, Paul Eggert wrote:
> On 12/28/2012 05:29 AM, OndÅej BÃlka wrote:
> >Initialy I examined gnulib one but it uses hash tables and is hard to
> >inline so I wrote faster variant.
>
> Where is the faster variant?
Below. I fixed few details since first submission to libc-alpha.
> Should/could it be merged into gnulib?
Should. I am not expert on portability issues so improving portability
would be appreciated.
/* 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 <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define _ALLOCA_MC 0x2439a2431bca4812L
#define _MALLOC_MC 0x1bca48122439a243L
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
/* malloca(N) is a safe variant of alloca(N). It allocates N bytes of
memory allocated on the stack or heap for large requests.
It must be freed using freea() before
the function returns. Upon failure, it returns NULL. */
#if 1
#define malloca(n) ({\
void *__r__ = NULL;\
if (n < 4096 - 8)\
{\
__r__ = alloca (n + sizeof (uint64_t));\
if (__r__)\
{\
*((uint64_t *)__r__) = _ALLOCA_MC;\
__r__ += sizeof (uint64_t);\
}\
}\
if (!__r__)\
{\
__r__ = malloc (n + sizeof (uint64_t));\
if (__r__)\
{\
*((uint64_t *)__r__) = _MALLOC_MC;\
__r__ += sizeof (uint64_t);\
}\
}\
__r__;\
})
/* If desired we could detect more corruption by
adding constant to end of alloca'd array.*/
#define freea(r) {\
void *__r__ = r;\
if (__r__)\
{\
__r__ -= sizeof (uint64_t);\
if ( *((uint64_t *)__r__) == _MALLOC_MC)\
free (__r__);\
else if (*((uint64_t *)__r__) != _ALLOCA_MC)\
__abort_freea();\
}\
}
static void __abort_freea()
{
fprintf(stderr, "double freea or corruption\n");
abort();
}
#else
#define malloca malloc
#define freea free
#endif
#ifdef __cplusplus
}
#endif
#endif /* _MALLOCA_H */