1169689Skan/* Copyright (C) 2004 Free Software Foundation, Inc.
2169689Skan
3169689Skan   This file is part of GCC.
4169689Skan
5169689Skan   GCC is free software; you can redistribute it and/or modify
6169689Skan   it under the terms of the GNU General Public License as published by
7169689Skan   the Free Software Foundation; either version 2, or (at your option)
8169689Skan   any later version.
9169689Skan
10169689Skan   GCC is distributed in the hope that it will be useful,
11169689Skan   but WITHOUT ANY WARRANTY; without even the implied warranty of
12169689Skan   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13169689Skan   GNU General Public License for more details.
14169689Skan
15169689Skan   You should have received a copy of the GNU General Public License
16169689Skan   along with GCC; see the file COPYING.  If not, write to
17169689Skan   the Free Software Foundation, 51 Franklin Street, Fifth Floor,
18169689Skan   Boston, MA 02110-1301, USA.  */
19169689Skan
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
22169689Skan   the resulting executable to be covered by the GNU General Public
23169689Skan   License.  This exception does not however invalidate any other
24169689Skan   reasons why the executable file might be covered by the GNU General
25169689Skan   Public License.  */
26169689Skan
27169689Skan#ifndef _MM_MALLOC_H_INCLUDED
28169689Skan#define _MM_MALLOC_H_INCLUDED
29169689Skan
30169689Skan#include <stdlib.h>
31169689Skan#include <errno.h>
32169689Skan
33169689Skanstatic __inline__ void*
34169689Skan_mm_malloc (size_t size, size_t align)
35169689Skan{
36169689Skan  void * malloc_ptr;
37169689Skan  void * aligned_ptr;
38169689Skan
39169689Skan  /* Error if align is not a power of two.  */
40169689Skan  if (align & (align - 1))
41169689Skan    {
42169689Skan      errno = EINVAL;
43169689Skan      return ((void*) 0);
44169689Skan    }
45169689Skan
46169689Skan  if (size == 0)
47169689Skan    return ((void *) 0);
48169689Skan
49169689Skan /* Assume malloc'd pointer is aligned at least to sizeof (void*).
50169689Skan    If necessary, add another sizeof (void*) to store the value
51169689Skan    returned by malloc. Effectively this enforces a minimum alignment
52169689Skan    of sizeof double. */
53169689Skan    if (align < 2 * sizeof (void *))
54169689Skan      align = 2 * sizeof (void *);
55169689Skan
56169689Skan  malloc_ptr = malloc (size + align);
57169689Skan  if (!malloc_ptr)
58169689Skan    return ((void *) 0);
59169689Skan
60169689Skan  /* Align  We have at least sizeof (void *) space below malloc'd ptr. */
61169689Skan  aligned_ptr = (void *) (((size_t) malloc_ptr + align)
62169689Skan			  & ~((size_t) (align) - 1));
63169689Skan
64169689Skan  /* Store the original pointer just before p.  */
65169689Skan  ((void **) aligned_ptr) [-1] = malloc_ptr;
66169689Skan
67169689Skan  return aligned_ptr;
68169689Skan}
69169689Skan
70169689Skanstatic __inline__ void
71169689Skan_mm_free (void * aligned_ptr)
72169689Skan{
73169689Skan  if (aligned_ptr)
74169689Skan    free (((void **) aligned_ptr) [-1]);
75169689Skan}
76169689Skan
77169689Skan#endif /* _MM_MALLOC_H_INCLUDED */
78