1238384Sjkim/* Copyright (C) 2005-2020 Free Software Foundation, Inc.
2238384Sjkim   Contributed by Richard Henderson <rth@redhat.com>.
3238384Sjkim
4238384Sjkim   This file is part of the GNU Offloading and Multi Processing Library
5238384Sjkim   (libgomp).
6238384Sjkim
7238384Sjkim   Libgomp is free software; you can redistribute it and/or modify it
8238384Sjkim   under the terms of the GNU General Public License as published by
9238384Sjkim   the Free Software Foundation; either version 3, or (at your option)
10238384Sjkim   any later version.
11238384Sjkim
12238384Sjkim   Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13238384Sjkim   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14238384Sjkim   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15238384Sjkim   more details.
16238384Sjkim
17238384Sjkim   Under Section 7 of GPL version 3, you are granted additional
18238384Sjkim   permissions described in the GCC Runtime Library Exception, version
19238384Sjkim   3.1, as published by the Free Software Foundation.
20238384Sjkim
21238384Sjkim   You should have received a copy of the GNU General Public License and
22238384Sjkim   a copy of the GCC Runtime Library Exception along with this program;
23238384Sjkim   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24238384Sjkim   <http://www.gnu.org/licenses/>.  */
25238384Sjkim
26238384Sjkim/* This file contains wrappers for the system allocation routines.  Most
27238384Sjkim   places in the OpenMP API do not make any provision for failure, so in
28238384Sjkim   general we cannot allow memory allocation to fail.  */
29238384Sjkim
30238384Sjkim#define _GNU_SOURCE
31238384Sjkim#include "libgomp.h"
32238384Sjkim#include <stdlib.h>
33238384Sjkim
34238384Sjkim
35238384Sjkimvoid *
36238384Sjkimgomp_malloc (size_t size)
37238384Sjkim{
38238384Sjkim  void *ret = malloc (size);
39238384Sjkim  if (ret == NULL)
40238384Sjkim    gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
41238384Sjkim  return ret;
42238384Sjkim}
43238384Sjkim
44238384Sjkimvoid *
45238384Sjkimgomp_malloc_cleared (size_t size)
46238384Sjkim{
47238384Sjkim  void *ret = calloc (1, size);
48238384Sjkim  if (ret == NULL)
49238384Sjkim    gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
50238384Sjkim  return ret;
51238384Sjkim}
52238384Sjkim
53238384Sjkimvoid *
54238384Sjkimgomp_realloc (void *old, size_t size)
55238384Sjkim{
56238384Sjkim  void *ret = realloc (old, size);
57238384Sjkim  if (ret == NULL)
58238384Sjkim    gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
59238384Sjkim  return ret;
60238384Sjkim}
61238384Sjkim
62238384Sjkimvoid *
63238384Sjkimgomp_aligned_alloc (size_t al, size_t size)
64296341Sdelphij{
65296341Sdelphij  void *ret;
66238384Sjkim  if (al < sizeof (void *))
67238384Sjkim    al = sizeof (void *);
68238384Sjkim#ifdef HAVE_ALIGNED_ALLOC
69238384Sjkim  ret = aligned_alloc (al, size);
70238384Sjkim#elif defined(HAVE__ALIGNED_MALLOC)
71238384Sjkim  ret = _aligned_malloc (size, al);
72238384Sjkim#elif defined(HAVE_POSIX_MEMALIGN)
73238384Sjkim  if (posix_memalign (&ret, al, size) != 0)
74238384Sjkim    ret = NULL;
75238384Sjkim#elif defined(HAVE_MEMALIGN)
76238384Sjkim  {
77238384Sjkim    extern void *memalign (size_t, size_t);
78238384Sjkim    ret = memalign (al, size);
79238384Sjkim  }
80238384Sjkim#else
81238384Sjkim  ret = NULL;
82238384Sjkim  if ((al & (al - 1)) == 0 && size)
83238384Sjkim    {
84238384Sjkim      void *p = malloc (size + al);
85238384Sjkim      if (p)
86238384Sjkim	{
87238384Sjkim	  void *ap = (void *) (((uintptr_t) p + al) & -al);
88238384Sjkim	  ((void **) ap)[-1] = p;
89238384Sjkim	  ret = ap;
90238384Sjkim	}
91238384Sjkim    }
92238384Sjkim#endif
93238384Sjkim  if (ret == NULL)
94238384Sjkim    gomp_fatal ("Out of memory allocating %lu bytes", (unsigned long) size);
95238384Sjkim  return ret;
96238384Sjkim}
97238384Sjkim
98238384Sjkimvoid
99238384Sjkimgomp_aligned_free (void *ptr)
100238384Sjkim{
101#ifdef GOMP_HAVE_EFFICIENT_ALIGNED_ALLOC
102  free (ptr);
103#else
104  if (ptr)
105    free (((void **) ptr)[-1]);
106#endif
107}
108