annotate src/fftw-3.3.8/libbench2/util.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 d0c2a83c1364
children
rev   line source
Chris@82 1 /*
Chris@82 2 * Copyright (c) 2000 Matteo Frigo
Chris@82 3 * Copyright (c) 2000 Massachusetts Institute of Technology
Chris@82 4 *
Chris@82 5 * This program is free software; you can redistribute it and/or modify
Chris@82 6 * it under the terms of the GNU General Public License as published by
Chris@82 7 * the Free Software Foundation; either version 2 of the License, or
Chris@82 8 * (at your option) any later version.
Chris@82 9 *
Chris@82 10 * This program is distributed in the hope that it will be useful,
Chris@82 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@82 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@82 13 * GNU General Public License for more details.
Chris@82 14 *
Chris@82 15 * You should have received a copy of the GNU General Public License
Chris@82 16 * along with this program; if not, write to the Free Software
Chris@82 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@82 18 *
Chris@82 19 */
Chris@82 20
Chris@82 21 #include "libbench2/bench.h"
Chris@82 22 #include <stdlib.h>
Chris@82 23 #include <stdio.h>
Chris@82 24 #include <stddef.h>
Chris@82 25 #include <math.h>
Chris@82 26
Chris@82 27 #if defined(HAVE_MALLOC_H)
Chris@82 28 # include <malloc.h>
Chris@82 29 #endif
Chris@82 30
Chris@82 31 #if defined(HAVE_DECL_MEMALIGN) && !HAVE_DECL_MEMALIGN
Chris@82 32 extern void *memalign(size_t, size_t);
Chris@82 33 #endif
Chris@82 34
Chris@82 35 #if defined(HAVE_DECL_POSIX_MEMALIGN) && !HAVE_DECL_POSIX_MEMALIGN
Chris@82 36 extern int posix_memalign(void **, size_t, size_t);
Chris@82 37 #endif
Chris@82 38
Chris@82 39 void bench_assertion_failed(const char *s, int line, const char *file)
Chris@82 40 {
Chris@82 41 ovtpvt_err("bench: %s:%d: assertion failed: %s\n", file, line, s);
Chris@82 42 bench_exit(EXIT_FAILURE);
Chris@82 43 }
Chris@82 44
Chris@82 45 #ifdef HAVE_DRAND48
Chris@82 46 # if defined(HAVE_DECL_DRAND48) && !HAVE_DECL_DRAND48
Chris@82 47 extern double drand48(void);
Chris@82 48 # endif
Chris@82 49 double bench_drand(void)
Chris@82 50 {
Chris@82 51 return drand48() - 0.5;
Chris@82 52 }
Chris@82 53 # if defined(HAVE_DECL_SRAND48) && !HAVE_DECL_SRAND48
Chris@82 54 extern void srand48(long);
Chris@82 55 # endif
Chris@82 56 void bench_srand(int seed)
Chris@82 57 {
Chris@82 58 srand48(seed);
Chris@82 59 }
Chris@82 60 #else
Chris@82 61 double bench_drand(void)
Chris@82 62 {
Chris@82 63 double d = rand();
Chris@82 64 return (d / (double) RAND_MAX) - 0.5;
Chris@82 65 }
Chris@82 66 void bench_srand(int seed)
Chris@82 67 {
Chris@82 68 srand(seed);
Chris@82 69 }
Chris@82 70 #endif
Chris@82 71
Chris@82 72 /**********************************************************
Chris@82 73 * DEBUGGING CODE
Chris@82 74 **********************************************************/
Chris@82 75 #ifdef BENCH_DEBUG
Chris@82 76 static int bench_malloc_cnt = 0;
Chris@82 77
Chris@82 78 /*
Chris@82 79 * debugging malloc/free. Initialize every malloced and freed area to
Chris@82 80 * random values, just to make sure we are not using uninitialized
Chris@82 81 * pointers. Also check for writes past the ends of allocated blocks,
Chris@82 82 * and a couple of other things.
Chris@82 83 *
Chris@82 84 * This code is a quick and dirty hack -- use at your own risk.
Chris@82 85 */
Chris@82 86
Chris@82 87 static int bench_malloc_total = 0, bench_malloc_max = 0, bench_malloc_cnt_max = 0;
Chris@82 88
Chris@82 89 #define MAGIC ((size_t)0xABadCafe)
Chris@82 90 #define PAD_FACTOR 2
Chris@82 91 #define TWO_SIZE_T (2 * sizeof(size_t))
Chris@82 92
Chris@82 93 #define VERBOSE_ALLOCATION 0
Chris@82 94
Chris@82 95 #if VERBOSE_ALLOCATION
Chris@82 96 #define WHEN_VERBOSE(a) a
Chris@82 97 #else
Chris@82 98 #define WHEN_VERBOSE(a)
Chris@82 99 #endif
Chris@82 100
Chris@82 101 void *bench_malloc(size_t n)
Chris@82 102 {
Chris@82 103 char *p;
Chris@82 104 size_t i;
Chris@82 105
Chris@82 106 bench_malloc_total += n;
Chris@82 107
Chris@82 108 if (bench_malloc_total > bench_malloc_max)
Chris@82 109 bench_malloc_max = bench_malloc_total;
Chris@82 110
Chris@82 111 p = (char *) malloc(PAD_FACTOR * n + TWO_SIZE_T);
Chris@82 112 BENCH_ASSERT(p);
Chris@82 113
Chris@82 114 /* store the size in a known position */
Chris@82 115 ((size_t *) p)[0] = n;
Chris@82 116 ((size_t *) p)[1] = MAGIC;
Chris@82 117 for (i = 0; i < PAD_FACTOR * n; i++)
Chris@82 118 p[i + TWO_SIZE_T] = (char) (i ^ 0xDEADBEEF);
Chris@82 119
Chris@82 120 ++bench_malloc_cnt;
Chris@82 121
Chris@82 122 if (bench_malloc_cnt > bench_malloc_cnt_max)
Chris@82 123 bench_malloc_cnt_max = bench_malloc_cnt;
Chris@82 124
Chris@82 125 /* skip the size we stored previously */
Chris@82 126 return (void *) (p + TWO_SIZE_T);
Chris@82 127 }
Chris@82 128
Chris@82 129 void bench_free(void *p)
Chris@82 130 {
Chris@82 131 char *q;
Chris@82 132
Chris@82 133 BENCH_ASSERT(p);
Chris@82 134
Chris@82 135 q = ((char *) p) - TWO_SIZE_T;
Chris@82 136 BENCH_ASSERT(q);
Chris@82 137
Chris@82 138 {
Chris@82 139 size_t n = ((size_t *) q)[0];
Chris@82 140 size_t magic = ((size_t *) q)[1];
Chris@82 141 size_t i;
Chris@82 142
Chris@82 143 ((size_t *) q)[0] = 0; /* set to zero to detect duplicate free's */
Chris@82 144
Chris@82 145 BENCH_ASSERT(magic == MAGIC);
Chris@82 146 ((size_t *) q)[1] = ~MAGIC;
Chris@82 147
Chris@82 148 bench_malloc_total -= n;
Chris@82 149 BENCH_ASSERT(bench_malloc_total >= 0);
Chris@82 150
Chris@82 151 /* check for writing past end of array: */
Chris@82 152 for (i = n; i < PAD_FACTOR * n; ++i)
Chris@82 153 if (q[i + TWO_SIZE_T] != (char) (i ^ 0xDEADBEEF)) {
Chris@82 154 BENCH_ASSERT(0 /* array bounds overwritten */);
Chris@82 155 }
Chris@82 156 for (i = 0; i < PAD_FACTOR * n; ++i)
Chris@82 157 q[i + TWO_SIZE_T] = (char) (i ^ 0xBEEFDEAD);
Chris@82 158
Chris@82 159 --bench_malloc_cnt;
Chris@82 160
Chris@82 161 BENCH_ASSERT(bench_malloc_cnt >= 0);
Chris@82 162
Chris@82 163 BENCH_ASSERT(
Chris@82 164 (bench_malloc_cnt == 0 && bench_malloc_total == 0) ||
Chris@82 165 (bench_malloc_cnt > 0 && bench_malloc_total > 0));
Chris@82 166
Chris@82 167 free(q);
Chris@82 168 }
Chris@82 169 }
Chris@82 170
Chris@82 171 #else
Chris@82 172 /**********************************************************
Chris@82 173 * NON DEBUGGING CODE
Chris@82 174 **********************************************************/
Chris@82 175 /* production version, no hacks */
Chris@82 176
Chris@82 177 #define MIN_ALIGNMENT 128 /* must be power of two */
Chris@82 178
Chris@82 179 #define real_free free /* memalign and malloc use ordinary free */
Chris@82 180
Chris@82 181 void *bench_malloc(size_t n)
Chris@82 182 {
Chris@82 183 void *p;
Chris@82 184 if (n == 0) n = 1;
Chris@82 185
Chris@82 186 #if defined(WITH_OUR_MALLOC)
Chris@82 187 /* Our own aligned malloc/free. Assumes sizeof(void*) is
Chris@82 188 a power of two <= 8 and that malloc is at least
Chris@82 189 sizeof(void*)-aligned. Assumes size_t = uintptr_t. */
Chris@82 190 {
Chris@82 191 void *p0;
Chris@82 192 if ((p0 = malloc(n + MIN_ALIGNMENT))) {
Chris@82 193 p = (void *) (((size_t) p0 + MIN_ALIGNMENT) & (~((size_t) (MIN_ALIGNMENT - 1))));
Chris@82 194 *((void **) p - 1) = p0;
Chris@82 195 }
Chris@82 196 else
Chris@82 197 p = (void *) 0;
Chris@82 198 }
Chris@82 199 #elif defined(HAVE_MEMALIGN)
Chris@82 200 p = memalign(MIN_ALIGNMENT, n);
Chris@82 201 #elif defined(HAVE_POSIX_MEMALIGN)
Chris@82 202 /* note: posix_memalign is broken in glibc 2.2.5: it constrains
Chris@82 203 the size, not the alignment, to be (power of two) * sizeof(void*).
Chris@82 204 The bug seems to have been fixed as of glibc 2.3.1. */
Chris@82 205 if (posix_memalign(&p, MIN_ALIGNMENT, n))
Chris@82 206 p = (void*) 0;
Chris@82 207 #elif defined(__ICC) || defined(__INTEL_COMPILER) || defined(HAVE__MM_MALLOC)
Chris@82 208 /* Intel's C compiler defines _mm_malloc and _mm_free intrinsics */
Chris@82 209 p = (void *) _mm_malloc(n, MIN_ALIGNMENT);
Chris@82 210 # undef real_free
Chris@82 211 # define real_free _mm_free
Chris@82 212 #else
Chris@82 213 p = malloc(n);
Chris@82 214 #endif
Chris@82 215
Chris@82 216 BENCH_ASSERT(p);
Chris@82 217 return p;
Chris@82 218 }
Chris@82 219
Chris@82 220 void bench_free(void *p)
Chris@82 221 {
Chris@82 222 #ifdef WITH_OUR_MALLOC
Chris@82 223 if (p) free(*((void **) p - 1));
Chris@82 224 #else
Chris@82 225 real_free(p);
Chris@82 226 #endif
Chris@82 227 }
Chris@82 228
Chris@82 229 #endif
Chris@82 230
Chris@82 231 void bench_free0(void *p)
Chris@82 232 {
Chris@82 233 if (p) bench_free(p);
Chris@82 234 }