gmm_malloc.h revision 169690
150397Sobrien/* Copyright (C) 2004 Free Software Foundation, Inc.
290075Sobrien
3169689Skan   This file is part of GCC.
450397Sobrien
550397Sobrien   GCC is free software; you can redistribute it and/or modify
690075Sobrien   it under the terms of the GNU General Public License as published by
750397Sobrien   the Free Software Foundation; either version 2, or (at your option)
890075Sobrien   any later version.
990075Sobrien
1090075Sobrien   GCC is distributed in the hope that it will be useful,
1190075Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1250397Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1390075Sobrien   GNU General Public License for more details.
1490075Sobrien
1590075Sobrien   You should have received a copy of the GNU General Public License
1690075Sobrien   along with GCC; see the file COPYING.  If not, write to
1750397Sobrien   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
1850397Sobrien   Boston, MA 02110-1301, USA.  */
1990075Sobrien
20169689Skan/* As a special exception, if you include this header file into source
21169689Skan   files compiled by GCC, this header file does not by itself cause
2250397Sobrien   the resulting executable to be covered by the GNU General Public
2350397Sobrien   License.  This exception does not however invalidate any other
2450397Sobrien   reasons why the executable file might be covered by the GNU General
2550397Sobrien   Public License.  */
2650397Sobrien
2750397Sobrien#ifndef _MM_MALLOC_H_INCLUDED
2850397Sobrien#define _MM_MALLOC_H_INCLUDED
2950397Sobrien
3050397Sobrien#include <stdlib.h>
3150397Sobrien#include <errno.h>
3250397Sobrien
3350397Sobrienstatic __inline__ void*
3450397Sobrien_mm_malloc (size_t size, size_t align)
3550397Sobrien{
3650397Sobrien  void * malloc_ptr;
3750397Sobrien  void * aligned_ptr;
3850397Sobrien
3950397Sobrien  /* Error if align is not a power of two.  */
4050397Sobrien  if (align & (align - 1))
4150397Sobrien    {
4250397Sobrien      errno = EINVAL;
4350397Sobrien      return ((void*) 0);
4450397Sobrien    }
4550397Sobrien
4650397Sobrien  if (size == 0)
4790075Sobrien    return ((void *) 0);
4850397Sobrien
4950397Sobrien /* Assume malloc'd pointer is aligned at least to sizeof (void*).
5090075Sobrien    If necessary, add another sizeof (void*) to store the value
5190075Sobrien    returned by malloc. Effectively this enforces a minimum alignment
52132718Skan    of sizeof double. */
53132718Skan    if (align < 2 * sizeof (void *))
5490075Sobrien      align = 2 * sizeof (void *);
5590075Sobrien
5690075Sobrien  malloc_ptr = malloc (size + align);
5790075Sobrien  if (!malloc_ptr)
5890075Sobrien    return ((void *) 0);
5990075Sobrien
6090075Sobrien  /* Align  We have at least sizeof (void *) space below malloc'd ptr. */
6190075Sobrien  aligned_ptr = (void *) (((size_t) malloc_ptr + align)
6290075Sobrien			  & ~((size_t) (align) - 1));
6390075Sobrien
6490075Sobrien  /* Store the original pointer just before p.  */
6590075Sobrien  ((void **) aligned_ptr) [-1] = malloc_ptr;
6690075Sobrien
6790075Sobrien  return aligned_ptr;
6890075Sobrien}
6990075Sobrien
7090075Sobrienstatic __inline__ void
7190075Sobrien_mm_free (void * aligned_ptr)
7290075Sobrien{
7390075Sobrien  if (aligned_ptr)
7490075Sobrien    free (((void **) aligned_ptr) [-1]);
75117395Skan}
76132718Skan
77169689Skan#endif /* _MM_MALLOC_H_INCLUDED */
78169689Skan