annotate src/fftw-3.3.5/kernel/kalloc.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 2cd0e3b3e1fd
children
rev   line source
Chris@42 1 /*
Chris@42 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@42 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@42 4 *
Chris@42 5 * This program is free software; you can redistribute it and/or modify
Chris@42 6 * it under the terms of the GNU General Public License as published by
Chris@42 7 * the Free Software Foundation; either version 2 of the License, or
Chris@42 8 * (at your option) any later version.
Chris@42 9 *
Chris@42 10 * This program is distributed in the hope that it will be useful,
Chris@42 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@42 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@42 13 * GNU General Public License for more details.
Chris@42 14 *
Chris@42 15 * You should have received a copy of the GNU General Public License
Chris@42 16 * along with this program; if not, write to the Free Software
Chris@42 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@42 18 *
Chris@42 19 */
Chris@42 20
Chris@42 21
Chris@42 22 #include "ifftw.h"
Chris@42 23
Chris@42 24 #if defined(HAVE_MALLOC_H)
Chris@42 25 # include <malloc.h>
Chris@42 26 #endif
Chris@42 27
Chris@42 28 /* ``kernel'' malloc(), with proper memory alignment */
Chris@42 29
Chris@42 30 #if defined(HAVE_DECL_MEMALIGN) && !HAVE_DECL_MEMALIGN
Chris@42 31 extern void *memalign(size_t, size_t);
Chris@42 32 #endif
Chris@42 33
Chris@42 34 #if defined(HAVE_DECL_POSIX_MEMALIGN) && !HAVE_DECL_POSIX_MEMALIGN
Chris@42 35 extern int posix_memalign(void **, size_t, size_t);
Chris@42 36 #endif
Chris@42 37
Chris@42 38 #if defined(macintosh) /* MacOS 9 */
Chris@42 39 # include <Multiprocessing.h>
Chris@42 40 #endif
Chris@42 41
Chris@42 42 #define real_free free /* memalign and malloc use ordinary free */
Chris@42 43
Chris@42 44 #define IS_POWER_OF_TWO(n) (((n) > 0) && (((n) & ((n) - 1)) == 0))
Chris@42 45 #if defined(WITH_OUR_MALLOC) && (MIN_ALIGNMENT >= 8) && IS_POWER_OF_TWO(MIN_ALIGNMENT)
Chris@42 46 /* Our own MIN_ALIGNMENT-aligned malloc/free. Assumes sizeof(void*) is a
Chris@42 47 power of two <= 8 and that malloc is at least sizeof(void*)-aligned.
Chris@42 48
Chris@42 49 The main reason for this routine is that, as of this writing,
Chris@42 50 Windows does not include any aligned allocation routines in its
Chris@42 51 system libraries, and instead provides an implementation with a
Chris@42 52 Visual C++ "Processor Pack" that you have to statically link into
Chris@42 53 your program. We do not want to require users to have VC++
Chris@42 54 (e.g. gcc/MinGW should be fine). Our code should be at least as good
Chris@42 55 as the MS _aligned_malloc, in any case, according to second-hand
Chris@42 56 reports of the algorithm it employs (also based on plain malloc). */
Chris@42 57 static void *our_malloc(size_t n)
Chris@42 58 {
Chris@42 59 void *p0, *p;
Chris@42 60 if (!(p0 = malloc(n + MIN_ALIGNMENT))) return (void *) 0;
Chris@42 61 p = (void *) (((uintptr_t) p0 + MIN_ALIGNMENT) & (~((uintptr_t) (MIN_ALIGNMENT - 1))));
Chris@42 62 *((void **) p - 1) = p0;
Chris@42 63 return p;
Chris@42 64 }
Chris@42 65 static void our_free(void *p)
Chris@42 66 {
Chris@42 67 if (p) free(*((void **) p - 1));
Chris@42 68 }
Chris@42 69 #endif
Chris@42 70
Chris@42 71 void *X(kernel_malloc)(size_t n)
Chris@42 72 {
Chris@42 73 void *p;
Chris@42 74
Chris@42 75 #if defined(MIN_ALIGNMENT)
Chris@42 76
Chris@42 77 # if defined(WITH_OUR_MALLOC)
Chris@42 78 p = our_malloc(n);
Chris@42 79 # undef real_free
Chris@42 80 # define real_free our_free
Chris@42 81
Chris@42 82 # elif defined(__FreeBSD__) && (MIN_ALIGNMENT <= 16)
Chris@42 83 /* FreeBSD does not have memalign, but its malloc is 16-byte aligned. */
Chris@42 84 p = malloc(n);
Chris@42 85
Chris@42 86 # elif (defined(__MACOSX__) || defined(__APPLE__)) && (MIN_ALIGNMENT <= 16)
Chris@42 87 /* MacOS X malloc is already 16-byte aligned */
Chris@42 88 p = malloc(n);
Chris@42 89
Chris@42 90 # elif defined(HAVE_MEMALIGN)
Chris@42 91 p = memalign(MIN_ALIGNMENT, n);
Chris@42 92
Chris@42 93 # elif defined(HAVE_POSIX_MEMALIGN)
Chris@42 94 /* note: posix_memalign is broken in glibc 2.2.5: it constrains
Chris@42 95 the size, not the alignment, to be (power of two) * sizeof(void*).
Chris@42 96 The bug seems to have been fixed as of glibc 2.3.1. */
Chris@42 97 if (posix_memalign(&p, MIN_ALIGNMENT, n))
Chris@42 98 p = (void*) 0;
Chris@42 99
Chris@42 100 # elif defined(__ICC) || defined(__INTEL_COMPILER) || defined(HAVE__MM_MALLOC)
Chris@42 101 /* Intel's C compiler defines _mm_malloc and _mm_free intrinsics */
Chris@42 102 p = (void *) _mm_malloc(n, MIN_ALIGNMENT);
Chris@42 103 # undef real_free
Chris@42 104 # define real_free _mm_free
Chris@42 105
Chris@42 106 # elif defined(_MSC_VER)
Chris@42 107 /* MS Visual C++ 6.0 with a "Processor Pack" supports SIMD
Chris@42 108 and _aligned_malloc/free (uses malloc.h) */
Chris@42 109 p = (void *) _aligned_malloc(n, MIN_ALIGNMENT);
Chris@42 110 # undef real_free
Chris@42 111 # define real_free _aligned_free
Chris@42 112
Chris@42 113 # elif defined(macintosh) /* MacOS 9 */
Chris@42 114 p = (void *) MPAllocateAligned(n,
Chris@42 115 # if MIN_ALIGNMENT == 8
Chris@42 116 kMPAllocate8ByteAligned,
Chris@42 117 # elif MIN_ALIGNMENT == 16
Chris@42 118 kMPAllocate16ByteAligned,
Chris@42 119 # elif MIN_ALIGNMENT == 32
Chris@42 120 kMPAllocate32ByteAligned,
Chris@42 121 # else
Chris@42 122 # error "Unknown alignment for MPAllocateAligned"
Chris@42 123 # endif
Chris@42 124 0);
Chris@42 125 # undef real_free
Chris@42 126 # define real_free MPFree
Chris@42 127
Chris@42 128 # else
Chris@42 129 /* Add your machine here and send a patch to fftw@fftw.org
Chris@42 130 or (e.g. for Windows) configure --with-our-malloc */
Chris@42 131 # error "Don't know how to malloc() aligned memory ... try configuring --with-our-malloc"
Chris@42 132 # endif
Chris@42 133
Chris@42 134 #else /* !defined(MIN_ALIGNMENT) */
Chris@42 135 p = malloc(n);
Chris@42 136 #endif
Chris@42 137
Chris@42 138 return p;
Chris@42 139 }
Chris@42 140
Chris@42 141 void X(kernel_free)(void *p)
Chris@42 142 {
Chris@42 143 real_free(p);
Chris@42 144 }