mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
186
memory/jemalloc/src/test/include/test/SFMT-alti.h
Normal file
186
memory/jemalloc/src/test/include/test/SFMT-alti.h
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* @file SFMT-alti.h
|
||||
*
|
||||
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
|
||||
* pseudorandom number generator
|
||||
*
|
||||
* @author Mutsuo Saito (Hiroshima University)
|
||||
* @author Makoto Matsumoto (Hiroshima University)
|
||||
*
|
||||
* Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* The new BSD License is applied to this software.
|
||||
* see LICENSE.txt
|
||||
*/
|
||||
|
||||
#ifndef SFMT_ALTI_H
|
||||
#define SFMT_ALTI_H
|
||||
|
||||
/**
|
||||
* This function represents the recursion formula in AltiVec and BIG ENDIAN.
|
||||
* @param a a 128-bit part of the interal state array
|
||||
* @param b a 128-bit part of the interal state array
|
||||
* @param c a 128-bit part of the interal state array
|
||||
* @param d a 128-bit part of the interal state array
|
||||
* @return output
|
||||
*/
|
||||
JEMALLOC_ALWAYS_INLINE
|
||||
vector unsigned int vec_recursion(vector unsigned int a,
|
||||
vector unsigned int b,
|
||||
vector unsigned int c,
|
||||
vector unsigned int d) {
|
||||
|
||||
const vector unsigned int sl1 = ALTI_SL1;
|
||||
const vector unsigned int sr1 = ALTI_SR1;
|
||||
#ifdef ONLY64
|
||||
const vector unsigned int mask = ALTI_MSK64;
|
||||
const vector unsigned char perm_sl = ALTI_SL2_PERM64;
|
||||
const vector unsigned char perm_sr = ALTI_SR2_PERM64;
|
||||
#else
|
||||
const vector unsigned int mask = ALTI_MSK;
|
||||
const vector unsigned char perm_sl = ALTI_SL2_PERM;
|
||||
const vector unsigned char perm_sr = ALTI_SR2_PERM;
|
||||
#endif
|
||||
vector unsigned int v, w, x, y, z;
|
||||
x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);
|
||||
v = a;
|
||||
y = vec_sr(b, sr1);
|
||||
z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);
|
||||
w = vec_sl(d, sl1);
|
||||
z = vec_xor(z, w);
|
||||
y = vec_and(y, mask);
|
||||
v = vec_xor(v, x);
|
||||
z = vec_xor(z, y);
|
||||
z = vec_xor(z, v);
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the internal state array with pseudorandom
|
||||
* integers.
|
||||
*/
|
||||
JEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) {
|
||||
int i;
|
||||
vector unsigned int r, r1, r2;
|
||||
|
||||
r1 = ctx->sfmt[N - 2].s;
|
||||
r2 = ctx->sfmt[N - 1].s;
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2);
|
||||
ctx->sfmt[i].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1 - N].s, r1, r2);
|
||||
ctx->sfmt[i].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the user-specified array with pseudorandom
|
||||
* integers.
|
||||
*
|
||||
* @param array an 128-bit array to be filled by pseudorandom numbers.
|
||||
* @param size number of 128-bit pesudorandom numbers to be generated.
|
||||
*/
|
||||
JEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {
|
||||
int i, j;
|
||||
vector unsigned int r, r1, r2;
|
||||
|
||||
r1 = ctx->sfmt[N - 2].s;
|
||||
r2 = ctx->sfmt[N - 1].s;
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2);
|
||||
array[i].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
r = vec_recursion(ctx->sfmt[i].s, array[i + POS1 - N].s, r1, r2);
|
||||
array[i].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
/* main loop */
|
||||
for (; i < size - N; i++) {
|
||||
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
|
||||
array[i].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (j = 0; j < 2 * N - size; j++) {
|
||||
ctx->sfmt[j].s = array[j + size - N].s;
|
||||
}
|
||||
for (; i < size; i++) {
|
||||
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
|
||||
array[i].s = r;
|
||||
ctx->sfmt[j++].s = r;
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ONLY64
|
||||
#if defined(__APPLE__)
|
||||
#define ALTI_SWAP (vector unsigned char) \
|
||||
(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)
|
||||
#else
|
||||
#define ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}
|
||||
#endif
|
||||
/**
|
||||
* This function swaps high and low 32-bit of 64-bit integers in user
|
||||
* specified array.
|
||||
*
|
||||
* @param array an 128-bit array to be swaped.
|
||||
* @param size size of 128-bit array.
|
||||
*/
|
||||
JEMALLOC_INLINE void swap(w128_t *array, int size) {
|
||||
int i;
|
||||
const vector unsigned char perm = ALTI_SWAP;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
132
memory/jemalloc/src/test/include/test/SFMT-params.h
Normal file
132
memory/jemalloc/src/test/include/test/SFMT-params.h
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS_H
|
||||
#define SFMT_PARAMS_H
|
||||
|
||||
#if !defined(MEXP)
|
||||
#ifdef __GNUC__
|
||||
#warning "MEXP is not defined. I assume MEXP is 19937."
|
||||
#endif
|
||||
#define MEXP 19937
|
||||
#endif
|
||||
/*-----------------
|
||||
BASIC DEFINITIONS
|
||||
-----------------*/
|
||||
/** Mersenne Exponent. The period of the sequence
|
||||
* is a multiple of 2^MEXP-1.
|
||||
* #define MEXP 19937 */
|
||||
/** SFMT generator has an internal state array of 128-bit integers,
|
||||
* and N is its size. */
|
||||
#define N (MEXP / 128 + 1)
|
||||
/** N32 is the size of internal state array when regarded as an array
|
||||
* of 32-bit integers.*/
|
||||
#define N32 (N * 4)
|
||||
/** N64 is the size of internal state array when regarded as an array
|
||||
* of 64-bit integers.*/
|
||||
#define N64 (N * 2)
|
||||
|
||||
/*----------------------
|
||||
the parameters of SFMT
|
||||
following definitions are in paramsXXXX.h file.
|
||||
----------------------*/
|
||||
/** the pick up position of the array.
|
||||
#define POS1 122
|
||||
*/
|
||||
|
||||
/** the parameter of shift left as four 32-bit registers.
|
||||
#define SL1 18
|
||||
*/
|
||||
|
||||
/** the parameter of shift left as one 128-bit register.
|
||||
* The 128-bit integer is shifted by (SL2 * 8) bits.
|
||||
#define SL2 1
|
||||
*/
|
||||
|
||||
/** the parameter of shift right as four 32-bit registers.
|
||||
#define SR1 11
|
||||
*/
|
||||
|
||||
/** the parameter of shift right as one 128-bit register.
|
||||
* The 128-bit integer is shifted by (SL2 * 8) bits.
|
||||
#define SR2 1
|
||||
*/
|
||||
|
||||
/** A bitmask, used in the recursion. These parameters are introduced
|
||||
* to break symmetry of SIMD.
|
||||
#define MSK1 0xdfffffefU
|
||||
#define MSK2 0xddfecb7fU
|
||||
#define MSK3 0xbffaffffU
|
||||
#define MSK4 0xbffffff6U
|
||||
*/
|
||||
|
||||
/** These definitions are part of a 128-bit period certification vector.
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0xc98e126aU
|
||||
*/
|
||||
|
||||
#if MEXP == 607
|
||||
#include "test/SFMT-params607.h"
|
||||
#elif MEXP == 1279
|
||||
#include "test/SFMT-params1279.h"
|
||||
#elif MEXP == 2281
|
||||
#include "test/SFMT-params2281.h"
|
||||
#elif MEXP == 4253
|
||||
#include "test/SFMT-params4253.h"
|
||||
#elif MEXP == 11213
|
||||
#include "test/SFMT-params11213.h"
|
||||
#elif MEXP == 19937
|
||||
#include "test/SFMT-params19937.h"
|
||||
#elif MEXP == 44497
|
||||
#include "test/SFMT-params44497.h"
|
||||
#elif MEXP == 86243
|
||||
#include "test/SFMT-params86243.h"
|
||||
#elif MEXP == 132049
|
||||
#include "test/SFMT-params132049.h"
|
||||
#elif MEXP == 216091
|
||||
#include "test/SFMT-params216091.h"
|
||||
#else
|
||||
#ifdef __GNUC__
|
||||
#error "MEXP is not valid."
|
||||
#undef MEXP
|
||||
#else
|
||||
#undef MEXP
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SFMT_PARAMS_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params11213.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params11213.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS11213_H
|
||||
#define SFMT_PARAMS11213_H
|
||||
|
||||
#define POS1 68
|
||||
#define SL1 14
|
||||
#define SL2 3
|
||||
#define SR1 7
|
||||
#define SR2 3
|
||||
#define MSK1 0xeffff7fbU
|
||||
#define MSK2 0xffffffefU
|
||||
#define MSK3 0xdfdfbfffU
|
||||
#define MSK4 0x7fffdbfdU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0xe8148000U
|
||||
#define PARITY4 0xd0c7afa3U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
|
||||
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
|
||||
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
|
||||
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
|
||||
|
||||
#endif /* SFMT_PARAMS11213_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params1279.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params1279.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS1279_H
|
||||
#define SFMT_PARAMS1279_H
|
||||
|
||||
#define POS1 7
|
||||
#define SL1 14
|
||||
#define SL2 3
|
||||
#define SR1 5
|
||||
#define SR2 1
|
||||
#define MSK1 0xf7fefffdU
|
||||
#define MSK2 0x7fefcfffU
|
||||
#define MSK3 0xaff3ef3fU
|
||||
#define MSK4 0xb5ffff7fU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0x20000000U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
|
||||
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
|
||||
|
||||
#endif /* SFMT_PARAMS1279_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params132049.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params132049.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS132049_H
|
||||
#define SFMT_PARAMS132049_H
|
||||
|
||||
#define POS1 110
|
||||
#define SL1 19
|
||||
#define SL2 1
|
||||
#define SR1 21
|
||||
#define SR2 1
|
||||
#define MSK1 0xffffbb5fU
|
||||
#define MSK2 0xfb6ebf95U
|
||||
#define MSK3 0xfffefffaU
|
||||
#define MSK4 0xcff77fffU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0xcb520000U
|
||||
#define PARITY4 0xc7e91c7dU
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
|
||||
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
|
||||
|
||||
#endif /* SFMT_PARAMS132049_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params19937.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params19937.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS19937_H
|
||||
#define SFMT_PARAMS19937_H
|
||||
|
||||
#define POS1 122
|
||||
#define SL1 18
|
||||
#define SL2 1
|
||||
#define SR1 11
|
||||
#define SR2 1
|
||||
#define MSK1 0xdfffffefU
|
||||
#define MSK2 0xddfecb7fU
|
||||
#define MSK3 0xbffaffffU
|
||||
#define MSK4 0xbffffff6U
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0x13c9e684U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
|
||||
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
|
||||
|
||||
#endif /* SFMT_PARAMS19937_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params216091.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params216091.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS216091_H
|
||||
#define SFMT_PARAMS216091_H
|
||||
|
||||
#define POS1 627
|
||||
#define SL1 11
|
||||
#define SL2 3
|
||||
#define SR1 10
|
||||
#define SR2 1
|
||||
#define MSK1 0xbff7bff7U
|
||||
#define MSK2 0xbfffffffU
|
||||
#define MSK3 0xbffffa7fU
|
||||
#define MSK4 0xffddfbfbU
|
||||
#define PARITY1 0xf8000001U
|
||||
#define PARITY2 0x89e80709U
|
||||
#define PARITY3 0x3bd2b64bU
|
||||
#define PARITY4 0x0c64b1e4U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
|
||||
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
|
||||
|
||||
#endif /* SFMT_PARAMS216091_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params2281.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params2281.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS2281_H
|
||||
#define SFMT_PARAMS2281_H
|
||||
|
||||
#define POS1 12
|
||||
#define SL1 19
|
||||
#define SL2 1
|
||||
#define SR1 5
|
||||
#define SR2 1
|
||||
#define MSK1 0xbff7ffbfU
|
||||
#define MSK2 0xfdfffffeU
|
||||
#define MSK3 0xf7ffef7fU
|
||||
#define MSK4 0xf2f7cbbfU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0x41dfa600U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
|
||||
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
|
||||
|
||||
#endif /* SFMT_PARAMS2281_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params4253.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params4253.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS4253_H
|
||||
#define SFMT_PARAMS4253_H
|
||||
|
||||
#define POS1 17
|
||||
#define SL1 20
|
||||
#define SL2 1
|
||||
#define SR1 7
|
||||
#define SR2 1
|
||||
#define MSK1 0x9f7bffffU
|
||||
#define MSK2 0x9fffff5fU
|
||||
#define MSK3 0x3efffffbU
|
||||
#define MSK4 0xfffff7bbU
|
||||
#define PARITY1 0xa8000001U
|
||||
#define PARITY2 0xaf5390a3U
|
||||
#define PARITY3 0xb740b3f8U
|
||||
#define PARITY4 0x6c11486dU
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
|
||||
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
|
||||
|
||||
#endif /* SFMT_PARAMS4253_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params44497.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params44497.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS44497_H
|
||||
#define SFMT_PARAMS44497_H
|
||||
|
||||
#define POS1 330
|
||||
#define SL1 5
|
||||
#define SL2 3
|
||||
#define SR1 9
|
||||
#define SR2 3
|
||||
#define MSK1 0xeffffffbU
|
||||
#define MSK2 0xdfbebfffU
|
||||
#define MSK3 0xbfbf7befU
|
||||
#define MSK4 0x9ffd7bffU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0xa3ac4000U
|
||||
#define PARITY4 0xecc1327aU
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
|
||||
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
|
||||
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
|
||||
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
|
||||
|
||||
#endif /* SFMT_PARAMS44497_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params607.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params607.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS607_H
|
||||
#define SFMT_PARAMS607_H
|
||||
|
||||
#define POS1 2
|
||||
#define SL1 15
|
||||
#define SL2 3
|
||||
#define SR1 13
|
||||
#define SR2 3
|
||||
#define MSK1 0xfdff37ffU
|
||||
#define MSK2 0xef7f3f7dU
|
||||
#define MSK3 0xff777b7dU
|
||||
#define MSK4 0x7ff7fb2fU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0x5986f054U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
|
||||
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
|
||||
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
|
||||
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
|
||||
|
||||
#endif /* SFMT_PARAMS607_H */
|
||||
81
memory/jemalloc/src/test/include/test/SFMT-params86243.h
Normal file
81
memory/jemalloc/src/test/include/test/SFMT-params86243.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef SFMT_PARAMS86243_H
|
||||
#define SFMT_PARAMS86243_H
|
||||
|
||||
#define POS1 366
|
||||
#define SL1 6
|
||||
#define SL2 7
|
||||
#define SR1 19
|
||||
#define SR2 1
|
||||
#define MSK1 0xfdbffbffU
|
||||
#define MSK2 0xbff7ff3fU
|
||||
#define MSK3 0xfd77efffU
|
||||
#define MSK4 0xbf9ff3ffU
|
||||
#define PARITY1 0x00000001U
|
||||
#define PARITY2 0x00000000U
|
||||
#define PARITY3 0x00000000U
|
||||
#define PARITY4 0xe9528d85U
|
||||
|
||||
|
||||
/* PARAMETERS FOR ALTIVEC */
|
||||
#if defined(__APPLE__) /* For OSX */
|
||||
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
|
||||
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
|
||||
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
|
||||
#define ALTI_MSK64 \
|
||||
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
|
||||
#define ALTI_SL2_PERM \
|
||||
(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
|
||||
#define ALTI_SL2_PERM64 \
|
||||
(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
|
||||
#define ALTI_SR2_PERM \
|
||||
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
|
||||
#define ALTI_SR2_PERM64 \
|
||||
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
|
||||
#else /* For OTHER OSs(Linux?) */
|
||||
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
|
||||
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
|
||||
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
|
||||
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
|
||||
#define ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
|
||||
#define ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
|
||||
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
|
||||
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
|
||||
#endif /* For OSX */
|
||||
#define IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
|
||||
|
||||
#endif /* SFMT_PARAMS86243_H */
|
||||
157
memory/jemalloc/src/test/include/test/SFMT-sse2.h
Normal file
157
memory/jemalloc/src/test/include/test/SFMT-sse2.h
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* @file SFMT-sse2.h
|
||||
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2
|
||||
*
|
||||
* @author Mutsuo Saito (Hiroshima University)
|
||||
* @author Makoto Matsumoto (Hiroshima University)
|
||||
*
|
||||
* @note We assume LITTLE ENDIAN in this file
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* The new BSD License is applied to this software, see LICENSE.txt
|
||||
*/
|
||||
|
||||
#ifndef SFMT_SSE2_H
|
||||
#define SFMT_SSE2_H
|
||||
|
||||
/**
|
||||
* This function represents the recursion formula.
|
||||
* @param a a 128-bit part of the interal state array
|
||||
* @param b a 128-bit part of the interal state array
|
||||
* @param c a 128-bit part of the interal state array
|
||||
* @param d a 128-bit part of the interal state array
|
||||
* @param mask 128-bit mask
|
||||
* @return output
|
||||
*/
|
||||
JEMALLOC_ALWAYS_INLINE __m128i mm_recursion(__m128i *a, __m128i *b,
|
||||
__m128i c, __m128i d, __m128i mask) {
|
||||
__m128i v, x, y, z;
|
||||
|
||||
x = _mm_load_si128(a);
|
||||
y = _mm_srli_epi32(*b, SR1);
|
||||
z = _mm_srli_si128(c, SR2);
|
||||
v = _mm_slli_epi32(d, SL1);
|
||||
z = _mm_xor_si128(z, x);
|
||||
z = _mm_xor_si128(z, v);
|
||||
x = _mm_slli_si128(x, SL2);
|
||||
y = _mm_and_si128(y, mask);
|
||||
z = _mm_xor_si128(z, x);
|
||||
z = _mm_xor_si128(z, y);
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the internal state array with pseudorandom
|
||||
* integers.
|
||||
*/
|
||||
JEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) {
|
||||
int i;
|
||||
__m128i r, r1, r2, mask;
|
||||
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
|
||||
|
||||
r1 = _mm_load_si128(&ctx->sfmt[N - 2].si);
|
||||
r2 = _mm_load_si128(&ctx->sfmt[N - 1].si);
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&ctx->sfmt[i].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1 - N].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&ctx->sfmt[i].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the user-specified array with pseudorandom
|
||||
* integers.
|
||||
*
|
||||
* @param array an 128-bit array to be filled by pseudorandom numbers.
|
||||
* @param size number of 128-bit pesudorandom numbers to be generated.
|
||||
*/
|
||||
JEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {
|
||||
int i, j;
|
||||
__m128i r, r1, r2, mask;
|
||||
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
|
||||
|
||||
r1 = _mm_load_si128(&ctx->sfmt[N - 2].si);
|
||||
r2 = _mm_load_si128(&ctx->sfmt[N - 1].si);
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&array[i].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
r = mm_recursion(&ctx->sfmt[i].si, &array[i + POS1 - N].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&array[i].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
/* main loop */
|
||||
for (; i < size - N; i++) {
|
||||
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&array[i].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
for (j = 0; j < 2 * N - size; j++) {
|
||||
r = _mm_load_si128(&array[j + size - N].si);
|
||||
_mm_store_si128(&ctx->sfmt[j].si, r);
|
||||
}
|
||||
for (; i < size; i++) {
|
||||
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
|
||||
mask);
|
||||
_mm_store_si128(&array[i].si, r);
|
||||
_mm_store_si128(&ctx->sfmt[j++].si, r);
|
||||
r1 = r2;
|
||||
r2 = r;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
171
memory/jemalloc/src/test/include/test/SFMT.h
Normal file
171
memory/jemalloc/src/test/include/test/SFMT.h
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* @file SFMT.h
|
||||
*
|
||||
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
|
||||
* number generator
|
||||
*
|
||||
* @author Mutsuo Saito (Hiroshima University)
|
||||
* @author Makoto Matsumoto (Hiroshima University)
|
||||
*
|
||||
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* The new BSD License is applied to this software.
|
||||
* see LICENSE.txt
|
||||
*
|
||||
* @note We assume that your system has inttypes.h. If your system
|
||||
* doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
|
||||
* and you have to define PRIu64 and PRIx64 in this file as follows:
|
||||
* @verbatim
|
||||
typedef unsigned int uint32_t
|
||||
typedef unsigned long long uint64_t
|
||||
#define PRIu64 "llu"
|
||||
#define PRIx64 "llx"
|
||||
@endverbatim
|
||||
* uint32_t must be exactly 32-bit unsigned integer type (no more, no
|
||||
* less), and uint64_t must be exactly 64-bit unsigned integer type.
|
||||
* PRIu64 and PRIx64 are used for printf function to print 64-bit
|
||||
* unsigned int and 64-bit unsigned int in hexadecimal format.
|
||||
*/
|
||||
|
||||
#ifndef SFMT_H
|
||||
#define SFMT_H
|
||||
|
||||
typedef struct sfmt_s sfmt_t;
|
||||
|
||||
uint32_t gen_rand32(sfmt_t *ctx);
|
||||
uint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit);
|
||||
uint64_t gen_rand64(sfmt_t *ctx);
|
||||
uint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit);
|
||||
void fill_array32(sfmt_t *ctx, uint32_t *array, int size);
|
||||
void fill_array64(sfmt_t *ctx, uint64_t *array, int size);
|
||||
sfmt_t *init_gen_rand(uint32_t seed);
|
||||
sfmt_t *init_by_array(uint32_t *init_key, int key_length);
|
||||
void fini_gen_rand(sfmt_t *ctx);
|
||||
const char *get_idstring(void);
|
||||
int get_min_array_size32(void);
|
||||
int get_min_array_size64(void);
|
||||
|
||||
#ifndef JEMALLOC_ENABLE_INLINE
|
||||
double to_real1(uint32_t v);
|
||||
double genrand_real1(sfmt_t *ctx);
|
||||
double to_real2(uint32_t v);
|
||||
double genrand_real2(sfmt_t *ctx);
|
||||
double to_real3(uint32_t v);
|
||||
double genrand_real3(sfmt_t *ctx);
|
||||
double to_res53(uint64_t v);
|
||||
double to_res53_mix(uint32_t x, uint32_t y);
|
||||
double genrand_res53(sfmt_t *ctx);
|
||||
double genrand_res53_mix(sfmt_t *ctx);
|
||||
#endif
|
||||
|
||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(SFMT_C_))
|
||||
/* These real versions are due to Isaku Wada */
|
||||
/** generates a random number on [0,1]-real-interval */
|
||||
JEMALLOC_INLINE double to_real1(uint32_t v)
|
||||
{
|
||||
return v * (1.0/4294967295.0);
|
||||
/* divided by 2^32-1 */
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1]-real-interval */
|
||||
JEMALLOC_INLINE double genrand_real1(sfmt_t *ctx)
|
||||
{
|
||||
return to_real1(gen_rand32(ctx));
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1)-real-interval */
|
||||
JEMALLOC_INLINE double to_real2(uint32_t v)
|
||||
{
|
||||
return v * (1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1)-real-interval */
|
||||
JEMALLOC_INLINE double genrand_real2(sfmt_t *ctx)
|
||||
{
|
||||
return to_real2(gen_rand32(ctx));
|
||||
}
|
||||
|
||||
/** generates a random number on (0,1)-real-interval */
|
||||
JEMALLOC_INLINE double to_real3(uint32_t v)
|
||||
{
|
||||
return (((double)v) + 0.5)*(1.0/4294967296.0);
|
||||
/* divided by 2^32 */
|
||||
}
|
||||
|
||||
/** generates a random number on (0,1)-real-interval */
|
||||
JEMALLOC_INLINE double genrand_real3(sfmt_t *ctx)
|
||||
{
|
||||
return to_real3(gen_rand32(ctx));
|
||||
}
|
||||
/** These real versions are due to Isaku Wada */
|
||||
|
||||
/** generates a random number on [0,1) with 53-bit resolution*/
|
||||
JEMALLOC_INLINE double to_res53(uint64_t v)
|
||||
{
|
||||
return v * (1.0/18446744073709551616.0L);
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1) with 53-bit resolution from two
|
||||
* 32 bit integers */
|
||||
JEMALLOC_INLINE double to_res53_mix(uint32_t x, uint32_t y)
|
||||
{
|
||||
return to_res53(x | ((uint64_t)y << 32));
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1) with 53-bit resolution
|
||||
*/
|
||||
JEMALLOC_INLINE double genrand_res53(sfmt_t *ctx)
|
||||
{
|
||||
return to_res53(gen_rand64(ctx));
|
||||
}
|
||||
|
||||
/** generates a random number on [0,1) with 53-bit resolution
|
||||
using 32bit integer.
|
||||
*/
|
||||
JEMALLOC_INLINE double genrand_res53_mix(sfmt_t *ctx)
|
||||
{
|
||||
uint32_t x, y;
|
||||
|
||||
x = gen_rand32(ctx);
|
||||
y = gen_rand32(ctx);
|
||||
return to_res53_mix(x, y);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
31
memory/jemalloc/src/test/include/test/btalloc.h
Normal file
31
memory/jemalloc/src/test/include/test/btalloc.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/* btalloc() provides a mechanism for allocating via permuted backtraces. */
|
||||
void *btalloc(size_t size, unsigned bits);
|
||||
|
||||
#define btalloc_n_proto(n) \
|
||||
void *btalloc_##n(size_t size, unsigned bits);
|
||||
btalloc_n_proto(0)
|
||||
btalloc_n_proto(1)
|
||||
|
||||
#define btalloc_n_gen(n) \
|
||||
void * \
|
||||
btalloc_##n(size_t size, unsigned bits) \
|
||||
{ \
|
||||
void *p; \
|
||||
\
|
||||
if (bits == 0) \
|
||||
p = mallocx(size, 0); \
|
||||
else { \
|
||||
switch (bits & 0x1U) { \
|
||||
case 0: \
|
||||
p = (btalloc_0(size, bits >> 1)); \
|
||||
break; \
|
||||
case 1: \
|
||||
p = (btalloc_1(size, bits >> 1)); \
|
||||
break; \
|
||||
default: not_reached(); \
|
||||
} \
|
||||
} \
|
||||
/* Intentionally sabotage tail call optimization. */ \
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure"); \
|
||||
return (p); \
|
||||
}
|
||||
163
memory/jemalloc/src/test/include/test/jemalloc_test.h.in
Normal file
163
memory/jemalloc/src/test/include/test/jemalloc_test.h.in
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include <limits.h>
|
||||
#ifndef SIZE_T_MAX
|
||||
# define SIZE_T_MAX SIZE_MAX
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
# include "msvc_compat/strings.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include "msvc_compat/windows_extra.h"
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "test/jemalloc_test_defs.h"
|
||||
|
||||
#ifdef JEMALLOC_OSSPIN
|
||||
# include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ALTIVEC) && !defined(__APPLE__)
|
||||
# include <altivec.h>
|
||||
#endif
|
||||
#ifdef HAVE_SSE2
|
||||
# include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* For unit tests, expose all public and private interfaces.
|
||||
*/
|
||||
#ifdef JEMALLOC_UNIT_TEST
|
||||
# define JEMALLOC_JET
|
||||
# define JEMALLOC_MANGLE
|
||||
# include "jemalloc/internal/jemalloc_internal.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* For integration tests, expose the public jemalloc interfaces, but only
|
||||
* expose the minimum necessary internal utility code (to avoid re-implementing
|
||||
* essentially identical code within the test infrastructure).
|
||||
*/
|
||||
#elif defined(JEMALLOC_INTEGRATION_TEST)
|
||||
# define JEMALLOC_MANGLE
|
||||
# include "jemalloc/jemalloc@install_suffix@.h"
|
||||
# include "jemalloc/internal/jemalloc_internal_defs.h"
|
||||
# include "jemalloc/internal/jemalloc_internal_macros.h"
|
||||
|
||||
static const bool config_debug =
|
||||
#ifdef JEMALLOC_DEBUG
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
|
||||
# define JEMALLOC_N(n) @private_namespace@##n
|
||||
# include "jemalloc/internal/private_namespace.h"
|
||||
|
||||
# define JEMALLOC_H_TYPES
|
||||
# define JEMALLOC_H_STRUCTS
|
||||
# define JEMALLOC_H_EXTERNS
|
||||
# define JEMALLOC_H_INLINES
|
||||
# include "jemalloc/internal/nstime.h"
|
||||
# include "jemalloc/internal/util.h"
|
||||
# include "jemalloc/internal/qr.h"
|
||||
# include "jemalloc/internal/ql.h"
|
||||
# undef JEMALLOC_H_TYPES
|
||||
# undef JEMALLOC_H_STRUCTS
|
||||
# undef JEMALLOC_H_EXTERNS
|
||||
# undef JEMALLOC_H_INLINES
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* For stress tests, expose the public jemalloc interfaces with name mangling
|
||||
* so that they can be tested as e.g. malloc() and free(). Also expose the
|
||||
* public jemalloc interfaces with jet_ prefixes, so that stress tests can use
|
||||
* a separate allocator for their internal data structures.
|
||||
*/
|
||||
#elif defined(JEMALLOC_STRESS_TEST)
|
||||
# include "jemalloc/jemalloc@install_suffix@.h"
|
||||
|
||||
# include "jemalloc/jemalloc_protos_jet.h"
|
||||
|
||||
# define JEMALLOC_JET
|
||||
# include "jemalloc/internal/jemalloc_internal.h"
|
||||
# include "jemalloc/internal/public_unnamespace.h"
|
||||
# undef JEMALLOC_JET
|
||||
|
||||
# include "jemalloc/jemalloc_rename.h"
|
||||
# define JEMALLOC_MANGLE
|
||||
# ifdef JEMALLOC_STRESS_TESTLIB
|
||||
# include "jemalloc/jemalloc_mangle_jet.h"
|
||||
# else
|
||||
# include "jemalloc/jemalloc_mangle.h"
|
||||
# endif
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* This header does dangerous things, the effects of which only test code
|
||||
* should be subject to.
|
||||
*/
|
||||
#else
|
||||
# error "This header cannot be included outside a testing context"
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Common test utilities.
|
||||
*/
|
||||
#include "test/btalloc.h"
|
||||
#include "test/math.h"
|
||||
#include "test/mtx.h"
|
||||
#include "test/mq.h"
|
||||
#include "test/test.h"
|
||||
#include "test/timer.h"
|
||||
#include "test/thd.h"
|
||||
#define MEXP 19937
|
||||
#include "test/SFMT.h"
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* Define always-enabled assertion macros, so that test assertions execute even
|
||||
* if assertions are disabled in the library code.
|
||||
*/
|
||||
#undef assert
|
||||
#undef not_reached
|
||||
#undef not_implemented
|
||||
#undef assert_not_implemented
|
||||
|
||||
#define assert(e) do { \
|
||||
if (!(e)) { \
|
||||
malloc_printf( \
|
||||
"<jemalloc>: %s:%d: Failed assertion: \"%s\"\n", \
|
||||
__FILE__, __LINE__, #e); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define not_reached() do { \
|
||||
malloc_printf( \
|
||||
"<jemalloc>: %s:%d: Unreachable code reached\n", \
|
||||
__FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#define not_implemented() do { \
|
||||
malloc_printf("<jemalloc>: %s:%d: Not implemented\n", \
|
||||
__FILE__, __LINE__); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
#define assert_not_implemented(e) do { \
|
||||
if (!(e)) \
|
||||
not_implemented(); \
|
||||
} while (0)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include "jemalloc/internal/jemalloc_internal_defs.h"
|
||||
#include "jemalloc/internal/jemalloc_internal_decls.h"
|
||||
|
||||
/*
|
||||
* For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its
|
||||
* dependencies are notoriously unportable in practice.
|
||||
*/
|
||||
#undef HAVE_SSE2
|
||||
#undef HAVE_ALTIVEC
|
||||
311
memory/jemalloc/src/test/include/test/math.h
Normal file
311
memory/jemalloc/src/test/include/test/math.h
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
#ifndef JEMALLOC_ENABLE_INLINE
|
||||
double ln_gamma(double x);
|
||||
double i_gamma(double x, double p, double ln_gamma_p);
|
||||
double pt_norm(double p);
|
||||
double pt_chi2(double p, double df, double ln_gamma_df_2);
|
||||
double pt_gamma(double p, double shape, double scale, double ln_gamma_shape);
|
||||
#endif
|
||||
|
||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(MATH_C_))
|
||||
/*
|
||||
* Compute the natural log of Gamma(x), accurate to 10 decimal places.
|
||||
*
|
||||
* This implementation is based on:
|
||||
*
|
||||
* Pike, M.C., I.D. Hill (1966) Algorithm 291: Logarithm of Gamma function
|
||||
* [S14]. Communications of the ACM 9(9):684.
|
||||
*/
|
||||
JEMALLOC_INLINE double
|
||||
ln_gamma(double x)
|
||||
{
|
||||
double f, z;
|
||||
|
||||
assert(x > 0.0);
|
||||
|
||||
if (x < 7.0) {
|
||||
f = 1.0;
|
||||
z = x;
|
||||
while (z < 7.0) {
|
||||
f *= z;
|
||||
z += 1.0;
|
||||
}
|
||||
x = z;
|
||||
f = -log(f);
|
||||
} else
|
||||
f = 0.0;
|
||||
|
||||
z = 1.0 / (x * x);
|
||||
|
||||
return (f + (x-0.5) * log(x) - x + 0.918938533204673 +
|
||||
(((-0.000595238095238 * z + 0.000793650793651) * z -
|
||||
0.002777777777778) * z + 0.083333333333333) / x);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the incomplete Gamma ratio for [0..x], where p is the shape
|
||||
* parameter, and ln_gamma_p is ln_gamma(p).
|
||||
*
|
||||
* This implementation is based on:
|
||||
*
|
||||
* Bhattacharjee, G.P. (1970) Algorithm AS 32: The incomplete Gamma integral.
|
||||
* Applied Statistics 19:285-287.
|
||||
*/
|
||||
JEMALLOC_INLINE double
|
||||
i_gamma(double x, double p, double ln_gamma_p)
|
||||
{
|
||||
double acu, factor, oflo, gin, term, rn, a, b, an, dif;
|
||||
double pn[6];
|
||||
unsigned i;
|
||||
|
||||
assert(p > 0.0);
|
||||
assert(x >= 0.0);
|
||||
|
||||
if (x == 0.0)
|
||||
return (0.0);
|
||||
|
||||
acu = 1.0e-10;
|
||||
oflo = 1.0e30;
|
||||
gin = 0.0;
|
||||
factor = exp(p * log(x) - x - ln_gamma_p);
|
||||
|
||||
if (x <= 1.0 || x < p) {
|
||||
/* Calculation by series expansion. */
|
||||
gin = 1.0;
|
||||
term = 1.0;
|
||||
rn = p;
|
||||
|
||||
while (true) {
|
||||
rn += 1.0;
|
||||
term *= x / rn;
|
||||
gin += term;
|
||||
if (term <= acu) {
|
||||
gin *= factor / p;
|
||||
return (gin);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Calculation by continued fraction. */
|
||||
a = 1.0 - p;
|
||||
b = a + x + 1.0;
|
||||
term = 0.0;
|
||||
pn[0] = 1.0;
|
||||
pn[1] = x;
|
||||
pn[2] = x + 1.0;
|
||||
pn[3] = x * b;
|
||||
gin = pn[2] / pn[3];
|
||||
|
||||
while (true) {
|
||||
a += 1.0;
|
||||
b += 2.0;
|
||||
term += 1.0;
|
||||
an = a * term;
|
||||
for (i = 0; i < 2; i++)
|
||||
pn[i+4] = b * pn[i+2] - an * pn[i];
|
||||
if (pn[5] != 0.0) {
|
||||
rn = pn[4] / pn[5];
|
||||
dif = fabs(gin - rn);
|
||||
if (dif <= acu && dif <= acu * rn) {
|
||||
gin = 1.0 - factor * gin;
|
||||
return (gin);
|
||||
}
|
||||
gin = rn;
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
pn[i] = pn[i+2];
|
||||
|
||||
if (fabs(pn[4]) >= oflo) {
|
||||
for (i = 0; i < 4; i++)
|
||||
pn[i] /= oflo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a value p in [0..1] of the lower tail area of the normal distribution,
|
||||
* compute the limit on the definite integral from [-inf..z] that satisfies p,
|
||||
* accurate to 16 decimal places.
|
||||
*
|
||||
* This implementation is based on:
|
||||
*
|
||||
* Wichura, M.J. (1988) Algorithm AS 241: The percentage points of the normal
|
||||
* distribution. Applied Statistics 37(3):477-484.
|
||||
*/
|
||||
JEMALLOC_INLINE double
|
||||
pt_norm(double p)
|
||||
{
|
||||
double q, r, ret;
|
||||
|
||||
assert(p > 0.0 && p < 1.0);
|
||||
|
||||
q = p - 0.5;
|
||||
if (fabs(q) <= 0.425) {
|
||||
/* p close to 1/2. */
|
||||
r = 0.180625 - q * q;
|
||||
return (q * (((((((2.5090809287301226727e3 * r +
|
||||
3.3430575583588128105e4) * r + 6.7265770927008700853e4) * r
|
||||
+ 4.5921953931549871457e4) * r + 1.3731693765509461125e4) *
|
||||
r + 1.9715909503065514427e3) * r + 1.3314166789178437745e2)
|
||||
* r + 3.3871328727963666080e0) /
|
||||
(((((((5.2264952788528545610e3 * r +
|
||||
2.8729085735721942674e4) * r + 3.9307895800092710610e4) * r
|
||||
+ 2.1213794301586595867e4) * r + 5.3941960214247511077e3) *
|
||||
r + 6.8718700749205790830e2) * r + 4.2313330701600911252e1)
|
||||
* r + 1.0));
|
||||
} else {
|
||||
if (q < 0.0)
|
||||
r = p;
|
||||
else
|
||||
r = 1.0 - p;
|
||||
assert(r > 0.0);
|
||||
|
||||
r = sqrt(-log(r));
|
||||
if (r <= 5.0) {
|
||||
/* p neither close to 1/2 nor 0 or 1. */
|
||||
r -= 1.6;
|
||||
ret = ((((((((7.74545014278341407640e-4 * r +
|
||||
2.27238449892691845833e-2) * r +
|
||||
2.41780725177450611770e-1) * r +
|
||||
1.27045825245236838258e0) * r +
|
||||
3.64784832476320460504e0) * r +
|
||||
5.76949722146069140550e0) * r +
|
||||
4.63033784615654529590e0) * r +
|
||||
1.42343711074968357734e0) /
|
||||
(((((((1.05075007164441684324e-9 * r +
|
||||
5.47593808499534494600e-4) * r +
|
||||
1.51986665636164571966e-2)
|
||||
* r + 1.48103976427480074590e-1) * r +
|
||||
6.89767334985100004550e-1) * r +
|
||||
1.67638483018380384940e0) * r +
|
||||
2.05319162663775882187e0) * r + 1.0));
|
||||
} else {
|
||||
/* p near 0 or 1. */
|
||||
r -= 5.0;
|
||||
ret = ((((((((2.01033439929228813265e-7 * r +
|
||||
2.71155556874348757815e-5) * r +
|
||||
1.24266094738807843860e-3) * r +
|
||||
2.65321895265761230930e-2) * r +
|
||||
2.96560571828504891230e-1) * r +
|
||||
1.78482653991729133580e0) * r +
|
||||
5.46378491116411436990e0) * r +
|
||||
6.65790464350110377720e0) /
|
||||
(((((((2.04426310338993978564e-15 * r +
|
||||
1.42151175831644588870e-7) * r +
|
||||
1.84631831751005468180e-5) * r +
|
||||
7.86869131145613259100e-4) * r +
|
||||
1.48753612908506148525e-2) * r +
|
||||
1.36929880922735805310e-1) * r +
|
||||
5.99832206555887937690e-1)
|
||||
* r + 1.0));
|
||||
}
|
||||
if (q < 0.0)
|
||||
ret = -ret;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a value p in [0..1] of the lower tail area of the Chi^2 distribution
|
||||
* with df degrees of freedom, where ln_gamma_df_2 is ln_gamma(df/2.0), compute
|
||||
* the upper limit on the definite integral from [0..z] that satisfies p,
|
||||
* accurate to 12 decimal places.
|
||||
*
|
||||
* This implementation is based on:
|
||||
*
|
||||
* Best, D.J., D.E. Roberts (1975) Algorithm AS 91: The percentage points of
|
||||
* the Chi^2 distribution. Applied Statistics 24(3):385-388.
|
||||
*
|
||||
* Shea, B.L. (1991) Algorithm AS R85: A remark on AS 91: The percentage
|
||||
* points of the Chi^2 distribution. Applied Statistics 40(1):233-235.
|
||||
*/
|
||||
JEMALLOC_INLINE double
|
||||
pt_chi2(double p, double df, double ln_gamma_df_2)
|
||||
{
|
||||
double e, aa, xx, c, ch, a, q, p1, p2, t, x, b, s1, s2, s3, s4, s5, s6;
|
||||
unsigned i;
|
||||
|
||||
assert(p >= 0.0 && p < 1.0);
|
||||
assert(df > 0.0);
|
||||
|
||||
e = 5.0e-7;
|
||||
aa = 0.6931471805;
|
||||
|
||||
xx = 0.5 * df;
|
||||
c = xx - 1.0;
|
||||
|
||||
if (df < -1.24 * log(p)) {
|
||||
/* Starting approximation for small Chi^2. */
|
||||
ch = pow(p * xx * exp(ln_gamma_df_2 + xx * aa), 1.0 / xx);
|
||||
if (ch - e < 0.0)
|
||||
return (ch);
|
||||
} else {
|
||||
if (df > 0.32) {
|
||||
x = pt_norm(p);
|
||||
/*
|
||||
* Starting approximation using Wilson and Hilferty
|
||||
* estimate.
|
||||
*/
|
||||
p1 = 0.222222 / df;
|
||||
ch = df * pow(x * sqrt(p1) + 1.0 - p1, 3.0);
|
||||
/* Starting approximation for p tending to 1. */
|
||||
if (ch > 2.2 * df + 6.0) {
|
||||
ch = -2.0 * (log(1.0 - p) - c * log(0.5 * ch) +
|
||||
ln_gamma_df_2);
|
||||
}
|
||||
} else {
|
||||
ch = 0.4;
|
||||
a = log(1.0 - p);
|
||||
while (true) {
|
||||
q = ch;
|
||||
p1 = 1.0 + ch * (4.67 + ch);
|
||||
p2 = ch * (6.73 + ch * (6.66 + ch));
|
||||
t = -0.5 + (4.67 + 2.0 * ch) / p1 - (6.73 + ch
|
||||
* (13.32 + 3.0 * ch)) / p2;
|
||||
ch -= (1.0 - exp(a + ln_gamma_df_2 + 0.5 * ch +
|
||||
c * aa) * p2 / p1) / t;
|
||||
if (fabs(q / ch - 1.0) - 0.01 <= 0.0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 20; i++) {
|
||||
/* Calculation of seven-term Taylor series. */
|
||||
q = ch;
|
||||
p1 = 0.5 * ch;
|
||||
if (p1 < 0.0)
|
||||
return (-1.0);
|
||||
p2 = p - i_gamma(p1, xx, ln_gamma_df_2);
|
||||
t = p2 * exp(xx * aa + ln_gamma_df_2 + p1 - c * log(ch));
|
||||
b = t / ch;
|
||||
a = 0.5 * t - b * c;
|
||||
s1 = (210.0 + a * (140.0 + a * (105.0 + a * (84.0 + a * (70.0 +
|
||||
60.0 * a))))) / 420.0;
|
||||
s2 = (420.0 + a * (735.0 + a * (966.0 + a * (1141.0 + 1278.0 *
|
||||
a)))) / 2520.0;
|
||||
s3 = (210.0 + a * (462.0 + a * (707.0 + 932.0 * a))) / 2520.0;
|
||||
s4 = (252.0 + a * (672.0 + 1182.0 * a) + c * (294.0 + a *
|
||||
(889.0 + 1740.0 * a))) / 5040.0;
|
||||
s5 = (84.0 + 264.0 * a + c * (175.0 + 606.0 * a)) / 2520.0;
|
||||
s6 = (120.0 + c * (346.0 + 127.0 * c)) / 5040.0;
|
||||
ch += t * (1.0 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3
|
||||
- b * (s4 - b * (s5 - b * s6))))));
|
||||
if (fabs(q / ch - 1.0) <= e)
|
||||
break;
|
||||
}
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a value p in [0..1] and Gamma distribution shape and scale parameters,
|
||||
* compute the upper limit on the definite integral from [0..z] that satisfies
|
||||
* p.
|
||||
*/
|
||||
JEMALLOC_INLINE double
|
||||
pt_gamma(double p, double shape, double scale, double ln_gamma_shape)
|
||||
{
|
||||
|
||||
return (pt_chi2(p, shape * 2.0, ln_gamma_shape) * 0.5 * scale);
|
||||
}
|
||||
#endif
|
||||
109
memory/jemalloc/src/test/include/test/mq.h
Normal file
109
memory/jemalloc/src/test/include/test/mq.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
void mq_nanosleep(unsigned ns);
|
||||
|
||||
/*
|
||||
* Simple templated message queue implementation that relies on only mutexes for
|
||||
* synchronization (which reduces portability issues). Given the following
|
||||
* setup:
|
||||
*
|
||||
* typedef struct mq_msg_s mq_msg_t;
|
||||
* struct mq_msg_s {
|
||||
* mq_msg(mq_msg_t) link;
|
||||
* [message data]
|
||||
* };
|
||||
* mq_gen(, mq_, mq_t, mq_msg_t, link)
|
||||
*
|
||||
* The API is as follows:
|
||||
*
|
||||
* bool mq_init(mq_t *mq);
|
||||
* void mq_fini(mq_t *mq);
|
||||
* unsigned mq_count(mq_t *mq);
|
||||
* mq_msg_t *mq_tryget(mq_t *mq);
|
||||
* mq_msg_t *mq_get(mq_t *mq);
|
||||
* void mq_put(mq_t *mq, mq_msg_t *msg);
|
||||
*
|
||||
* The message queue linkage embedded in each message is to be treated as
|
||||
* externally opaque (no need to initialize or clean up externally). mq_fini()
|
||||
* does not perform any cleanup of messages, since it knows nothing of their
|
||||
* payloads.
|
||||
*/
|
||||
#define mq_msg(a_mq_msg_type) ql_elm(a_mq_msg_type)
|
||||
|
||||
#define mq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field) \
|
||||
typedef struct { \
|
||||
mtx_t lock; \
|
||||
ql_head(a_mq_msg_type) msgs; \
|
||||
unsigned count; \
|
||||
} a_mq_type; \
|
||||
a_attr bool \
|
||||
a_prefix##init(a_mq_type *mq) { \
|
||||
\
|
||||
if (mtx_init(&mq->lock)) \
|
||||
return (true); \
|
||||
ql_new(&mq->msgs); \
|
||||
mq->count = 0; \
|
||||
return (false); \
|
||||
} \
|
||||
a_attr void \
|
||||
a_prefix##fini(a_mq_type *mq) \
|
||||
{ \
|
||||
\
|
||||
mtx_fini(&mq->lock); \
|
||||
} \
|
||||
a_attr unsigned \
|
||||
a_prefix##count(a_mq_type *mq) \
|
||||
{ \
|
||||
unsigned count; \
|
||||
\
|
||||
mtx_lock(&mq->lock); \
|
||||
count = mq->count; \
|
||||
mtx_unlock(&mq->lock); \
|
||||
return (count); \
|
||||
} \
|
||||
a_attr a_mq_msg_type * \
|
||||
a_prefix##tryget(a_mq_type *mq) \
|
||||
{ \
|
||||
a_mq_msg_type *msg; \
|
||||
\
|
||||
mtx_lock(&mq->lock); \
|
||||
msg = ql_first(&mq->msgs); \
|
||||
if (msg != NULL) { \
|
||||
ql_head_remove(&mq->msgs, a_mq_msg_type, a_field); \
|
||||
mq->count--; \
|
||||
} \
|
||||
mtx_unlock(&mq->lock); \
|
||||
return (msg); \
|
||||
} \
|
||||
a_attr a_mq_msg_type * \
|
||||
a_prefix##get(a_mq_type *mq) \
|
||||
{ \
|
||||
a_mq_msg_type *msg; \
|
||||
unsigned ns; \
|
||||
\
|
||||
msg = a_prefix##tryget(mq); \
|
||||
if (msg != NULL) \
|
||||
return (msg); \
|
||||
\
|
||||
ns = 1; \
|
||||
while (true) { \
|
||||
mq_nanosleep(ns); \
|
||||
msg = a_prefix##tryget(mq); \
|
||||
if (msg != NULL) \
|
||||
return (msg); \
|
||||
if (ns < 1000*1000*1000) { \
|
||||
/* Double sleep time, up to max 1 second. */ \
|
||||
ns <<= 1; \
|
||||
if (ns > 1000*1000*1000) \
|
||||
ns = 1000*1000*1000; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
a_attr void \
|
||||
a_prefix##put(a_mq_type *mq, a_mq_msg_type *msg) \
|
||||
{ \
|
||||
\
|
||||
mtx_lock(&mq->lock); \
|
||||
ql_elm_new(msg, a_field); \
|
||||
ql_tail_insert(&mq->msgs, msg, a_field); \
|
||||
mq->count++; \
|
||||
mtx_unlock(&mq->lock); \
|
||||
}
|
||||
23
memory/jemalloc/src/test/include/test/mtx.h
Normal file
23
memory/jemalloc/src/test/include/test/mtx.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* mtx is a slightly simplified version of malloc_mutex. This code duplication
|
||||
* is unfortunate, but there are allocator bootstrapping considerations that
|
||||
* would leak into the test infrastructure if malloc_mutex were used directly
|
||||
* in tests.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
#ifdef _WIN32
|
||||
CRITICAL_SECTION lock;
|
||||
#elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
|
||||
os_unfair_lock lock;
|
||||
#elif (defined(JEMALLOC_OSSPIN))
|
||||
OSSpinLock lock;
|
||||
#else
|
||||
pthread_mutex_t lock;
|
||||
#endif
|
||||
} mtx_t;
|
||||
|
||||
bool mtx_init(mtx_t *mtx);
|
||||
void mtx_fini(mtx_t *mtx);
|
||||
void mtx_lock(mtx_t *mtx);
|
||||
void mtx_unlock(mtx_t *mtx);
|
||||
333
memory/jemalloc/src/test/include/test/test.h
Normal file
333
memory/jemalloc/src/test/include/test/test.h
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
#define ASSERT_BUFSIZE 256
|
||||
|
||||
#define assert_cmp(t, a, b, cmp, neg_cmp, pri, ...) do { \
|
||||
t a_ = (a); \
|
||||
t b_ = (b); \
|
||||
if (!(a_ cmp b_)) { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Failed assertion: " \
|
||||
"(%s) "#cmp" (%s) --> " \
|
||||
"%"pri" "#neg_cmp" %"pri": ", \
|
||||
__func__, __FILE__, __LINE__, \
|
||||
#a, #b, a_, b_); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define assert_ptr_eq(a, b, ...) assert_cmp(void *, a, b, ==, \
|
||||
!=, "p", __VA_ARGS__)
|
||||
#define assert_ptr_ne(a, b, ...) assert_cmp(void *, a, b, !=, \
|
||||
==, "p", __VA_ARGS__)
|
||||
#define assert_ptr_null(a, ...) assert_cmp(void *, a, NULL, ==, \
|
||||
!=, "p", __VA_ARGS__)
|
||||
#define assert_ptr_not_null(a, ...) assert_cmp(void *, a, NULL, !=, \
|
||||
==, "p", __VA_ARGS__)
|
||||
|
||||
#define assert_c_eq(a, b, ...) assert_cmp(char, a, b, ==, !=, "c", __VA_ARGS__)
|
||||
#define assert_c_ne(a, b, ...) assert_cmp(char, a, b, !=, ==, "c", __VA_ARGS__)
|
||||
#define assert_c_lt(a, b, ...) assert_cmp(char, a, b, <, >=, "c", __VA_ARGS__)
|
||||
#define assert_c_le(a, b, ...) assert_cmp(char, a, b, <=, >, "c", __VA_ARGS__)
|
||||
#define assert_c_ge(a, b, ...) assert_cmp(char, a, b, >=, <, "c", __VA_ARGS__)
|
||||
#define assert_c_gt(a, b, ...) assert_cmp(char, a, b, >, <=, "c", __VA_ARGS__)
|
||||
|
||||
#define assert_x_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "#x", __VA_ARGS__)
|
||||
#define assert_x_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "#x", __VA_ARGS__)
|
||||
#define assert_x_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "#x", __VA_ARGS__)
|
||||
#define assert_x_le(a, b, ...) assert_cmp(int, a, b, <=, >, "#x", __VA_ARGS__)
|
||||
#define assert_x_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "#x", __VA_ARGS__)
|
||||
#define assert_x_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "#x", __VA_ARGS__)
|
||||
|
||||
#define assert_d_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "d", __VA_ARGS__)
|
||||
#define assert_d_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "d", __VA_ARGS__)
|
||||
#define assert_d_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "d", __VA_ARGS__)
|
||||
#define assert_d_le(a, b, ...) assert_cmp(int, a, b, <=, >, "d", __VA_ARGS__)
|
||||
#define assert_d_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "d", __VA_ARGS__)
|
||||
#define assert_d_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "d", __VA_ARGS__)
|
||||
|
||||
#define assert_u_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "u", __VA_ARGS__)
|
||||
#define assert_u_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "u", __VA_ARGS__)
|
||||
#define assert_u_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "u", __VA_ARGS__)
|
||||
#define assert_u_le(a, b, ...) assert_cmp(int, a, b, <=, >, "u", __VA_ARGS__)
|
||||
#define assert_u_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "u", __VA_ARGS__)
|
||||
#define assert_u_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "u", __VA_ARGS__)
|
||||
|
||||
#define assert_ld_eq(a, b, ...) assert_cmp(long, a, b, ==, \
|
||||
!=, "ld", __VA_ARGS__)
|
||||
#define assert_ld_ne(a, b, ...) assert_cmp(long, a, b, !=, \
|
||||
==, "ld", __VA_ARGS__)
|
||||
#define assert_ld_lt(a, b, ...) assert_cmp(long, a, b, <, \
|
||||
>=, "ld", __VA_ARGS__)
|
||||
#define assert_ld_le(a, b, ...) assert_cmp(long, a, b, <=, \
|
||||
>, "ld", __VA_ARGS__)
|
||||
#define assert_ld_ge(a, b, ...) assert_cmp(long, a, b, >=, \
|
||||
<, "ld", __VA_ARGS__)
|
||||
#define assert_ld_gt(a, b, ...) assert_cmp(long, a, b, >, \
|
||||
<=, "ld", __VA_ARGS__)
|
||||
|
||||
#define assert_lu_eq(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, ==, !=, "lu", __VA_ARGS__)
|
||||
#define assert_lu_ne(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, !=, ==, "lu", __VA_ARGS__)
|
||||
#define assert_lu_lt(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, <, >=, "lu", __VA_ARGS__)
|
||||
#define assert_lu_le(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, <=, >, "lu", __VA_ARGS__)
|
||||
#define assert_lu_ge(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, >=, <, "lu", __VA_ARGS__)
|
||||
#define assert_lu_gt(a, b, ...) assert_cmp(unsigned long, \
|
||||
a, b, >, <=, "lu", __VA_ARGS__)
|
||||
|
||||
#define assert_qd_eq(a, b, ...) assert_cmp(long long, a, b, ==, \
|
||||
!=, "qd", __VA_ARGS__)
|
||||
#define assert_qd_ne(a, b, ...) assert_cmp(long long, a, b, !=, \
|
||||
==, "qd", __VA_ARGS__)
|
||||
#define assert_qd_lt(a, b, ...) assert_cmp(long long, a, b, <, \
|
||||
>=, "qd", __VA_ARGS__)
|
||||
#define assert_qd_le(a, b, ...) assert_cmp(long long, a, b, <=, \
|
||||
>, "qd", __VA_ARGS__)
|
||||
#define assert_qd_ge(a, b, ...) assert_cmp(long long, a, b, >=, \
|
||||
<, "qd", __VA_ARGS__)
|
||||
#define assert_qd_gt(a, b, ...) assert_cmp(long long, a, b, >, \
|
||||
<=, "qd", __VA_ARGS__)
|
||||
|
||||
#define assert_qu_eq(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, ==, !=, "qu", __VA_ARGS__)
|
||||
#define assert_qu_ne(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, !=, ==, "qu", __VA_ARGS__)
|
||||
#define assert_qu_lt(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, <, >=, "qu", __VA_ARGS__)
|
||||
#define assert_qu_le(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, <=, >, "qu", __VA_ARGS__)
|
||||
#define assert_qu_ge(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, >=, <, "qu", __VA_ARGS__)
|
||||
#define assert_qu_gt(a, b, ...) assert_cmp(unsigned long long, \
|
||||
a, b, >, <=, "qu", __VA_ARGS__)
|
||||
|
||||
#define assert_jd_eq(a, b, ...) assert_cmp(intmax_t, a, b, ==, \
|
||||
!=, "jd", __VA_ARGS__)
|
||||
#define assert_jd_ne(a, b, ...) assert_cmp(intmax_t, a, b, !=, \
|
||||
==, "jd", __VA_ARGS__)
|
||||
#define assert_jd_lt(a, b, ...) assert_cmp(intmax_t, a, b, <, \
|
||||
>=, "jd", __VA_ARGS__)
|
||||
#define assert_jd_le(a, b, ...) assert_cmp(intmax_t, a, b, <=, \
|
||||
>, "jd", __VA_ARGS__)
|
||||
#define assert_jd_ge(a, b, ...) assert_cmp(intmax_t, a, b, >=, \
|
||||
<, "jd", __VA_ARGS__)
|
||||
#define assert_jd_gt(a, b, ...) assert_cmp(intmax_t, a, b, >, \
|
||||
<=, "jd", __VA_ARGS__)
|
||||
|
||||
#define assert_ju_eq(a, b, ...) assert_cmp(uintmax_t, a, b, ==, \
|
||||
!=, "ju", __VA_ARGS__)
|
||||
#define assert_ju_ne(a, b, ...) assert_cmp(uintmax_t, a, b, !=, \
|
||||
==, "ju", __VA_ARGS__)
|
||||
#define assert_ju_lt(a, b, ...) assert_cmp(uintmax_t, a, b, <, \
|
||||
>=, "ju", __VA_ARGS__)
|
||||
#define assert_ju_le(a, b, ...) assert_cmp(uintmax_t, a, b, <=, \
|
||||
>, "ju", __VA_ARGS__)
|
||||
#define assert_ju_ge(a, b, ...) assert_cmp(uintmax_t, a, b, >=, \
|
||||
<, "ju", __VA_ARGS__)
|
||||
#define assert_ju_gt(a, b, ...) assert_cmp(uintmax_t, a, b, >, \
|
||||
<=, "ju", __VA_ARGS__)
|
||||
|
||||
#define assert_zd_eq(a, b, ...) assert_cmp(ssize_t, a, b, ==, \
|
||||
!=, "zd", __VA_ARGS__)
|
||||
#define assert_zd_ne(a, b, ...) assert_cmp(ssize_t, a, b, !=, \
|
||||
==, "zd", __VA_ARGS__)
|
||||
#define assert_zd_lt(a, b, ...) assert_cmp(ssize_t, a, b, <, \
|
||||
>=, "zd", __VA_ARGS__)
|
||||
#define assert_zd_le(a, b, ...) assert_cmp(ssize_t, a, b, <=, \
|
||||
>, "zd", __VA_ARGS__)
|
||||
#define assert_zd_ge(a, b, ...) assert_cmp(ssize_t, a, b, >=, \
|
||||
<, "zd", __VA_ARGS__)
|
||||
#define assert_zd_gt(a, b, ...) assert_cmp(ssize_t, a, b, >, \
|
||||
<=, "zd", __VA_ARGS__)
|
||||
|
||||
#define assert_zu_eq(a, b, ...) assert_cmp(size_t, a, b, ==, \
|
||||
!=, "zu", __VA_ARGS__)
|
||||
#define assert_zu_ne(a, b, ...) assert_cmp(size_t, a, b, !=, \
|
||||
==, "zu", __VA_ARGS__)
|
||||
#define assert_zu_lt(a, b, ...) assert_cmp(size_t, a, b, <, \
|
||||
>=, "zu", __VA_ARGS__)
|
||||
#define assert_zu_le(a, b, ...) assert_cmp(size_t, a, b, <=, \
|
||||
>, "zu", __VA_ARGS__)
|
||||
#define assert_zu_ge(a, b, ...) assert_cmp(size_t, a, b, >=, \
|
||||
<, "zu", __VA_ARGS__)
|
||||
#define assert_zu_gt(a, b, ...) assert_cmp(size_t, a, b, >, \
|
||||
<=, "zu", __VA_ARGS__)
|
||||
|
||||
#define assert_d32_eq(a, b, ...) assert_cmp(int32_t, a, b, ==, \
|
||||
!=, FMTd32, __VA_ARGS__)
|
||||
#define assert_d32_ne(a, b, ...) assert_cmp(int32_t, a, b, !=, \
|
||||
==, FMTd32, __VA_ARGS__)
|
||||
#define assert_d32_lt(a, b, ...) assert_cmp(int32_t, a, b, <, \
|
||||
>=, FMTd32, __VA_ARGS__)
|
||||
#define assert_d32_le(a, b, ...) assert_cmp(int32_t, a, b, <=, \
|
||||
>, FMTd32, __VA_ARGS__)
|
||||
#define assert_d32_ge(a, b, ...) assert_cmp(int32_t, a, b, >=, \
|
||||
<, FMTd32, __VA_ARGS__)
|
||||
#define assert_d32_gt(a, b, ...) assert_cmp(int32_t, a, b, >, \
|
||||
<=, FMTd32, __VA_ARGS__)
|
||||
|
||||
#define assert_u32_eq(a, b, ...) assert_cmp(uint32_t, a, b, ==, \
|
||||
!=, FMTu32, __VA_ARGS__)
|
||||
#define assert_u32_ne(a, b, ...) assert_cmp(uint32_t, a, b, !=, \
|
||||
==, FMTu32, __VA_ARGS__)
|
||||
#define assert_u32_lt(a, b, ...) assert_cmp(uint32_t, a, b, <, \
|
||||
>=, FMTu32, __VA_ARGS__)
|
||||
#define assert_u32_le(a, b, ...) assert_cmp(uint32_t, a, b, <=, \
|
||||
>, FMTu32, __VA_ARGS__)
|
||||
#define assert_u32_ge(a, b, ...) assert_cmp(uint32_t, a, b, >=, \
|
||||
<, FMTu32, __VA_ARGS__)
|
||||
#define assert_u32_gt(a, b, ...) assert_cmp(uint32_t, a, b, >, \
|
||||
<=, FMTu32, __VA_ARGS__)
|
||||
|
||||
#define assert_d64_eq(a, b, ...) assert_cmp(int64_t, a, b, ==, \
|
||||
!=, FMTd64, __VA_ARGS__)
|
||||
#define assert_d64_ne(a, b, ...) assert_cmp(int64_t, a, b, !=, \
|
||||
==, FMTd64, __VA_ARGS__)
|
||||
#define assert_d64_lt(a, b, ...) assert_cmp(int64_t, a, b, <, \
|
||||
>=, FMTd64, __VA_ARGS__)
|
||||
#define assert_d64_le(a, b, ...) assert_cmp(int64_t, a, b, <=, \
|
||||
>, FMTd64, __VA_ARGS__)
|
||||
#define assert_d64_ge(a, b, ...) assert_cmp(int64_t, a, b, >=, \
|
||||
<, FMTd64, __VA_ARGS__)
|
||||
#define assert_d64_gt(a, b, ...) assert_cmp(int64_t, a, b, >, \
|
||||
<=, FMTd64, __VA_ARGS__)
|
||||
|
||||
#define assert_u64_eq(a, b, ...) assert_cmp(uint64_t, a, b, ==, \
|
||||
!=, FMTu64, __VA_ARGS__)
|
||||
#define assert_u64_ne(a, b, ...) assert_cmp(uint64_t, a, b, !=, \
|
||||
==, FMTu64, __VA_ARGS__)
|
||||
#define assert_u64_lt(a, b, ...) assert_cmp(uint64_t, a, b, <, \
|
||||
>=, FMTu64, __VA_ARGS__)
|
||||
#define assert_u64_le(a, b, ...) assert_cmp(uint64_t, a, b, <=, \
|
||||
>, FMTu64, __VA_ARGS__)
|
||||
#define assert_u64_ge(a, b, ...) assert_cmp(uint64_t, a, b, >=, \
|
||||
<, FMTu64, __VA_ARGS__)
|
||||
#define assert_u64_gt(a, b, ...) assert_cmp(uint64_t, a, b, >, \
|
||||
<=, FMTu64, __VA_ARGS__)
|
||||
|
||||
#define assert_b_eq(a, b, ...) do { \
|
||||
bool a_ = (a); \
|
||||
bool b_ = (b); \
|
||||
if (!(a_ == b_)) { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Failed assertion: " \
|
||||
"(%s) == (%s) --> %s != %s: ", \
|
||||
__func__, __FILE__, __LINE__, \
|
||||
#a, #b, a_ ? "true" : "false", \
|
||||
b_ ? "true" : "false"); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert_b_ne(a, b, ...) do { \
|
||||
bool a_ = (a); \
|
||||
bool b_ = (b); \
|
||||
if (!(a_ != b_)) { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Failed assertion: " \
|
||||
"(%s) != (%s) --> %s == %s: ", \
|
||||
__func__, __FILE__, __LINE__, \
|
||||
#a, #b, a_ ? "true" : "false", \
|
||||
b_ ? "true" : "false"); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert_true(a, ...) assert_b_eq(a, true, __VA_ARGS__)
|
||||
#define assert_false(a, ...) assert_b_eq(a, false, __VA_ARGS__)
|
||||
|
||||
#define assert_str_eq(a, b, ...) do { \
|
||||
if (strcmp((a), (b))) { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Failed assertion: " \
|
||||
"(%s) same as (%s) --> " \
|
||||
"\"%s\" differs from \"%s\": ", \
|
||||
__func__, __FILE__, __LINE__, #a, #b, a, b); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert_str_ne(a, b, ...) do { \
|
||||
if (!strcmp((a), (b))) { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Failed assertion: " \
|
||||
"(%s) differs from (%s) --> " \
|
||||
"\"%s\" same as \"%s\": ", \
|
||||
__func__, __FILE__, __LINE__, #a, #b, a, b); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define assert_not_reached(...) do { \
|
||||
char prefix[ASSERT_BUFSIZE]; \
|
||||
char message[ASSERT_BUFSIZE]; \
|
||||
malloc_snprintf(prefix, sizeof(prefix), \
|
||||
"%s:%s:%d: Unreachable code reached: ", \
|
||||
__func__, __FILE__, __LINE__); \
|
||||
malloc_snprintf(message, sizeof(message), __VA_ARGS__); \
|
||||
p_test_fail(prefix, message); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* If this enum changes, corresponding changes in test/test.sh.in are also
|
||||
* necessary.
|
||||
*/
|
||||
typedef enum {
|
||||
test_status_pass = 0,
|
||||
test_status_skip = 1,
|
||||
test_status_fail = 2,
|
||||
|
||||
test_status_count = 3
|
||||
} test_status_t;
|
||||
|
||||
typedef void (test_t)(void);
|
||||
|
||||
#define TEST_BEGIN(f) \
|
||||
static void \
|
||||
f(void) \
|
||||
{ \
|
||||
p_test_init(#f);
|
||||
|
||||
#define TEST_END \
|
||||
goto label_test_end; \
|
||||
label_test_end: \
|
||||
p_test_fini(); \
|
||||
}
|
||||
|
||||
#define test(...) \
|
||||
p_test(__VA_ARGS__, NULL)
|
||||
|
||||
#define test_no_malloc_init(...) \
|
||||
p_test_no_malloc_init(__VA_ARGS__, NULL)
|
||||
|
||||
#define test_skip_if(e) do { \
|
||||
if (e) { \
|
||||
test_skip("%s:%s:%d: Test skipped: (%s)", \
|
||||
__func__, __FILE__, __LINE__, #e); \
|
||||
goto label_test_end; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void test_skip(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2);
|
||||
void test_fail(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2);
|
||||
|
||||
/* For private use by macros. */
|
||||
test_status_t p_test(test_t *t, ...);
|
||||
test_status_t p_test_no_malloc_init(test_t *t, ...);
|
||||
void p_test_init(const char *name);
|
||||
void p_test_fini(void);
|
||||
void p_test_fail(const char *prefix, const char *message);
|
||||
9
memory/jemalloc/src/test/include/test/thd.h
Normal file
9
memory/jemalloc/src/test/include/test/thd.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* Abstraction layer for threading in tests. */
|
||||
#ifdef _WIN32
|
||||
typedef HANDLE thd_t;
|
||||
#else
|
||||
typedef pthread_t thd_t;
|
||||
#endif
|
||||
|
||||
void thd_create(thd_t *thd, void *(*proc)(void *), void *arg);
|
||||
void thd_join(thd_t thd, void **ret);
|
||||
11
memory/jemalloc/src/test/include/test/timer.h
Normal file
11
memory/jemalloc/src/test/include/test/timer.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* Simple timer, for use in benchmark reporting. */
|
||||
|
||||
typedef struct {
|
||||
nstime_t t0;
|
||||
nstime_t t1;
|
||||
} timedelta_t;
|
||||
|
||||
void timer_start(timedelta_t *timer);
|
||||
void timer_stop(timedelta_t *timer);
|
||||
uint64_t timer_usec(const timedelta_t *timer);
|
||||
void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen);
|
||||
69
memory/jemalloc/src/test/integration/MALLOCX_ARENA.c
Normal file
69
memory/jemalloc/src/test/integration/MALLOCX_ARENA.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 10
|
||||
|
||||
static bool have_dss =
|
||||
#ifdef JEMALLOC_DSS
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
unsigned thread_ind = (unsigned)(uintptr_t)arg;
|
||||
unsigned arena_ind;
|
||||
void *p;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(arena_ind);
|
||||
assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0,
|
||||
"Error in arenas.extend");
|
||||
|
||||
if (thread_ind % 4 != 3) {
|
||||
size_t mib[3];
|
||||
size_t miblen = sizeof(mib) / sizeof(size_t);
|
||||
const char *dss_precs[] = {"disabled", "primary", "secondary"};
|
||||
unsigned prec_ind = thread_ind %
|
||||
(sizeof(dss_precs)/sizeof(char*));
|
||||
const char *dss = dss_precs[prec_ind];
|
||||
int expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT;
|
||||
assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0,
|
||||
"Error in mallctlnametomib()");
|
||||
mib[1] = arena_ind;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss,
|
||||
sizeof(const char *)), expected_err,
|
||||
"Error in mallctlbymib()");
|
||||
}
|
||||
|
||||
p = mallocx(1, MALLOCX_ARENA(arena_ind));
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
dallocx(p, 0);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_MALLOCX_ARENA)
|
||||
{
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
thd_create(&thds[i], thd_start,
|
||||
(void *)(uintptr_t)i);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_MALLOCX_ARENA));
|
||||
}
|
||||
139
memory/jemalloc/src/test/integration/aligned_alloc.c
Normal file
139
memory/jemalloc/src/test/integration/aligned_alloc.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define CHUNK 0x400000
|
||||
#define MAXALIGN (((size_t)1) << 23)
|
||||
|
||||
/*
|
||||
* On systems which can't merge extents, tests that call this function generate
|
||||
* a lot of dirty memory very quickly. Purging between cycles mitigates
|
||||
* potential OOM on e.g. 32-bit Windows.
|
||||
*/
|
||||
static void
|
||||
purge(void)
|
||||
{
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl error");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_alignment_errors)
|
||||
{
|
||||
size_t alignment;
|
||||
void *p;
|
||||
|
||||
alignment = 0;
|
||||
set_errno(0);
|
||||
p = aligned_alloc(alignment, 1);
|
||||
assert_false(p != NULL || get_errno() != EINVAL,
|
||||
"Expected error for invalid alignment %zu", alignment);
|
||||
|
||||
for (alignment = sizeof(size_t); alignment < MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
set_errno(0);
|
||||
p = aligned_alloc(alignment + 1, 1);
|
||||
assert_false(p != NULL || get_errno() != EINVAL,
|
||||
"Expected error for invalid alignment %zu",
|
||||
alignment + 1);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_oom_errors)
|
||||
{
|
||||
size_t alignment, size;
|
||||
void *p;
|
||||
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
alignment = UINT64_C(0x8000000000000000);
|
||||
size = UINT64_C(0x8000000000000000);
|
||||
#else
|
||||
alignment = 0x80000000LU;
|
||||
size = 0x80000000LU;
|
||||
#endif
|
||||
set_errno(0);
|
||||
p = aligned_alloc(alignment, size);
|
||||
assert_false(p != NULL || get_errno() != ENOMEM,
|
||||
"Expected error for aligned_alloc(%zu, %zu)",
|
||||
alignment, size);
|
||||
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
alignment = UINT64_C(0x4000000000000000);
|
||||
size = UINT64_C(0xc000000000000001);
|
||||
#else
|
||||
alignment = 0x40000000LU;
|
||||
size = 0xc0000001LU;
|
||||
#endif
|
||||
set_errno(0);
|
||||
p = aligned_alloc(alignment, size);
|
||||
assert_false(p != NULL || get_errno() != ENOMEM,
|
||||
"Expected error for aligned_alloc(%zu, %zu)",
|
||||
alignment, size);
|
||||
|
||||
alignment = 0x10LU;
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
size = UINT64_C(0xfffffffffffffff0);
|
||||
#else
|
||||
size = 0xfffffff0LU;
|
||||
#endif
|
||||
set_errno(0);
|
||||
p = aligned_alloc(alignment, size);
|
||||
assert_false(p != NULL || get_errno() != ENOMEM,
|
||||
"Expected error for aligned_alloc(&p, %zu, %zu)",
|
||||
alignment, size);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_alignment_and_size)
|
||||
{
|
||||
#define NITER 4
|
||||
size_t alignment, size, total;
|
||||
unsigned i;
|
||||
void *ps[NITER];
|
||||
|
||||
for (i = 0; i < NITER; i++)
|
||||
ps[i] = NULL;
|
||||
|
||||
for (alignment = 8;
|
||||
alignment <= MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
total = 0;
|
||||
for (size = 1;
|
||||
size < 3 * alignment && size < (1U << 31);
|
||||
size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
||||
for (i = 0; i < NITER; i++) {
|
||||
ps[i] = aligned_alloc(alignment, size);
|
||||
if (ps[i] == NULL) {
|
||||
char buf[BUFERROR_BUF];
|
||||
|
||||
buferror(get_errno(), buf, sizeof(buf));
|
||||
test_fail(
|
||||
"Error for alignment=%zu, "
|
||||
"size=%zu (%#zx): %s",
|
||||
alignment, size, size, buf);
|
||||
}
|
||||
total += malloc_usable_size(ps[i]);
|
||||
if (total >= (MAXALIGN << 1))
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < NITER; i++) {
|
||||
if (ps[i] != NULL) {
|
||||
free(ps[i]);
|
||||
ps[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
purge();
|
||||
}
|
||||
#undef NITER
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_alignment_errors,
|
||||
test_oom_errors,
|
||||
test_alignment_and_size));
|
||||
}
|
||||
125
memory/jemalloc/src/test/integration/allocated.c
Normal file
125
memory/jemalloc/src/test/integration/allocated.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static const bool config_stats =
|
||||
#ifdef JEMALLOC_STATS
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
int err;
|
||||
void *p;
|
||||
uint64_t a0, a1, d0, d1;
|
||||
uint64_t *ap0, *ap1, *dp0, *dp1;
|
||||
size_t sz, usize;
|
||||
|
||||
sz = sizeof(a0);
|
||||
if ((err = mallctl("thread.allocated", &a0, &sz, NULL, 0))) {
|
||||
if (err == ENOENT)
|
||||
goto label_ENOENT;
|
||||
test_fail("%s(): Error in mallctl(): %s", __func__,
|
||||
strerror(err));
|
||||
}
|
||||
sz = sizeof(ap0);
|
||||
if ((err = mallctl("thread.allocatedp", &ap0, &sz, NULL, 0))) {
|
||||
if (err == ENOENT)
|
||||
goto label_ENOENT;
|
||||
test_fail("%s(): Error in mallctl(): %s", __func__,
|
||||
strerror(err));
|
||||
}
|
||||
assert_u64_eq(*ap0, a0,
|
||||
"\"thread.allocatedp\" should provide a pointer to internal "
|
||||
"storage");
|
||||
|
||||
sz = sizeof(d0);
|
||||
if ((err = mallctl("thread.deallocated", &d0, &sz, NULL, 0))) {
|
||||
if (err == ENOENT)
|
||||
goto label_ENOENT;
|
||||
test_fail("%s(): Error in mallctl(): %s", __func__,
|
||||
strerror(err));
|
||||
}
|
||||
sz = sizeof(dp0);
|
||||
if ((err = mallctl("thread.deallocatedp", &dp0, &sz, NULL, 0))) {
|
||||
if (err == ENOENT)
|
||||
goto label_ENOENT;
|
||||
test_fail("%s(): Error in mallctl(): %s", __func__,
|
||||
strerror(err));
|
||||
}
|
||||
assert_u64_eq(*dp0, d0,
|
||||
"\"thread.deallocatedp\" should provide a pointer to internal "
|
||||
"storage");
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() error");
|
||||
|
||||
sz = sizeof(a1);
|
||||
mallctl("thread.allocated", &a1, &sz, NULL, 0);
|
||||
sz = sizeof(ap1);
|
||||
mallctl("thread.allocatedp", &ap1, &sz, NULL, 0);
|
||||
assert_u64_eq(*ap1, a1,
|
||||
"Dereferenced \"thread.allocatedp\" value should equal "
|
||||
"\"thread.allocated\" value");
|
||||
assert_ptr_eq(ap0, ap1,
|
||||
"Pointer returned by \"thread.allocatedp\" should not change");
|
||||
|
||||
usize = malloc_usable_size(p);
|
||||
assert_u64_le(a0 + usize, a1,
|
||||
"Allocated memory counter should increase by at least the amount "
|
||||
"explicitly allocated");
|
||||
|
||||
free(p);
|
||||
|
||||
sz = sizeof(d1);
|
||||
mallctl("thread.deallocated", &d1, &sz, NULL, 0);
|
||||
sz = sizeof(dp1);
|
||||
mallctl("thread.deallocatedp", &dp1, &sz, NULL, 0);
|
||||
assert_u64_eq(*dp1, d1,
|
||||
"Dereferenced \"thread.deallocatedp\" value should equal "
|
||||
"\"thread.deallocated\" value");
|
||||
assert_ptr_eq(dp0, dp1,
|
||||
"Pointer returned by \"thread.deallocatedp\" should not change");
|
||||
|
||||
assert_u64_le(d0 + usize, d1,
|
||||
"Deallocated memory counter should increase by at least the amount "
|
||||
"explicitly deallocated");
|
||||
|
||||
return (NULL);
|
||||
label_ENOENT:
|
||||
assert_false(config_stats,
|
||||
"ENOENT should only be returned if stats are disabled");
|
||||
test_skip("\"thread.allocated\" mallctl not available");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_main_thread)
|
||||
{
|
||||
|
||||
thd_start(NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_subthread)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
thd_create(&thd, thd_start, NULL);
|
||||
thd_join(thd, NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
/* Run tests multiple times to check for bad interactions. */
|
||||
return (test(
|
||||
test_main_thread,
|
||||
test_subthread,
|
||||
test_main_thread,
|
||||
test_subthread,
|
||||
test_main_thread));
|
||||
}
|
||||
293
memory/jemalloc/src/test/integration/chunk.c
Normal file
293
memory/jemalloc/src/test/integration/chunk.c
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf = "junk:false";
|
||||
#endif
|
||||
|
||||
static chunk_hooks_t orig_hooks;
|
||||
static chunk_hooks_t old_hooks;
|
||||
|
||||
static bool do_dalloc = true;
|
||||
static bool do_decommit;
|
||||
|
||||
static bool did_alloc;
|
||||
static bool did_dalloc;
|
||||
static bool did_commit;
|
||||
static bool did_decommit;
|
||||
static bool did_purge;
|
||||
static bool did_split;
|
||||
static bool did_merge;
|
||||
|
||||
#if 0
|
||||
# define TRACE_HOOK(fmt, ...) malloc_printf(fmt, __VA_ARGS__)
|
||||
#else
|
||||
# define TRACE_HOOK(fmt, ...)
|
||||
#endif
|
||||
|
||||
void *
|
||||
chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero,
|
||||
bool *commit, unsigned arena_ind)
|
||||
{
|
||||
|
||||
TRACE_HOOK("%s(new_addr=%p, size=%zu, alignment=%zu, *zero=%s, "
|
||||
"*commit=%s, arena_ind=%u)\n", __func__, new_addr, size, alignment,
|
||||
*zero ? "true" : "false", *commit ? "true" : "false", arena_ind);
|
||||
did_alloc = true;
|
||||
return (old_hooks.alloc(new_addr, size, alignment, zero, commit,
|
||||
arena_ind));
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind)
|
||||
{
|
||||
|
||||
TRACE_HOOK("%s(chunk=%p, size=%zu, committed=%s, arena_ind=%u)\n",
|
||||
__func__, chunk, size, committed ? "true" : "false", arena_ind);
|
||||
did_dalloc = true;
|
||||
if (!do_dalloc)
|
||||
return (true);
|
||||
return (old_hooks.dalloc(chunk, size, committed, arena_ind));
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_commit(void *chunk, size_t size, size_t offset, size_t length,
|
||||
unsigned arena_ind)
|
||||
{
|
||||
bool err;
|
||||
|
||||
TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
|
||||
"arena_ind=%u)\n", __func__, chunk, size, offset, length,
|
||||
arena_ind);
|
||||
err = old_hooks.commit(chunk, size, offset, length, arena_ind);
|
||||
did_commit = !err;
|
||||
return (err);
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_decommit(void *chunk, size_t size, size_t offset, size_t length,
|
||||
unsigned arena_ind)
|
||||
{
|
||||
bool err;
|
||||
|
||||
TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, "
|
||||
"arena_ind=%u)\n", __func__, chunk, size, offset, length,
|
||||
arena_ind);
|
||||
if (!do_decommit)
|
||||
return (true);
|
||||
err = old_hooks.decommit(chunk, size, offset, length, arena_ind);
|
||||
did_decommit = !err;
|
||||
return (err);
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_purge(void *chunk, size_t size, size_t offset, size_t length,
|
||||
unsigned arena_ind)
|
||||
{
|
||||
|
||||
TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu "
|
||||
"arena_ind=%u)\n", __func__, chunk, size, offset, length,
|
||||
arena_ind);
|
||||
did_purge = true;
|
||||
return (old_hooks.purge(chunk, size, offset, length, arena_ind));
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b,
|
||||
bool committed, unsigned arena_ind)
|
||||
{
|
||||
|
||||
TRACE_HOOK("%s(chunk=%p, size=%zu, size_a=%zu, size_b=%zu, "
|
||||
"committed=%s, arena_ind=%u)\n", __func__, chunk, size, size_a,
|
||||
size_b, committed ? "true" : "false", arena_ind);
|
||||
did_split = true;
|
||||
return (old_hooks.split(chunk, size, size_a, size_b, committed,
|
||||
arena_ind));
|
||||
}
|
||||
|
||||
bool
|
||||
chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,
|
||||
bool committed, unsigned arena_ind)
|
||||
{
|
||||
|
||||
TRACE_HOOK("%s(chunk_a=%p, size_a=%zu, chunk_b=%p size_b=%zu, "
|
||||
"committed=%s, arena_ind=%u)\n", __func__, chunk_a, size_a, chunk_b,
|
||||
size_b, committed ? "true" : "false", arena_ind);
|
||||
did_merge = true;
|
||||
return (old_hooks.merge(chunk_a, size_a, chunk_b, size_b,
|
||||
committed, arena_ind));
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_chunk)
|
||||
{
|
||||
void *p;
|
||||
size_t old_size, new_size, large0, large1, huge0, huge1, huge2, sz;
|
||||
unsigned arena_ind;
|
||||
int flags;
|
||||
size_t hooks_mib[3], purge_mib[3];
|
||||
size_t hooks_miblen, purge_miblen;
|
||||
chunk_hooks_t new_hooks = {
|
||||
chunk_alloc,
|
||||
chunk_dalloc,
|
||||
chunk_commit,
|
||||
chunk_decommit,
|
||||
chunk_purge,
|
||||
chunk_split,
|
||||
chunk_merge
|
||||
};
|
||||
bool xallocx_success_a, xallocx_success_b, xallocx_success_c;
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
||||
|
||||
/* Install custom chunk hooks. */
|
||||
hooks_miblen = sizeof(hooks_mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arena.0.chunk_hooks", hooks_mib,
|
||||
&hooks_miblen), 0, "Unexpected mallctlnametomib() failure");
|
||||
hooks_mib[1] = (size_t)arena_ind;
|
||||
old_size = sizeof(chunk_hooks_t);
|
||||
new_size = sizeof(chunk_hooks_t);
|
||||
assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, &old_hooks, &old_size,
|
||||
&new_hooks, new_size), 0, "Unexpected chunk_hooks error");
|
||||
orig_hooks = old_hooks;
|
||||
assert_ptr_ne(old_hooks.alloc, chunk_alloc, "Unexpected alloc error");
|
||||
assert_ptr_ne(old_hooks.dalloc, chunk_dalloc,
|
||||
"Unexpected dalloc error");
|
||||
assert_ptr_ne(old_hooks.commit, chunk_commit,
|
||||
"Unexpected commit error");
|
||||
assert_ptr_ne(old_hooks.decommit, chunk_decommit,
|
||||
"Unexpected decommit error");
|
||||
assert_ptr_ne(old_hooks.purge, chunk_purge, "Unexpected purge error");
|
||||
assert_ptr_ne(old_hooks.split, chunk_split, "Unexpected split error");
|
||||
assert_ptr_ne(old_hooks.merge, chunk_merge, "Unexpected merge error");
|
||||
|
||||
/* Get large size classes. */
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
|
||||
"Unexpected arenas.lrun.0.size failure");
|
||||
assert_d_eq(mallctl("arenas.lrun.1.size", &large1, &sz, NULL, 0), 0,
|
||||
"Unexpected arenas.lrun.1.size failure");
|
||||
|
||||
/* Get huge size classes. */
|
||||
assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0,
|
||||
"Unexpected arenas.hchunk.0.size failure");
|
||||
assert_d_eq(mallctl("arenas.hchunk.1.size", &huge1, &sz, NULL, 0), 0,
|
||||
"Unexpected arenas.hchunk.1.size failure");
|
||||
assert_d_eq(mallctl("arenas.hchunk.2.size", &huge2, &sz, NULL, 0), 0,
|
||||
"Unexpected arenas.hchunk.2.size failure");
|
||||
|
||||
/* Test dalloc/decommit/purge cascade. */
|
||||
purge_miblen = sizeof(purge_mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arena.0.purge", purge_mib, &purge_miblen),
|
||||
0, "Unexpected mallctlnametomib() failure");
|
||||
purge_mib[1] = (size_t)arena_ind;
|
||||
do_dalloc = false;
|
||||
do_decommit = false;
|
||||
p = mallocx(huge0 * 2, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
did_dalloc = false;
|
||||
did_decommit = false;
|
||||
did_purge = false;
|
||||
did_split = false;
|
||||
xallocx_success_a = (xallocx(p, huge0, 0, flags) == huge0);
|
||||
assert_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
||||
0, "Unexpected arena.%u.purge error", arena_ind);
|
||||
if (xallocx_success_a) {
|
||||
assert_true(did_dalloc, "Expected dalloc");
|
||||
assert_false(did_decommit, "Unexpected decommit");
|
||||
assert_true(did_purge, "Expected purge");
|
||||
}
|
||||
assert_true(did_split, "Expected split");
|
||||
dallocx(p, flags);
|
||||
do_dalloc = true;
|
||||
|
||||
/* Test decommit/commit and observe split/merge. */
|
||||
do_dalloc = false;
|
||||
do_decommit = true;
|
||||
p = mallocx(huge0 * 2, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
did_decommit = false;
|
||||
did_commit = false;
|
||||
did_split = false;
|
||||
did_merge = false;
|
||||
xallocx_success_b = (xallocx(p, huge0, 0, flags) == huge0);
|
||||
assert_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
||||
0, "Unexpected arena.%u.purge error", arena_ind);
|
||||
if (xallocx_success_b)
|
||||
assert_true(did_split, "Expected split");
|
||||
xallocx_success_c = (xallocx(p, huge0 * 2, 0, flags) == huge0 * 2);
|
||||
assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
|
||||
if (xallocx_success_b && xallocx_success_c)
|
||||
assert_true(did_merge, "Expected merge");
|
||||
dallocx(p, flags);
|
||||
do_dalloc = true;
|
||||
do_decommit = false;
|
||||
|
||||
/* Test purge for partial-chunk huge allocations. */
|
||||
if (huge0 * 2 > huge2) {
|
||||
/*
|
||||
* There are at least four size classes per doubling, so a
|
||||
* successful xallocx() from size=huge2 to size=huge1 is
|
||||
* guaranteed to leave trailing purgeable memory.
|
||||
*/
|
||||
p = mallocx(huge2, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
did_purge = false;
|
||||
assert_zu_eq(xallocx(p, huge1, 0, flags), huge1,
|
||||
"Unexpected xallocx() failure");
|
||||
assert_true(did_purge, "Expected purge");
|
||||
dallocx(p, flags);
|
||||
}
|
||||
|
||||
/* Test decommit for large allocations. */
|
||||
do_decommit = true;
|
||||
p = mallocx(large1, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
assert_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
||||
0, "Unexpected arena.%u.purge error", arena_ind);
|
||||
did_decommit = false;
|
||||
assert_zu_eq(xallocx(p, large0, 0, flags), large0,
|
||||
"Unexpected xallocx() failure");
|
||||
assert_d_eq(mallctlbymib(purge_mib, purge_miblen, NULL, NULL, NULL, 0),
|
||||
0, "Unexpected arena.%u.purge error", arena_ind);
|
||||
did_commit = false;
|
||||
assert_zu_eq(xallocx(p, large1, 0, flags), large1,
|
||||
"Unexpected xallocx() failure");
|
||||
assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match");
|
||||
dallocx(p, flags);
|
||||
do_decommit = false;
|
||||
|
||||
/* Make sure non-huge allocation succeeds. */
|
||||
p = mallocx(42, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
dallocx(p, flags);
|
||||
|
||||
/* Restore chunk hooks. */
|
||||
assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, NULL, NULL,
|
||||
&old_hooks, new_size), 0, "Unexpected chunk_hooks error");
|
||||
assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, &old_hooks, &old_size,
|
||||
NULL, 0), 0, "Unexpected chunk_hooks error");
|
||||
assert_ptr_eq(old_hooks.alloc, orig_hooks.alloc,
|
||||
"Unexpected alloc error");
|
||||
assert_ptr_eq(old_hooks.dalloc, orig_hooks.dalloc,
|
||||
"Unexpected dalloc error");
|
||||
assert_ptr_eq(old_hooks.commit, orig_hooks.commit,
|
||||
"Unexpected commit error");
|
||||
assert_ptr_eq(old_hooks.decommit, orig_hooks.decommit,
|
||||
"Unexpected decommit error");
|
||||
assert_ptr_eq(old_hooks.purge, orig_hooks.purge,
|
||||
"Unexpected purge error");
|
||||
assert_ptr_eq(old_hooks.split, orig_hooks.split,
|
||||
"Unexpected split error");
|
||||
assert_ptr_eq(old_hooks.merge, orig_hooks.merge,
|
||||
"Unexpected merge error");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(test_chunk));
|
||||
}
|
||||
234
memory/jemalloc/src/test/integration/mallocx.c
Normal file
234
memory/jemalloc/src/test/integration/mallocx.c
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf = "junk:false";
|
||||
#endif
|
||||
|
||||
static unsigned
|
||||
get_nsizes_impl(const char *cmd)
|
||||
{
|
||||
unsigned ret;
|
||||
size_t z;
|
||||
|
||||
z = sizeof(unsigned);
|
||||
assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
|
||||
"Unexpected mallctl(\"%s\", ...) failure", cmd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nhuge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nhchunks"));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_size_impl(const char *cmd, size_t ind)
|
||||
{
|
||||
size_t ret;
|
||||
size_t z;
|
||||
size_t mib[4];
|
||||
size_t miblen = 4;
|
||||
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
|
||||
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
|
||||
mib[2] = ind;
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
|
||||
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_huge_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.hchunk.0.size", ind));
|
||||
}
|
||||
|
||||
/*
|
||||
* On systems which can't merge extents, tests that call this function generate
|
||||
* a lot of dirty memory very quickly. Purging between cycles mitigates
|
||||
* potential OOM on e.g. 32-bit Windows.
|
||||
*/
|
||||
static void
|
||||
purge(void)
|
||||
{
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl error");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_overflow)
|
||||
{
|
||||
size_t hugemax;
|
||||
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
assert_ptr_null(mallocx(hugemax+1, 0),
|
||||
"Expected OOM for mallocx(size=%#zx, 0)", hugemax+1);
|
||||
|
||||
assert_ptr_null(mallocx(ZU(PTRDIFF_MAX)+1, 0),
|
||||
"Expected OOM for mallocx(size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
|
||||
|
||||
assert_ptr_null(mallocx(SIZE_T_MAX, 0),
|
||||
"Expected OOM for mallocx(size=%#zx, 0)", SIZE_T_MAX);
|
||||
|
||||
assert_ptr_null(mallocx(1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
|
||||
"Expected OOM for mallocx(size=1, MALLOCX_ALIGN(%#zx))",
|
||||
ZU(PTRDIFF_MAX)+1);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_oom)
|
||||
{
|
||||
size_t hugemax;
|
||||
bool oom;
|
||||
void *ptrs[3];
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* It should be impossible to allocate three objects that each consume
|
||||
* nearly half the virtual address space.
|
||||
*/
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
oom = false;
|
||||
for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) {
|
||||
ptrs[i] = mallocx(hugemax, 0);
|
||||
if (ptrs[i] == NULL)
|
||||
oom = true;
|
||||
}
|
||||
assert_true(oom,
|
||||
"Expected OOM during series of calls to mallocx(size=%zu, 0)",
|
||||
hugemax);
|
||||
for (i = 0; i < sizeof(ptrs) / sizeof(void *); i++) {
|
||||
if (ptrs[i] != NULL)
|
||||
dallocx(ptrs[i], 0);
|
||||
}
|
||||
purge();
|
||||
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
assert_ptr_null(mallocx(0x8000000000000000ULL,
|
||||
MALLOCX_ALIGN(0x8000000000000000ULL)),
|
||||
"Expected OOM for mallocx()");
|
||||
assert_ptr_null(mallocx(0x8000000000000000ULL,
|
||||
MALLOCX_ALIGN(0x80000000)),
|
||||
"Expected OOM for mallocx()");
|
||||
#else
|
||||
assert_ptr_null(mallocx(0x80000000UL, MALLOCX_ALIGN(0x80000000UL)),
|
||||
"Expected OOM for mallocx()");
|
||||
#endif
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_basic)
|
||||
{
|
||||
#define MAXSZ (((size_t)1) << 23)
|
||||
size_t sz;
|
||||
|
||||
for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {
|
||||
size_t nsz, rsz;
|
||||
void *p;
|
||||
nsz = nallocx(sz, 0);
|
||||
assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
|
||||
p = mallocx(sz, 0);
|
||||
assert_ptr_not_null(p,
|
||||
"Unexpected mallocx(size=%zx, flags=0) error", sz);
|
||||
rsz = sallocx(p, 0);
|
||||
assert_zu_ge(rsz, sz, "Real size smaller than expected");
|
||||
assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch");
|
||||
dallocx(p, 0);
|
||||
|
||||
p = mallocx(sz, 0);
|
||||
assert_ptr_not_null(p,
|
||||
"Unexpected mallocx(size=%zx, flags=0) error", sz);
|
||||
dallocx(p, 0);
|
||||
|
||||
nsz = nallocx(sz, MALLOCX_ZERO);
|
||||
assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
|
||||
p = mallocx(sz, MALLOCX_ZERO);
|
||||
assert_ptr_not_null(p,
|
||||
"Unexpected mallocx(size=%zx, flags=MALLOCX_ZERO) error",
|
||||
nsz);
|
||||
rsz = sallocx(p, 0);
|
||||
assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch");
|
||||
dallocx(p, 0);
|
||||
purge();
|
||||
}
|
||||
#undef MAXSZ
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_alignment_and_size)
|
||||
{
|
||||
#define MAXALIGN (((size_t)1) << 23)
|
||||
#define NITER 4
|
||||
size_t nsz, rsz, sz, alignment, total;
|
||||
unsigned i;
|
||||
void *ps[NITER];
|
||||
|
||||
for (i = 0; i < NITER; i++)
|
||||
ps[i] = NULL;
|
||||
|
||||
for (alignment = 8;
|
||||
alignment <= MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
total = 0;
|
||||
for (sz = 1;
|
||||
sz < 3 * alignment && sz < (1U << 31);
|
||||
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
||||
for (i = 0; i < NITER; i++) {
|
||||
nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
|
||||
MALLOCX_ZERO);
|
||||
assert_zu_ne(nsz, 0,
|
||||
"nallocx() error for alignment=%zu, "
|
||||
"size=%zu (%#zx)", alignment, sz, sz);
|
||||
ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
|
||||
MALLOCX_ZERO);
|
||||
assert_ptr_not_null(ps[i],
|
||||
"mallocx() error for alignment=%zu, "
|
||||
"size=%zu (%#zx)", alignment, sz, sz);
|
||||
rsz = sallocx(ps[i], 0);
|
||||
assert_zu_ge(rsz, sz,
|
||||
"Real size smaller than expected for "
|
||||
"alignment=%zu, size=%zu", alignment, sz);
|
||||
assert_zu_eq(nsz, rsz,
|
||||
"nallocx()/sallocx() size mismatch for "
|
||||
"alignment=%zu, size=%zu", alignment, sz);
|
||||
assert_ptr_null(
|
||||
(void *)((uintptr_t)ps[i] & (alignment-1)),
|
||||
"%p inadequately aligned for"
|
||||
" alignment=%zu, size=%zu", ps[i],
|
||||
alignment, sz);
|
||||
total += rsz;
|
||||
if (total >= (MAXALIGN << 1))
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < NITER; i++) {
|
||||
if (ps[i] != NULL) {
|
||||
dallocx(ps[i], 0);
|
||||
ps[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
purge();
|
||||
}
|
||||
#undef MAXALIGN
|
||||
#undef NITER
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_overflow,
|
||||
test_oom,
|
||||
test_basic,
|
||||
test_alignment_and_size));
|
||||
}
|
||||
49
memory/jemalloc/src/test/integration/overflow.c
Normal file
49
memory/jemalloc/src/test/integration/overflow.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_overflow)
|
||||
{
|
||||
unsigned nhchunks;
|
||||
size_t mib[4];
|
||||
size_t sz, miblen, max_size_class;
|
||||
void *p;
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() error");
|
||||
|
||||
miblen = sizeof(mib) / sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() error");
|
||||
mib[2] = nhchunks - 1;
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctlbymib() error");
|
||||
|
||||
assert_ptr_null(malloc(max_size_class + 1),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
assert_ptr_null(malloc(SIZE_T_MAX),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
|
||||
assert_ptr_null(calloc(1, max_size_class + 1),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
assert_ptr_null(calloc(1, SIZE_T_MAX),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() OOM");
|
||||
assert_ptr_null(realloc(p, max_size_class + 1),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
assert_ptr_null(realloc(p, SIZE_T_MAX),
|
||||
"Expected OOM due to over-sized allocation request");
|
||||
free(p);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_overflow));
|
||||
}
|
||||
133
memory/jemalloc/src/test/integration/posix_memalign.c
Normal file
133
memory/jemalloc/src/test/integration/posix_memalign.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define CHUNK 0x400000
|
||||
#define MAXALIGN (((size_t)1) << 23)
|
||||
|
||||
/*
|
||||
* On systems which can't merge extents, tests that call this function generate
|
||||
* a lot of dirty memory very quickly. Purging between cycles mitigates
|
||||
* potential OOM on e.g. 32-bit Windows.
|
||||
*/
|
||||
static void
|
||||
purge(void)
|
||||
{
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl error");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_alignment_errors)
|
||||
{
|
||||
size_t alignment;
|
||||
void *p;
|
||||
|
||||
for (alignment = 0; alignment < sizeof(void *); alignment++) {
|
||||
assert_d_eq(posix_memalign(&p, alignment, 1), EINVAL,
|
||||
"Expected error for invalid alignment %zu",
|
||||
alignment);
|
||||
}
|
||||
|
||||
for (alignment = sizeof(size_t); alignment < MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
assert_d_ne(posix_memalign(&p, alignment + 1, 1), 0,
|
||||
"Expected error for invalid alignment %zu",
|
||||
alignment + 1);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_oom_errors)
|
||||
{
|
||||
size_t alignment, size;
|
||||
void *p;
|
||||
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
alignment = UINT64_C(0x8000000000000000);
|
||||
size = UINT64_C(0x8000000000000000);
|
||||
#else
|
||||
alignment = 0x80000000LU;
|
||||
size = 0x80000000LU;
|
||||
#endif
|
||||
assert_d_ne(posix_memalign(&p, alignment, size), 0,
|
||||
"Expected error for posix_memalign(&p, %zu, %zu)",
|
||||
alignment, size);
|
||||
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
alignment = UINT64_C(0x4000000000000000);
|
||||
size = UINT64_C(0xc000000000000001);
|
||||
#else
|
||||
alignment = 0x40000000LU;
|
||||
size = 0xc0000001LU;
|
||||
#endif
|
||||
assert_d_ne(posix_memalign(&p, alignment, size), 0,
|
||||
"Expected error for posix_memalign(&p, %zu, %zu)",
|
||||
alignment, size);
|
||||
|
||||
alignment = 0x10LU;
|
||||
#if LG_SIZEOF_PTR == 3
|
||||
size = UINT64_C(0xfffffffffffffff0);
|
||||
#else
|
||||
size = 0xfffffff0LU;
|
||||
#endif
|
||||
assert_d_ne(posix_memalign(&p, alignment, size), 0,
|
||||
"Expected error for posix_memalign(&p, %zu, %zu)",
|
||||
alignment, size);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_alignment_and_size)
|
||||
{
|
||||
#define NITER 4
|
||||
size_t alignment, size, total;
|
||||
unsigned i;
|
||||
int err;
|
||||
void *ps[NITER];
|
||||
|
||||
for (i = 0; i < NITER; i++)
|
||||
ps[i] = NULL;
|
||||
|
||||
for (alignment = 8;
|
||||
alignment <= MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
total = 0;
|
||||
for (size = 1;
|
||||
size < 3 * alignment && size < (1U << 31);
|
||||
size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
||||
for (i = 0; i < NITER; i++) {
|
||||
err = posix_memalign(&ps[i],
|
||||
alignment, size);
|
||||
if (err) {
|
||||
char buf[BUFERROR_BUF];
|
||||
|
||||
buferror(get_errno(), buf, sizeof(buf));
|
||||
test_fail(
|
||||
"Error for alignment=%zu, "
|
||||
"size=%zu (%#zx): %s",
|
||||
alignment, size, size, buf);
|
||||
}
|
||||
total += malloc_usable_size(ps[i]);
|
||||
if (total >= (MAXALIGN << 1))
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < NITER; i++) {
|
||||
if (ps[i] != NULL) {
|
||||
free(ps[i]);
|
||||
ps[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
purge();
|
||||
}
|
||||
#undef NITER
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_alignment_errors,
|
||||
test_oom_errors,
|
||||
test_alignment_and_size));
|
||||
}
|
||||
259
memory/jemalloc/src/test/integration/rallocx.c
Normal file
259
memory/jemalloc/src/test/integration/rallocx.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static unsigned
|
||||
get_nsizes_impl(const char *cmd)
|
||||
{
|
||||
unsigned ret;
|
||||
size_t z;
|
||||
|
||||
z = sizeof(unsigned);
|
||||
assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
|
||||
"Unexpected mallctl(\"%s\", ...) failure", cmd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nhuge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nhchunks"));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_size_impl(const char *cmd, size_t ind)
|
||||
{
|
||||
size_t ret;
|
||||
size_t z;
|
||||
size_t mib[4];
|
||||
size_t miblen = 4;
|
||||
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
|
||||
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
|
||||
mib[2] = ind;
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
|
||||
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_huge_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.hchunk.0.size", ind));
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_grow_and_shrink)
|
||||
{
|
||||
void *p, *q;
|
||||
size_t tsz;
|
||||
#define NCYCLES 3
|
||||
unsigned i, j;
|
||||
#define NSZS 2500
|
||||
size_t szs[NSZS];
|
||||
#define MAXSZ ZU(12 * 1024 * 1024)
|
||||
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
szs[0] = sallocx(p, 0);
|
||||
|
||||
for (i = 0; i < NCYCLES; i++) {
|
||||
for (j = 1; j < NSZS && szs[j-1] < MAXSZ; j++) {
|
||||
q = rallocx(p, szs[j-1]+1, 0);
|
||||
assert_ptr_not_null(q,
|
||||
"Unexpected rallocx() error for size=%zu-->%zu",
|
||||
szs[j-1], szs[j-1]+1);
|
||||
szs[j] = sallocx(q, 0);
|
||||
assert_zu_ne(szs[j], szs[j-1]+1,
|
||||
"Expected size to be at least: %zu", szs[j-1]+1);
|
||||
p = q;
|
||||
}
|
||||
|
||||
for (j--; j > 0; j--) {
|
||||
q = rallocx(p, szs[j-1], 0);
|
||||
assert_ptr_not_null(q,
|
||||
"Unexpected rallocx() error for size=%zu-->%zu",
|
||||
szs[j], szs[j-1]);
|
||||
tsz = sallocx(q, 0);
|
||||
assert_zu_eq(tsz, szs[j-1],
|
||||
"Expected size=%zu, got size=%zu", szs[j-1], tsz);
|
||||
p = q;
|
||||
}
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
#undef MAXSZ
|
||||
#undef NSZS
|
||||
#undef NCYCLES
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static bool
|
||||
validate_fill(const void *p, uint8_t c, size_t offset, size_t len)
|
||||
{
|
||||
bool ret = false;
|
||||
const uint8_t *buf = (const uint8_t *)p;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
uint8_t b = buf[offset+i];
|
||||
if (b != c) {
|
||||
test_fail("Allocation at %p (len=%zu) contains %#x "
|
||||
"rather than %#x at offset %zu", p, len, b, c,
|
||||
offset+i);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_zero)
|
||||
{
|
||||
void *p, *q;
|
||||
size_t psz, qsz, i, j;
|
||||
size_t start_sizes[] = {1, 3*1024, 63*1024, 4095*1024};
|
||||
#define FILL_BYTE 0xaaU
|
||||
#define RANGE 2048
|
||||
|
||||
for (i = 0; i < sizeof(start_sizes)/sizeof(size_t); i++) {
|
||||
size_t start_size = start_sizes[i];
|
||||
p = mallocx(start_size, MALLOCX_ZERO);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
psz = sallocx(p, 0);
|
||||
|
||||
assert_false(validate_fill(p, 0, 0, psz),
|
||||
"Expected zeroed memory");
|
||||
memset(p, FILL_BYTE, psz);
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, psz),
|
||||
"Expected filled memory");
|
||||
|
||||
for (j = 1; j < RANGE; j++) {
|
||||
q = rallocx(p, start_size+j, MALLOCX_ZERO);
|
||||
assert_ptr_not_null(q, "Unexpected rallocx() error");
|
||||
qsz = sallocx(q, 0);
|
||||
if (q != p || qsz != psz) {
|
||||
assert_false(validate_fill(q, FILL_BYTE, 0,
|
||||
psz), "Expected filled memory");
|
||||
assert_false(validate_fill(q, 0, psz, qsz-psz),
|
||||
"Expected zeroed memory");
|
||||
}
|
||||
if (psz != qsz) {
|
||||
memset((void *)((uintptr_t)q+psz), FILL_BYTE,
|
||||
qsz-psz);
|
||||
psz = qsz;
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, psz),
|
||||
"Expected filled memory");
|
||||
dallocx(p, 0);
|
||||
}
|
||||
#undef FILL_BYTE
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_align)
|
||||
{
|
||||
void *p, *q;
|
||||
size_t align;
|
||||
#define MAX_ALIGN (ZU(1) << 25)
|
||||
|
||||
align = ZU(1);
|
||||
p = mallocx(1, MALLOCX_ALIGN(align));
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
for (align <<= 1; align <= MAX_ALIGN; align <<= 1) {
|
||||
q = rallocx(p, 1, MALLOCX_ALIGN(align));
|
||||
assert_ptr_not_null(q,
|
||||
"Unexpected rallocx() error for align=%zu", align);
|
||||
assert_ptr_null(
|
||||
(void *)((uintptr_t)q & (align-1)),
|
||||
"%p inadequately aligned for align=%zu",
|
||||
q, align);
|
||||
p = q;
|
||||
}
|
||||
dallocx(p, 0);
|
||||
#undef MAX_ALIGN
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_lg_align_and_zero)
|
||||
{
|
||||
void *p, *q;
|
||||
unsigned lg_align;
|
||||
size_t sz;
|
||||
#define MAX_LG_ALIGN 25
|
||||
#define MAX_VALIDATE (ZU(1) << 22)
|
||||
|
||||
lg_align = 0;
|
||||
p = mallocx(1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
for (lg_align++; lg_align <= MAX_LG_ALIGN; lg_align++) {
|
||||
q = rallocx(p, 1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
|
||||
assert_ptr_not_null(q,
|
||||
"Unexpected rallocx() error for lg_align=%u", lg_align);
|
||||
assert_ptr_null(
|
||||
(void *)((uintptr_t)q & ((ZU(1) << lg_align)-1)),
|
||||
"%p inadequately aligned for lg_align=%u", q, lg_align);
|
||||
sz = sallocx(q, 0);
|
||||
if ((sz << 1) <= MAX_VALIDATE) {
|
||||
assert_false(validate_fill(q, 0, 0, sz),
|
||||
"Expected zeroed memory");
|
||||
} else {
|
||||
assert_false(validate_fill(q, 0, 0, MAX_VALIDATE),
|
||||
"Expected zeroed memory");
|
||||
assert_false(validate_fill(
|
||||
(void *)((uintptr_t)q+sz-MAX_VALIDATE),
|
||||
0, 0, MAX_VALIDATE), "Expected zeroed memory");
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
dallocx(p, 0);
|
||||
#undef MAX_VALIDATE
|
||||
#undef MAX_LG_ALIGN
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_overflow)
|
||||
{
|
||||
size_t hugemax;
|
||||
void *p;
|
||||
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_ptr_null(rallocx(p, hugemax+1, 0),
|
||||
"Expected OOM for rallocx(p, size=%#zx, 0)", hugemax+1);
|
||||
|
||||
assert_ptr_null(rallocx(p, ZU(PTRDIFF_MAX)+1, 0),
|
||||
"Expected OOM for rallocx(p, size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
|
||||
|
||||
assert_ptr_null(rallocx(p, SIZE_T_MAX, 0),
|
||||
"Expected OOM for rallocx(p, size=%#zx, 0)", SIZE_T_MAX);
|
||||
|
||||
assert_ptr_null(rallocx(p, 1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
|
||||
"Expected OOM for rallocx(p, size=1, MALLOCX_ALIGN(%#zx))",
|
||||
ZU(PTRDIFF_MAX)+1);
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_grow_and_shrink,
|
||||
test_zero,
|
||||
test_align,
|
||||
test_lg_align_and_zero,
|
||||
test_overflow));
|
||||
}
|
||||
57
memory/jemalloc/src/test/integration/sdallocx.c
Normal file
57
memory/jemalloc/src/test/integration/sdallocx.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define MAXALIGN (((size_t)1) << 25)
|
||||
#define NITER 4
|
||||
|
||||
TEST_BEGIN(test_basic)
|
||||
{
|
||||
void *ptr = mallocx(64, 0);
|
||||
sdallocx(ptr, 64, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_alignment_and_size)
|
||||
{
|
||||
size_t nsz, sz, alignment, total;
|
||||
unsigned i;
|
||||
void *ps[NITER];
|
||||
|
||||
for (i = 0; i < NITER; i++)
|
||||
ps[i] = NULL;
|
||||
|
||||
for (alignment = 8;
|
||||
alignment <= MAXALIGN;
|
||||
alignment <<= 1) {
|
||||
total = 0;
|
||||
for (sz = 1;
|
||||
sz < 3 * alignment && sz < (1U << 31);
|
||||
sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
|
||||
for (i = 0; i < NITER; i++) {
|
||||
nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
|
||||
MALLOCX_ZERO);
|
||||
ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
|
||||
MALLOCX_ZERO);
|
||||
total += nsz;
|
||||
if (total >= (MAXALIGN << 1))
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < NITER; i++) {
|
||||
if (ps[i] != NULL) {
|
||||
sdallocx(ps[i], sz,
|
||||
MALLOCX_ALIGN(alignment));
|
||||
ps[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_basic,
|
||||
test_alignment_and_size));
|
||||
}
|
||||
79
memory/jemalloc/src/test/integration/thread_arena.c
Normal file
79
memory/jemalloc/src/test/integration/thread_arena.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 10
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
unsigned main_arena_ind = *(unsigned *)arg;
|
||||
void *p;
|
||||
unsigned arena_ind;
|
||||
size_t size;
|
||||
int err;
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Error in malloc()");
|
||||
free(p);
|
||||
|
||||
size = sizeof(arena_ind);
|
||||
if ((err = mallctl("thread.arena", &arena_ind, &size, &main_arena_ind,
|
||||
sizeof(main_arena_ind)))) {
|
||||
char buf[BUFERROR_BUF];
|
||||
|
||||
buferror(err, buf, sizeof(buf));
|
||||
test_fail("Error in mallctl(): %s", buf);
|
||||
}
|
||||
|
||||
size = sizeof(arena_ind);
|
||||
if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) {
|
||||
char buf[BUFERROR_BUF];
|
||||
|
||||
buferror(err, buf, sizeof(buf));
|
||||
test_fail("Error in mallctl(): %s", buf);
|
||||
}
|
||||
assert_u_eq(arena_ind, main_arena_ind,
|
||||
"Arena index should be same as for main thread");
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_thread_arena)
|
||||
{
|
||||
void *p;
|
||||
unsigned arena_ind;
|
||||
size_t size;
|
||||
int err;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Error in malloc()");
|
||||
|
||||
size = sizeof(arena_ind);
|
||||
if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) {
|
||||
char buf[BUFERROR_BUF];
|
||||
|
||||
buferror(err, buf, sizeof(buf));
|
||||
test_fail("Error in mallctl(): %s", buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
thd_create(&thds[i], thd_start,
|
||||
(void *)&arena_ind);
|
||||
}
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
intptr_t join_ret;
|
||||
thd_join(thds[i], (void *)&join_ret);
|
||||
assert_zd_eq(join_ret, 0, "Unexpected thread join error");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_thread_arena));
|
||||
}
|
||||
113
memory/jemalloc/src/test/integration/thread_tcache_enabled.c
Normal file
113
memory/jemalloc/src/test/integration/thread_tcache_enabled.c
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static const bool config_tcache =
|
||||
#ifdef JEMALLOC_TCACHE
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
;
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
int err;
|
||||
size_t sz;
|
||||
bool e0, e1;
|
||||
|
||||
sz = sizeof(bool);
|
||||
if ((err = mallctl("thread.tcache.enabled", &e0, &sz, NULL, 0))) {
|
||||
if (err == ENOENT) {
|
||||
assert_false(config_tcache,
|
||||
"ENOENT should only be returned if tcache is "
|
||||
"disabled");
|
||||
}
|
||||
goto label_ENOENT;
|
||||
}
|
||||
|
||||
if (e0) {
|
||||
e1 = false;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz),
|
||||
0, "Unexpected mallctl() error");
|
||||
assert_true(e0, "tcache should be enabled");
|
||||
}
|
||||
|
||||
e1 = true;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_false(e0, "tcache should be disabled");
|
||||
|
||||
e1 = true;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_true(e0, "tcache should be enabled");
|
||||
|
||||
e1 = false;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_true(e0, "tcache should be enabled");
|
||||
|
||||
e1 = false;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_false(e0, "tcache should be disabled");
|
||||
|
||||
free(malloc(1));
|
||||
e1 = true;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_false(e0, "tcache should be disabled");
|
||||
|
||||
free(malloc(1));
|
||||
e1 = true;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_true(e0, "tcache should be enabled");
|
||||
|
||||
free(malloc(1));
|
||||
e1 = false;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_true(e0, "tcache should be enabled");
|
||||
|
||||
free(malloc(1));
|
||||
e1 = false;
|
||||
assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0,
|
||||
"Unexpected mallctl() error");
|
||||
assert_false(e0, "tcache should be disabled");
|
||||
|
||||
free(malloc(1));
|
||||
return (NULL);
|
||||
label_ENOENT:
|
||||
test_skip("\"thread.tcache.enabled\" mallctl not available");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_main_thread)
|
||||
{
|
||||
|
||||
thd_start(NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_subthread)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
thd_create(&thd, thd_start, NULL);
|
||||
thd_join(thd, NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
/* Run tests multiple times to check for bad interactions. */
|
||||
return (test(
|
||||
test_main_thread,
|
||||
test_subthread,
|
||||
test_main_thread,
|
||||
test_subthread,
|
||||
test_main_thread));
|
||||
}
|
||||
497
memory/jemalloc/src/test/integration/xallocx.c
Normal file
497
memory/jemalloc/src/test/integration/xallocx.c
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf = "junk:false";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use a separate arena for xallocx() extension/contraction tests so that
|
||||
* internal allocation e.g. by heap profiling can't interpose allocations where
|
||||
* xallocx() would ordinarily be able to extend.
|
||||
*/
|
||||
static unsigned
|
||||
arena_ind(void)
|
||||
{
|
||||
static unsigned ind = 0;
|
||||
|
||||
if (ind == 0) {
|
||||
size_t sz = sizeof(ind);
|
||||
assert_d_eq(mallctl("arenas.extend", &ind, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure creating arena");
|
||||
}
|
||||
|
||||
return (ind);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_same_size)
|
||||
{
|
||||
void *p;
|
||||
size_t sz, tsz;
|
||||
|
||||
p = mallocx(42, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
sz = sallocx(p, 0);
|
||||
|
||||
tsz = xallocx(p, sz, 0, 0);
|
||||
assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_extra_no_move)
|
||||
{
|
||||
void *p;
|
||||
size_t sz, tsz;
|
||||
|
||||
p = mallocx(42, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
sz = sallocx(p, 0);
|
||||
|
||||
tsz = xallocx(p, sz, sz-42, 0);
|
||||
assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_no_move_fail)
|
||||
{
|
||||
void *p;
|
||||
size_t sz, tsz;
|
||||
|
||||
p = mallocx(42, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
sz = sallocx(p, 0);
|
||||
|
||||
tsz = xallocx(p, sz + 5, 0, 0);
|
||||
assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz);
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static unsigned
|
||||
get_nsizes_impl(const char *cmd)
|
||||
{
|
||||
unsigned ret;
|
||||
size_t z;
|
||||
|
||||
z = sizeof(unsigned);
|
||||
assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
|
||||
"Unexpected mallctl(\"%s\", ...) failure", cmd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nsmall(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nbins"));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nlarge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nlruns"));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nhuge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nhchunks"));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_size_impl(const char *cmd, size_t ind)
|
||||
{
|
||||
size_t ret;
|
||||
size_t z;
|
||||
size_t mib[4];
|
||||
size_t miblen = 4;
|
||||
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
|
||||
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
|
||||
mib[2] = ind;
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
|
||||
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_small_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.bin.0.size", ind));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_large_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.lrun.0.size", ind));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_huge_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.hchunk.0.size", ind));
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_size)
|
||||
{
|
||||
size_t small0, hugemax;
|
||||
void *p;
|
||||
|
||||
/* Get size classes. */
|
||||
small0 = get_small_size(0);
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(small0, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
/* Test smallest supported size. */
|
||||
assert_zu_eq(xallocx(p, 1, 0, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
/* Test largest supported size. */
|
||||
assert_zu_le(xallocx(p, hugemax, 0, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
/* Test size overflow. */
|
||||
assert_zu_le(xallocx(p, hugemax+1, 0, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, SIZE_T_MAX, 0, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_size_extra_overflow)
|
||||
{
|
||||
size_t small0, hugemax;
|
||||
void *p;
|
||||
|
||||
/* Get size classes. */
|
||||
small0 = get_small_size(0);
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(small0, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
/* Test overflows that can be resolved by clamping extra. */
|
||||
assert_zu_le(xallocx(p, hugemax-1, 2, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, hugemax, 1, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
/* Test overflow such that hugemax-size underflows. */
|
||||
assert_zu_le(xallocx(p, hugemax+1, 2, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, hugemax+2, 3, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, SIZE_T_MAX-2, 2, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, SIZE_T_MAX-1, 1, 0), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_extra_small)
|
||||
{
|
||||
size_t small0, small1, hugemax;
|
||||
void *p;
|
||||
|
||||
/* Get size classes. */
|
||||
small0 = get_small_size(0);
|
||||
small1 = get_small_size(1);
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(small0, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
assert_zu_eq(xallocx(p, small1, 0, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, small1, 0, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
/* Test size+extra overflow. */
|
||||
assert_zu_eq(xallocx(p, small0, hugemax - small0 + 1, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, small0, SIZE_T_MAX - small0, 0), small0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_extra_large)
|
||||
{
|
||||
int flags = MALLOCX_ARENA(arena_ind());
|
||||
size_t smallmax, large0, large1, large2, huge0, hugemax;
|
||||
void *p;
|
||||
|
||||
/* Get size classes. */
|
||||
smallmax = get_small_size(get_nsmall()-1);
|
||||
large0 = get_large_size(0);
|
||||
large1 = get_large_size(1);
|
||||
large2 = get_large_size(2);
|
||||
huge0 = get_huge_size(0);
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(large2, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
assert_zu_eq(xallocx(p, large2, 0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size decrease with zero extra. */
|
||||
assert_zu_eq(xallocx(p, large0, 0, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, smallmax, 0, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, large2, 0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size decrease with non-zero extra. */
|
||||
assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, large1, large2 - large1, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, large0, large1 - large0, flags), large1,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, smallmax, large0 - smallmax, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, large0, 0, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with zero extra. */
|
||||
assert_zu_eq(xallocx(p, large2, 0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, huge0, 0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, large0, 0, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with non-zero extra. */
|
||||
assert_zu_lt(xallocx(p, large0, huge0 - large0, flags), huge0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, large0, 0, flags), large0,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with non-zero extra. */
|
||||
assert_zu_eq(xallocx(p, large0, large2 - large0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, large2, 0, flags), large2,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size+extra overflow. */
|
||||
assert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, flags), huge0,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
dallocx(p, flags);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_extra_huge)
|
||||
{
|
||||
int flags = MALLOCX_ARENA(arena_ind());
|
||||
size_t largemax, huge1, huge2, huge3, hugemax;
|
||||
void *p;
|
||||
|
||||
/* Get size classes. */
|
||||
largemax = get_large_size(get_nlarge()-1);
|
||||
huge1 = get_huge_size(1);
|
||||
huge2 = get_huge_size(2);
|
||||
huge3 = get_huge_size(3);
|
||||
hugemax = get_huge_size(get_nhuge()-1);
|
||||
|
||||
p = mallocx(huge3, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
|
||||
assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size decrease with zero extra. */
|
||||
assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_ge(xallocx(p, largemax, 0, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size decrease with non-zero extra. */
|
||||
assert_zu_eq(xallocx(p, huge1, huge3 - huge1, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, huge2, huge3 - huge2, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_eq(xallocx(p, huge1, huge2 - huge1, flags), huge2,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_ge(xallocx(p, largemax, huge1 - largemax, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with zero extra. */
|
||||
assert_zu_le(xallocx(p, huge3, 0, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
assert_zu_le(xallocx(p, hugemax+1, 0, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with non-zero extra. */
|
||||
assert_zu_le(xallocx(p, huge1, SIZE_T_MAX - huge1, flags), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_ge(xallocx(p, huge1, 0, flags), huge1,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size increase with non-zero extra. */
|
||||
assert_zu_le(xallocx(p, huge1, huge3 - huge1, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
assert_zu_eq(xallocx(p, huge3, 0, flags), huge3,
|
||||
"Unexpected xallocx() behavior");
|
||||
/* Test size+extra overflow. */
|
||||
assert_zu_le(xallocx(p, huge3, hugemax - huge3 + 1, flags), hugemax,
|
||||
"Unexpected xallocx() behavior");
|
||||
|
||||
dallocx(p, flags);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
print_filled_extents(const void *p, uint8_t c, size_t len)
|
||||
{
|
||||
const uint8_t *pc = (const uint8_t *)p;
|
||||
size_t i, range0;
|
||||
uint8_t c0;
|
||||
|
||||
malloc_printf(" p=%p, c=%#x, len=%zu:", p, c, len);
|
||||
range0 = 0;
|
||||
c0 = pc[0];
|
||||
for (i = 0; i < len; i++) {
|
||||
if (pc[i] != c0) {
|
||||
malloc_printf(" %#x[%zu..%zu)", c0, range0, i);
|
||||
range0 = i;
|
||||
c0 = pc[i];
|
||||
}
|
||||
}
|
||||
malloc_printf(" %#x[%zu..%zu)\n", c0, range0, i);
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_fill(const void *p, uint8_t c, size_t offset, size_t len)
|
||||
{
|
||||
const uint8_t *pc = (const uint8_t *)p;
|
||||
bool err;
|
||||
size_t i;
|
||||
|
||||
for (i = offset, err = false; i < offset+len; i++) {
|
||||
if (pc[i] != c)
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (err)
|
||||
print_filled_extents(p, c, offset + len);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static void
|
||||
test_zero(size_t szmin, size_t szmax)
|
||||
{
|
||||
int flags = MALLOCX_ARENA(arena_ind()) | MALLOCX_ZERO;
|
||||
size_t sz, nsz;
|
||||
void *p;
|
||||
#define FILL_BYTE 0x7aU
|
||||
|
||||
sz = szmax;
|
||||
p = mallocx(sz, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() error");
|
||||
assert_false(validate_fill(p, 0x00, 0, sz), "Memory not filled: sz=%zu",
|
||||
sz);
|
||||
|
||||
/*
|
||||
* Fill with non-zero so that non-debug builds are more likely to detect
|
||||
* errors.
|
||||
*/
|
||||
memset(p, FILL_BYTE, sz);
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, sz),
|
||||
"Memory not filled: sz=%zu", sz);
|
||||
|
||||
/* Shrink in place so that we can expect growing in place to succeed. */
|
||||
sz = szmin;
|
||||
assert_zu_eq(xallocx(p, sz, 0, flags), sz,
|
||||
"Unexpected xallocx() error");
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, sz),
|
||||
"Memory not filled: sz=%zu", sz);
|
||||
|
||||
for (sz = szmin; sz < szmax; sz = nsz) {
|
||||
nsz = nallocx(sz+1, flags);
|
||||
assert_zu_eq(xallocx(p, sz+1, 0, flags), nsz,
|
||||
"Unexpected xallocx() failure");
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, sz),
|
||||
"Memory not filled: sz=%zu", sz);
|
||||
assert_false(validate_fill(p, 0x00, sz, nsz-sz),
|
||||
"Memory not filled: sz=%zu, nsz-sz=%zu", sz, nsz-sz);
|
||||
memset((void *)((uintptr_t)p + sz), FILL_BYTE, nsz-sz);
|
||||
assert_false(validate_fill(p, FILL_BYTE, 0, nsz),
|
||||
"Memory not filled: nsz=%zu", nsz);
|
||||
}
|
||||
|
||||
dallocx(p, flags);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_zero_large)
|
||||
{
|
||||
size_t large0, largemax;
|
||||
|
||||
/* Get size classes. */
|
||||
large0 = get_large_size(0);
|
||||
largemax = get_large_size(get_nlarge()-1);
|
||||
|
||||
test_zero(large0, largemax);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_zero_huge)
|
||||
{
|
||||
size_t huge0, huge1;
|
||||
|
||||
/* Get size classes. */
|
||||
huge0 = get_huge_size(0);
|
||||
huge1 = get_huge_size(1);
|
||||
|
||||
test_zero(huge1, huge0 * 2);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_same_size,
|
||||
test_extra_no_move,
|
||||
test_no_move_fail,
|
||||
test_size,
|
||||
test_size_extra_overflow,
|
||||
test_extra_small,
|
||||
test_extra_large,
|
||||
test_extra_huge,
|
||||
test_zero_large,
|
||||
test_zero_huge));
|
||||
}
|
||||
719
memory/jemalloc/src/test/src/SFMT.c
Normal file
719
memory/jemalloc/src/test/src/SFMT.c
Normal file
|
|
@ -0,0 +1,719 @@
|
|||
/*
|
||||
* This file derives from SFMT 1.3.3
|
||||
* (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
|
||||
* released under the terms of the following license:
|
||||
*
|
||||
* Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of the Hiroshima University nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/**
|
||||
* @file SFMT.c
|
||||
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
|
||||
*
|
||||
* @author Mutsuo Saito (Hiroshima University)
|
||||
* @author Makoto Matsumoto (Hiroshima University)
|
||||
*
|
||||
* Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
||||
* University. All rights reserved.
|
||||
*
|
||||
* The new BSD License is applied to this software, see LICENSE.txt
|
||||
*/
|
||||
#define SFMT_C_
|
||||
#include "test/jemalloc_test.h"
|
||||
#include "test/SFMT-params.h"
|
||||
|
||||
#if defined(JEMALLOC_BIG_ENDIAN) && !defined(BIG_ENDIAN64)
|
||||
#define BIG_ENDIAN64 1
|
||||
#endif
|
||||
#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
|
||||
#define BIG_ENDIAN64 1
|
||||
#endif
|
||||
#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
|
||||
#define BIG_ENDIAN64 1
|
||||
#endif
|
||||
#if defined(ONLY64) && !defined(BIG_ENDIAN64)
|
||||
#if defined(__GNUC__)
|
||||
#error "-DONLY64 must be specified with -DBIG_ENDIAN64"
|
||||
#endif
|
||||
#undef ONLY64
|
||||
#endif
|
||||
/*------------------------------------------------------
|
||||
128-bit SIMD data type for Altivec, SSE2 or standard C
|
||||
------------------------------------------------------*/
|
||||
#if defined(HAVE_ALTIVEC)
|
||||
/** 128-bit data structure */
|
||||
union W128_T {
|
||||
vector unsigned int s;
|
||||
uint32_t u[4];
|
||||
};
|
||||
/** 128-bit data type */
|
||||
typedef union W128_T w128_t;
|
||||
|
||||
#elif defined(HAVE_SSE2)
|
||||
/** 128-bit data structure */
|
||||
union W128_T {
|
||||
__m128i si;
|
||||
uint32_t u[4];
|
||||
};
|
||||
/** 128-bit data type */
|
||||
typedef union W128_T w128_t;
|
||||
|
||||
#else
|
||||
|
||||
/** 128-bit data structure */
|
||||
struct W128_T {
|
||||
uint32_t u[4];
|
||||
};
|
||||
/** 128-bit data type */
|
||||
typedef struct W128_T w128_t;
|
||||
|
||||
#endif
|
||||
|
||||
struct sfmt_s {
|
||||
/** the 128-bit internal state array */
|
||||
w128_t sfmt[N];
|
||||
/** index counter to the 32-bit internal state array */
|
||||
int idx;
|
||||
/** a flag: it is 0 if and only if the internal state is not yet
|
||||
* initialized. */
|
||||
int initialized;
|
||||
};
|
||||
|
||||
/*--------------------------------------
|
||||
FILE GLOBAL VARIABLES
|
||||
internal state, index counter and flag
|
||||
--------------------------------------*/
|
||||
|
||||
/** a parity check vector which certificate the period of 2^{MEXP} */
|
||||
static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
|
||||
|
||||
/*----------------
|
||||
STATIC FUNCTIONS
|
||||
----------------*/
|
||||
JEMALLOC_INLINE_C int idxof(int i);
|
||||
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
|
||||
JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift);
|
||||
JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift);
|
||||
#endif
|
||||
JEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx);
|
||||
JEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size);
|
||||
JEMALLOC_INLINE_C uint32_t func1(uint32_t x);
|
||||
JEMALLOC_INLINE_C uint32_t func2(uint32_t x);
|
||||
static void period_certification(sfmt_t *ctx);
|
||||
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
|
||||
JEMALLOC_INLINE_C void swap(w128_t *array, int size);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_ALTIVEC)
|
||||
#include "test/SFMT-alti.h"
|
||||
#elif defined(HAVE_SSE2)
|
||||
#include "test/SFMT-sse2.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function simulate a 64-bit index of LITTLE ENDIAN
|
||||
* in BIG ENDIAN machine.
|
||||
*/
|
||||
#ifdef ONLY64
|
||||
JEMALLOC_INLINE_C int idxof(int i) {
|
||||
return i ^ 1;
|
||||
}
|
||||
#else
|
||||
JEMALLOC_INLINE_C int idxof(int i) {
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* This function simulates SIMD 128-bit right shift by the standard C.
|
||||
* The 128-bit integer given in in is shifted by (shift * 8) bits.
|
||||
* This function simulates the LITTLE ENDIAN SIMD.
|
||||
* @param out the output of this function
|
||||
* @param in the 128-bit data to be shifted
|
||||
* @param shift the shift value
|
||||
*/
|
||||
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
|
||||
#ifdef ONLY64
|
||||
JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) {
|
||||
uint64_t th, tl, oh, ol;
|
||||
|
||||
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
|
||||
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
|
||||
|
||||
oh = th >> (shift * 8);
|
||||
ol = tl >> (shift * 8);
|
||||
ol |= th << (64 - shift * 8);
|
||||
out->u[0] = (uint32_t)(ol >> 32);
|
||||
out->u[1] = (uint32_t)ol;
|
||||
out->u[2] = (uint32_t)(oh >> 32);
|
||||
out->u[3] = (uint32_t)oh;
|
||||
}
|
||||
#else
|
||||
JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) {
|
||||
uint64_t th, tl, oh, ol;
|
||||
|
||||
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
|
||||
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
|
||||
|
||||
oh = th >> (shift * 8);
|
||||
ol = tl >> (shift * 8);
|
||||
ol |= th << (64 - shift * 8);
|
||||
out->u[1] = (uint32_t)(ol >> 32);
|
||||
out->u[0] = (uint32_t)ol;
|
||||
out->u[3] = (uint32_t)(oh >> 32);
|
||||
out->u[2] = (uint32_t)oh;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* This function simulates SIMD 128-bit left shift by the standard C.
|
||||
* The 128-bit integer given in in is shifted by (shift * 8) bits.
|
||||
* This function simulates the LITTLE ENDIAN SIMD.
|
||||
* @param out the output of this function
|
||||
* @param in the 128-bit data to be shifted
|
||||
* @param shift the shift value
|
||||
*/
|
||||
#ifdef ONLY64
|
||||
JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) {
|
||||
uint64_t th, tl, oh, ol;
|
||||
|
||||
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
|
||||
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
|
||||
|
||||
oh = th << (shift * 8);
|
||||
ol = tl << (shift * 8);
|
||||
oh |= tl >> (64 - shift * 8);
|
||||
out->u[0] = (uint32_t)(ol >> 32);
|
||||
out->u[1] = (uint32_t)ol;
|
||||
out->u[2] = (uint32_t)(oh >> 32);
|
||||
out->u[3] = (uint32_t)oh;
|
||||
}
|
||||
#else
|
||||
JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) {
|
||||
uint64_t th, tl, oh, ol;
|
||||
|
||||
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
|
||||
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
|
||||
|
||||
oh = th << (shift * 8);
|
||||
ol = tl << (shift * 8);
|
||||
oh |= tl >> (64 - shift * 8);
|
||||
out->u[1] = (uint32_t)(ol >> 32);
|
||||
out->u[0] = (uint32_t)ol;
|
||||
out->u[3] = (uint32_t)(oh >> 32);
|
||||
out->u[2] = (uint32_t)oh;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function represents the recursion formula.
|
||||
* @param r output
|
||||
* @param a a 128-bit part of the internal state array
|
||||
* @param b a 128-bit part of the internal state array
|
||||
* @param c a 128-bit part of the internal state array
|
||||
* @param d a 128-bit part of the internal state array
|
||||
*/
|
||||
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
|
||||
#ifdef ONLY64
|
||||
JEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
|
||||
w128_t *d) {
|
||||
w128_t x;
|
||||
w128_t y;
|
||||
|
||||
lshift128(&x, a, SL2);
|
||||
rshift128(&y, c, SR2);
|
||||
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
|
||||
^ (d->u[0] << SL1);
|
||||
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
|
||||
^ (d->u[1] << SL1);
|
||||
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
|
||||
^ (d->u[2] << SL1);
|
||||
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
|
||||
^ (d->u[3] << SL1);
|
||||
}
|
||||
#else
|
||||
JEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
|
||||
w128_t *d) {
|
||||
w128_t x;
|
||||
w128_t y;
|
||||
|
||||
lshift128(&x, a, SL2);
|
||||
rshift128(&y, c, SR2);
|
||||
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
|
||||
^ (d->u[0] << SL1);
|
||||
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
|
||||
^ (d->u[1] << SL1);
|
||||
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
|
||||
^ (d->u[2] << SL1);
|
||||
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
|
||||
^ (d->u[3] << SL1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
|
||||
/**
|
||||
* This function fills the internal state array with pseudorandom
|
||||
* integers.
|
||||
*/
|
||||
JEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx) {
|
||||
int i;
|
||||
w128_t *r1, *r2;
|
||||
|
||||
r1 = &ctx->sfmt[N - 2];
|
||||
r2 = &ctx->sfmt[N - 1];
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1,
|
||||
r2);
|
||||
r1 = r2;
|
||||
r2 = &ctx->sfmt[i];
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1 - N], r1,
|
||||
r2);
|
||||
r1 = r2;
|
||||
r2 = &ctx->sfmt[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function fills the user-specified array with pseudorandom
|
||||
* integers.
|
||||
*
|
||||
* @param array an 128-bit array to be filled by pseudorandom numbers.
|
||||
* @param size number of 128-bit pseudorandom numbers to be generated.
|
||||
*/
|
||||
JEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {
|
||||
int i, j;
|
||||
w128_t *r1, *r2;
|
||||
|
||||
r1 = &ctx->sfmt[N - 2];
|
||||
r2 = &ctx->sfmt[N - 1];
|
||||
for (i = 0; i < N - POS1; i++) {
|
||||
do_recursion(&array[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1, r2);
|
||||
r1 = r2;
|
||||
r2 = &array[i];
|
||||
}
|
||||
for (; i < N; i++) {
|
||||
do_recursion(&array[i], &ctx->sfmt[i], &array[i + POS1 - N], r1, r2);
|
||||
r1 = r2;
|
||||
r2 = &array[i];
|
||||
}
|
||||
for (; i < size - N; i++) {
|
||||
do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
|
||||
r1 = r2;
|
||||
r2 = &array[i];
|
||||
}
|
||||
for (j = 0; j < 2 * N - size; j++) {
|
||||
ctx->sfmt[j] = array[j + size - N];
|
||||
}
|
||||
for (; i < size; i++, j++) {
|
||||
do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
|
||||
r1 = r2;
|
||||
r2 = &array[i];
|
||||
ctx->sfmt[j] = array[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
|
||||
JEMALLOC_INLINE_C void swap(w128_t *array, int size) {
|
||||
int i;
|
||||
uint32_t x, y;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
x = array[i].u[0];
|
||||
y = array[i].u[2];
|
||||
array[i].u[0] = array[i].u[1];
|
||||
array[i].u[2] = array[i].u[3];
|
||||
array[i].u[1] = x;
|
||||
array[i].u[3] = y;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* This function represents a function used in the initialization
|
||||
* by init_by_array
|
||||
* @param x 32-bit integer
|
||||
* @return 32-bit integer
|
||||
*/
|
||||
static uint32_t func1(uint32_t x) {
|
||||
return (x ^ (x >> 27)) * (uint32_t)1664525UL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function represents a function used in the initialization
|
||||
* by init_by_array
|
||||
* @param x 32-bit integer
|
||||
* @return 32-bit integer
|
||||
*/
|
||||
static uint32_t func2(uint32_t x) {
|
||||
return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function certificate the period of 2^{MEXP}
|
||||
*/
|
||||
static void period_certification(sfmt_t *ctx) {
|
||||
int inner = 0;
|
||||
int i, j;
|
||||
uint32_t work;
|
||||
uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
inner ^= psfmt32[idxof(i)] & parity[i];
|
||||
for (i = 16; i > 0; i >>= 1)
|
||||
inner ^= inner >> i;
|
||||
inner &= 1;
|
||||
/* check OK */
|
||||
if (inner == 1) {
|
||||
return;
|
||||
}
|
||||
/* check NG, and modification */
|
||||
for (i = 0; i < 4; i++) {
|
||||
work = 1;
|
||||
for (j = 0; j < 32; j++) {
|
||||
if ((work & parity[i]) != 0) {
|
||||
psfmt32[idxof(i)] ^= work;
|
||||
return;
|
||||
}
|
||||
work = work << 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------
|
||||
PUBLIC FUNCTIONS
|
||||
----------------*/
|
||||
/**
|
||||
* This function returns the identification string.
|
||||
* The string shows the word size, the Mersenne exponent,
|
||||
* and all parameters of this generator.
|
||||
*/
|
||||
const char *get_idstring(void) {
|
||||
return IDSTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the minimum size of array used for \b
|
||||
* fill_array32() function.
|
||||
* @return minimum size of array used for fill_array32() function.
|
||||
*/
|
||||
int get_min_array_size32(void) {
|
||||
return N32;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the minimum size of array used for \b
|
||||
* fill_array64() function.
|
||||
* @return minimum size of array used for fill_array64() function.
|
||||
*/
|
||||
int get_min_array_size64(void) {
|
||||
return N64;
|
||||
}
|
||||
|
||||
#ifndef ONLY64
|
||||
/**
|
||||
* This function generates and returns 32-bit pseudorandom number.
|
||||
* init_gen_rand or init_by_array must be called before this function.
|
||||
* @return 32-bit pseudorandom number
|
||||
*/
|
||||
uint32_t gen_rand32(sfmt_t *ctx) {
|
||||
uint32_t r;
|
||||
uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
|
||||
|
||||
assert(ctx->initialized);
|
||||
if (ctx->idx >= N32) {
|
||||
gen_rand_all(ctx);
|
||||
ctx->idx = 0;
|
||||
}
|
||||
r = psfmt32[ctx->idx++];
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Generate a random integer in [0..limit). */
|
||||
uint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit) {
|
||||
uint32_t ret, above;
|
||||
|
||||
above = 0xffffffffU - (0xffffffffU % limit);
|
||||
while (1) {
|
||||
ret = gen_rand32(ctx);
|
||||
if (ret < above) {
|
||||
ret %= limit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* This function generates and returns 64-bit pseudorandom number.
|
||||
* init_gen_rand or init_by_array must be called before this function.
|
||||
* The function gen_rand64 should not be called after gen_rand32,
|
||||
* unless an initialization is again executed.
|
||||
* @return 64-bit pseudorandom number
|
||||
*/
|
||||
uint64_t gen_rand64(sfmt_t *ctx) {
|
||||
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
|
||||
uint32_t r1, r2;
|
||||
uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
|
||||
#else
|
||||
uint64_t r;
|
||||
uint64_t *psfmt64 = (uint64_t *)&ctx->sfmt[0].u[0];
|
||||
#endif
|
||||
|
||||
assert(ctx->initialized);
|
||||
assert(ctx->idx % 2 == 0);
|
||||
|
||||
if (ctx->idx >= N32) {
|
||||
gen_rand_all(ctx);
|
||||
ctx->idx = 0;
|
||||
}
|
||||
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
|
||||
r1 = psfmt32[ctx->idx];
|
||||
r2 = psfmt32[ctx->idx + 1];
|
||||
ctx->idx += 2;
|
||||
return ((uint64_t)r2 << 32) | r1;
|
||||
#else
|
||||
r = psfmt64[ctx->idx / 2];
|
||||
ctx->idx += 2;
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Generate a random integer in [0..limit). */
|
||||
uint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit) {
|
||||
uint64_t ret, above;
|
||||
|
||||
above = KQU(0xffffffffffffffff) - (KQU(0xffffffffffffffff) % limit);
|
||||
while (1) {
|
||||
ret = gen_rand64(ctx);
|
||||
if (ret < above) {
|
||||
ret %= limit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef ONLY64
|
||||
/**
|
||||
* This function generates pseudorandom 32-bit integers in the
|
||||
* specified array[] by one call. The number of pseudorandom integers
|
||||
* is specified by the argument size, which must be at least 624 and a
|
||||
* multiple of four. The generation by this function is much faster
|
||||
* than the following gen_rand function.
|
||||
*
|
||||
* For initialization, init_gen_rand or init_by_array must be called
|
||||
* before the first call of this function. This function can not be
|
||||
* used after calling gen_rand function, without initialization.
|
||||
*
|
||||
* @param array an array where pseudorandom 32-bit integers are filled
|
||||
* by this function. The pointer to the array must be \b "aligned"
|
||||
* (namely, must be a multiple of 16) in the SIMD version, since it
|
||||
* refers to the address of a 128-bit integer. In the standard C
|
||||
* version, the pointer is arbitrary.
|
||||
*
|
||||
* @param size the number of 32-bit pseudorandom integers to be
|
||||
* generated. size must be a multiple of 4, and greater than or equal
|
||||
* to (MEXP / 128 + 1) * 4.
|
||||
*
|
||||
* @note \b memalign or \b posix_memalign is available to get aligned
|
||||
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
|
||||
* returns the pointer to the aligned memory block.
|
||||
*/
|
||||
void fill_array32(sfmt_t *ctx, uint32_t *array, int size) {
|
||||
assert(ctx->initialized);
|
||||
assert(ctx->idx == N32);
|
||||
assert(size % 4 == 0);
|
||||
assert(size >= N32);
|
||||
|
||||
gen_rand_array(ctx, (w128_t *)array, size / 4);
|
||||
ctx->idx = N32;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function generates pseudorandom 64-bit integers in the
|
||||
* specified array[] by one call. The number of pseudorandom integers
|
||||
* is specified by the argument size, which must be at least 312 and a
|
||||
* multiple of two. The generation by this function is much faster
|
||||
* than the following gen_rand function.
|
||||
*
|
||||
* For initialization, init_gen_rand or init_by_array must be called
|
||||
* before the first call of this function. This function can not be
|
||||
* used after calling gen_rand function, without initialization.
|
||||
*
|
||||
* @param array an array where pseudorandom 64-bit integers are filled
|
||||
* by this function. The pointer to the array must be "aligned"
|
||||
* (namely, must be a multiple of 16) in the SIMD version, since it
|
||||
* refers to the address of a 128-bit integer. In the standard C
|
||||
* version, the pointer is arbitrary.
|
||||
*
|
||||
* @param size the number of 64-bit pseudorandom integers to be
|
||||
* generated. size must be a multiple of 2, and greater than or equal
|
||||
* to (MEXP / 128 + 1) * 2
|
||||
*
|
||||
* @note \b memalign or \b posix_memalign is available to get aligned
|
||||
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
|
||||
* returns the pointer to the aligned memory block.
|
||||
*/
|
||||
void fill_array64(sfmt_t *ctx, uint64_t *array, int size) {
|
||||
assert(ctx->initialized);
|
||||
assert(ctx->idx == N32);
|
||||
assert(size % 2 == 0);
|
||||
assert(size >= N64);
|
||||
|
||||
gen_rand_array(ctx, (w128_t *)array, size / 2);
|
||||
ctx->idx = N32;
|
||||
|
||||
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
|
||||
swap((w128_t *)array, size /2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes the internal state array with a 32-bit
|
||||
* integer seed.
|
||||
*
|
||||
* @param seed a 32-bit integer used as the seed.
|
||||
*/
|
||||
sfmt_t *init_gen_rand(uint32_t seed) {
|
||||
void *p;
|
||||
sfmt_t *ctx;
|
||||
int i;
|
||||
uint32_t *psfmt32;
|
||||
|
||||
if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
ctx = (sfmt_t *)p;
|
||||
psfmt32 = &ctx->sfmt[0].u[0];
|
||||
|
||||
psfmt32[idxof(0)] = seed;
|
||||
for (i = 1; i < N32; i++) {
|
||||
psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
|
||||
^ (psfmt32[idxof(i - 1)] >> 30))
|
||||
+ i;
|
||||
}
|
||||
ctx->idx = N32;
|
||||
period_certification(ctx);
|
||||
ctx->initialized = 1;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes the internal state array,
|
||||
* with an array of 32-bit integers used as the seeds
|
||||
* @param init_key the array of 32-bit integers, used as a seed.
|
||||
* @param key_length the length of init_key.
|
||||
*/
|
||||
sfmt_t *init_by_array(uint32_t *init_key, int key_length) {
|
||||
void *p;
|
||||
sfmt_t *ctx;
|
||||
int i, j, count;
|
||||
uint32_t r;
|
||||
int lag;
|
||||
int mid;
|
||||
int size = N * 4;
|
||||
uint32_t *psfmt32;
|
||||
|
||||
if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
ctx = (sfmt_t *)p;
|
||||
psfmt32 = &ctx->sfmt[0].u[0];
|
||||
|
||||
if (size >= 623) {
|
||||
lag = 11;
|
||||
} else if (size >= 68) {
|
||||
lag = 7;
|
||||
} else if (size >= 39) {
|
||||
lag = 5;
|
||||
} else {
|
||||
lag = 3;
|
||||
}
|
||||
mid = (size - lag) / 2;
|
||||
|
||||
memset(ctx->sfmt, 0x8b, sizeof(ctx->sfmt));
|
||||
if (key_length + 1 > N32) {
|
||||
count = key_length + 1;
|
||||
} else {
|
||||
count = N32;
|
||||
}
|
||||
r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
|
||||
^ psfmt32[idxof(N32 - 1)]);
|
||||
psfmt32[idxof(mid)] += r;
|
||||
r += key_length;
|
||||
psfmt32[idxof(mid + lag)] += r;
|
||||
psfmt32[idxof(0)] = r;
|
||||
|
||||
count--;
|
||||
for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
|
||||
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
|
||||
^ psfmt32[idxof((i + N32 - 1) % N32)]);
|
||||
psfmt32[idxof((i + mid) % N32)] += r;
|
||||
r += init_key[j] + i;
|
||||
psfmt32[idxof((i + mid + lag) % N32)] += r;
|
||||
psfmt32[idxof(i)] = r;
|
||||
i = (i + 1) % N32;
|
||||
}
|
||||
for (; j < count; j++) {
|
||||
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
|
||||
^ psfmt32[idxof((i + N32 - 1) % N32)]);
|
||||
psfmt32[idxof((i + mid) % N32)] += r;
|
||||
r += i;
|
||||
psfmt32[idxof((i + mid + lag) % N32)] += r;
|
||||
psfmt32[idxof(i)] = r;
|
||||
i = (i + 1) % N32;
|
||||
}
|
||||
for (j = 0; j < N32; j++) {
|
||||
r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
|
||||
+ psfmt32[idxof((i + N32 - 1) % N32)]);
|
||||
psfmt32[idxof((i + mid) % N32)] ^= r;
|
||||
r -= i;
|
||||
psfmt32[idxof((i + mid + lag) % N32)] ^= r;
|
||||
psfmt32[idxof(i)] = r;
|
||||
i = (i + 1) % N32;
|
||||
}
|
||||
|
||||
ctx->idx = N32;
|
||||
period_certification(ctx);
|
||||
ctx->initialized = 1;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void fini_gen_rand(sfmt_t *ctx) {
|
||||
assert(ctx != NULL);
|
||||
|
||||
ctx->initialized = 0;
|
||||
free(ctx);
|
||||
}
|
||||
8
memory/jemalloc/src/test/src/btalloc.c
Normal file
8
memory/jemalloc/src/test/src/btalloc.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
void *
|
||||
btalloc(size_t size, unsigned bits)
|
||||
{
|
||||
|
||||
return (btalloc_0(size, bits));
|
||||
}
|
||||
3
memory/jemalloc/src/test/src/btalloc_0.c
Normal file
3
memory/jemalloc/src/test/src/btalloc_0.c
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
btalloc_n_gen(0)
|
||||
3
memory/jemalloc/src/test/src/btalloc_1.c
Normal file
3
memory/jemalloc/src/test/src/btalloc_1.c
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
btalloc_n_gen(1)
|
||||
2
memory/jemalloc/src/test/src/math.c
Normal file
2
memory/jemalloc/src/test/src/math.c
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#define MATH_C_
|
||||
#include "test/jemalloc_test.h"
|
||||
29
memory/jemalloc/src/test/src/mq.c
Normal file
29
memory/jemalloc/src/test/src/mq.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
/*
|
||||
* Sleep for approximately ns nanoseconds. No lower *nor* upper bound on sleep
|
||||
* time is guaranteed.
|
||||
*/
|
||||
void
|
||||
mq_nanosleep(unsigned ns)
|
||||
{
|
||||
|
||||
assert(ns <= 1000*1000*1000);
|
||||
|
||||
#ifdef _WIN32
|
||||
Sleep(ns / 1000);
|
||||
#else
|
||||
{
|
||||
struct timespec timeout;
|
||||
|
||||
if (ns < 1000*1000*1000) {
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_nsec = ns;
|
||||
} else {
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_nsec = 0;
|
||||
}
|
||||
nanosleep(&timeout, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
73
memory/jemalloc/src/test/src/mtx.c
Normal file
73
memory/jemalloc/src/test/src/mtx.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifndef _CRT_SPINCOUNT
|
||||
#define _CRT_SPINCOUNT 4000
|
||||
#endif
|
||||
|
||||
bool
|
||||
mtx_init(mtx_t *mtx)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT))
|
||||
return (true);
|
||||
#elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
|
||||
mtx->lock = OS_UNFAIR_LOCK_INIT;
|
||||
#elif (defined(JEMALLOC_OSSPIN))
|
||||
mtx->lock = 0;
|
||||
#else
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
if (pthread_mutexattr_init(&attr) != 0)
|
||||
return (true);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT);
|
||||
if (pthread_mutex_init(&mtx->lock, &attr) != 0) {
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return (true);
|
||||
}
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
#endif
|
||||
return (false);
|
||||
}
|
||||
|
||||
void
|
||||
mtx_fini(mtx_t *mtx)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
#elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
|
||||
#elif (defined(JEMALLOC_OSSPIN))
|
||||
#else
|
||||
pthread_mutex_destroy(&mtx->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mtx_lock(mtx_t *mtx)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
EnterCriticalSection(&mtx->lock);
|
||||
#elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
|
||||
os_unfair_lock_lock(&mtx->lock);
|
||||
#elif (defined(JEMALLOC_OSSPIN))
|
||||
OSSpinLockLock(&mtx->lock);
|
||||
#else
|
||||
pthread_mutex_lock(&mtx->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
mtx_unlock(mtx_t *mtx)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
LeaveCriticalSection(&mtx->lock);
|
||||
#elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
|
||||
os_unfair_lock_unlock(&mtx->lock);
|
||||
#elif (defined(JEMALLOC_OSSPIN))
|
||||
OSSpinLockUnlock(&mtx->lock);
|
||||
#else
|
||||
pthread_mutex_unlock(&mtx->lock);
|
||||
#endif
|
||||
}
|
||||
133
memory/jemalloc/src/test/src/test.c
Normal file
133
memory/jemalloc/src/test/src/test.c
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static unsigned test_count = 0;
|
||||
static test_status_t test_counts[test_status_count] = {0, 0, 0};
|
||||
static test_status_t test_status = test_status_pass;
|
||||
static const char * test_name = "";
|
||||
|
||||
JEMALLOC_FORMAT_PRINTF(1, 2)
|
||||
void
|
||||
test_skip(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
malloc_vcprintf(NULL, NULL, format, ap);
|
||||
va_end(ap);
|
||||
malloc_printf("\n");
|
||||
test_status = test_status_skip;
|
||||
}
|
||||
|
||||
JEMALLOC_FORMAT_PRINTF(1, 2)
|
||||
void
|
||||
test_fail(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
malloc_vcprintf(NULL, NULL, format, ap);
|
||||
va_end(ap);
|
||||
malloc_printf("\n");
|
||||
test_status = test_status_fail;
|
||||
}
|
||||
|
||||
static const char *
|
||||
test_status_string(test_status_t test_status)
|
||||
{
|
||||
|
||||
switch (test_status) {
|
||||
case test_status_pass: return "pass";
|
||||
case test_status_skip: return "skip";
|
||||
case test_status_fail: return "fail";
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
p_test_init(const char *name)
|
||||
{
|
||||
|
||||
test_count++;
|
||||
test_status = test_status_pass;
|
||||
test_name = name;
|
||||
}
|
||||
|
||||
void
|
||||
p_test_fini(void)
|
||||
{
|
||||
|
||||
test_counts[test_status]++;
|
||||
malloc_printf("%s: %s\n", test_name, test_status_string(test_status));
|
||||
}
|
||||
|
||||
static test_status_t
|
||||
p_test_impl(bool do_malloc_init, test_t *t, va_list ap)
|
||||
{
|
||||
test_status_t ret;
|
||||
|
||||
if (do_malloc_init) {
|
||||
/*
|
||||
* Make sure initialization occurs prior to running tests.
|
||||
* Tests are special because they may use internal facilities
|
||||
* prior to triggering initialization as a side effect of
|
||||
* calling into the public API.
|
||||
*/
|
||||
if (nallocx(1, 0) == 0) {
|
||||
malloc_printf("Initialization error");
|
||||
return (test_status_fail);
|
||||
}
|
||||
}
|
||||
|
||||
ret = test_status_pass;
|
||||
for (; t != NULL; t = va_arg(ap, test_t *)) {
|
||||
t();
|
||||
if (test_status > ret)
|
||||
ret = test_status;
|
||||
}
|
||||
|
||||
malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n",
|
||||
test_status_string(test_status_pass),
|
||||
test_counts[test_status_pass], test_count,
|
||||
test_status_string(test_status_skip),
|
||||
test_counts[test_status_skip], test_count,
|
||||
test_status_string(test_status_fail),
|
||||
test_counts[test_status_fail], test_count);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
test_status_t
|
||||
p_test(test_t *t, ...)
|
||||
{
|
||||
test_status_t ret;
|
||||
va_list ap;
|
||||
|
||||
ret = test_status_pass;
|
||||
va_start(ap, t);
|
||||
ret = p_test_impl(true, t, ap);
|
||||
va_end(ap);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
test_status_t
|
||||
p_test_no_malloc_init(test_t *t, ...)
|
||||
{
|
||||
test_status_t ret;
|
||||
va_list ap;
|
||||
|
||||
ret = test_status_pass;
|
||||
va_start(ap, t);
|
||||
ret = p_test_impl(false, t, ap);
|
||||
va_end(ap);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
p_test_fail(const char *prefix, const char *message)
|
||||
{
|
||||
|
||||
malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message);
|
||||
test_status = test_status_fail;
|
||||
}
|
||||
39
memory/jemalloc/src/test/src/thd.c
Normal file
39
memory/jemalloc/src/test/src/thd.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
void
|
||||
thd_create(thd_t *thd, void *(*proc)(void *), void *arg)
|
||||
{
|
||||
LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc;
|
||||
*thd = CreateThread(NULL, 0, routine, arg, 0, NULL);
|
||||
if (*thd == NULL)
|
||||
test_fail("Error in CreateThread()\n");
|
||||
}
|
||||
|
||||
void
|
||||
thd_join(thd_t thd, void **ret)
|
||||
{
|
||||
|
||||
if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) {
|
||||
DWORD exit_code;
|
||||
GetExitCodeThread(thd, (LPDWORD) &exit_code);
|
||||
*ret = (void *)(uintptr_t)exit_code;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
thd_create(thd_t *thd, void *(*proc)(void *), void *arg)
|
||||
{
|
||||
|
||||
if (pthread_create(thd, NULL, proc, arg) != 0)
|
||||
test_fail("Error in pthread_create()\n");
|
||||
}
|
||||
|
||||
void
|
||||
thd_join(thd_t thd, void **ret)
|
||||
{
|
||||
|
||||
pthread_join(thd, ret);
|
||||
}
|
||||
#endif
|
||||
60
memory/jemalloc/src/test/src/timer.c
Normal file
60
memory/jemalloc/src/test/src/timer.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
void
|
||||
timer_start(timedelta_t *timer)
|
||||
{
|
||||
|
||||
nstime_init(&timer->t0, 0);
|
||||
nstime_update(&timer->t0);
|
||||
}
|
||||
|
||||
void
|
||||
timer_stop(timedelta_t *timer)
|
||||
{
|
||||
|
||||
nstime_copy(&timer->t1, &timer->t0);
|
||||
nstime_update(&timer->t1);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
timer_usec(const timedelta_t *timer)
|
||||
{
|
||||
nstime_t delta;
|
||||
|
||||
nstime_copy(&delta, &timer->t1);
|
||||
nstime_subtract(&delta, &timer->t0);
|
||||
return (nstime_ns(&delta) / 1000);
|
||||
}
|
||||
|
||||
void
|
||||
timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen)
|
||||
{
|
||||
uint64_t t0 = timer_usec(a);
|
||||
uint64_t t1 = timer_usec(b);
|
||||
uint64_t mult;
|
||||
size_t i = 0;
|
||||
size_t j, n;
|
||||
|
||||
/* Whole. */
|
||||
n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1);
|
||||
i += n;
|
||||
if (i >= buflen)
|
||||
return;
|
||||
mult = 1;
|
||||
for (j = 0; j < n; j++)
|
||||
mult *= 10;
|
||||
|
||||
/* Decimal. */
|
||||
n = malloc_snprintf(&buf[i], buflen-i, ".");
|
||||
i += n;
|
||||
|
||||
/* Fraction. */
|
||||
while (i < buflen-1) {
|
||||
uint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10
|
||||
>= 5)) ? 1 : 0;
|
||||
n = malloc_snprintf(&buf[i], buflen-i,
|
||||
"%"FMTu64, (t0 * mult / t1) % 10 + round);
|
||||
i += n;
|
||||
mult *= 10;
|
||||
}
|
||||
}
|
||||
182
memory/jemalloc/src/test/stress/microbench.c
Normal file
182
memory/jemalloc/src/test/stress/microbench.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
JEMALLOC_INLINE_C void
|
||||
time_func(timedelta_t *timer, uint64_t nwarmup, uint64_t niter,
|
||||
void (*func)(void))
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
for (i = 0; i < nwarmup; i++)
|
||||
func();
|
||||
timer_start(timer);
|
||||
for (i = 0; i < niter; i++)
|
||||
func();
|
||||
timer_stop(timer);
|
||||
}
|
||||
|
||||
void
|
||||
compare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a,
|
||||
void (*func_a), const char *name_b, void (*func_b))
|
||||
{
|
||||
timedelta_t timer_a, timer_b;
|
||||
char ratio_buf[6];
|
||||
void *p;
|
||||
|
||||
p = mallocx(1, 0);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected mallocx() failure");
|
||||
return;
|
||||
}
|
||||
|
||||
time_func(&timer_a, nwarmup, niter, func_a);
|
||||
time_func(&timer_b, nwarmup, niter, func_b);
|
||||
|
||||
timer_ratio(&timer_a, &timer_b, ratio_buf, sizeof(ratio_buf));
|
||||
malloc_printf("%"FMTu64" iterations, %s=%"FMTu64"us, "
|
||||
"%s=%"FMTu64"us, ratio=1:%s\n",
|
||||
niter, name_a, timer_usec(&timer_a), name_b, timer_usec(&timer_b),
|
||||
ratio_buf);
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
malloc_free(void)
|
||||
{
|
||||
/* The compiler can optimize away free(malloc(1))! */
|
||||
void *p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void
|
||||
mallocx_free(void)
|
||||
{
|
||||
void *p = mallocx(1, 0);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected mallocx() failure");
|
||||
return;
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_malloc_vs_mallocx)
|
||||
{
|
||||
|
||||
compare_funcs(10*1000*1000, 100*1000*1000, "malloc",
|
||||
malloc_free, "mallocx", mallocx_free);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
malloc_dallocx(void)
|
||||
{
|
||||
void *p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
dallocx(p, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
malloc_sdallocx(void)
|
||||
{
|
||||
void *p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
sdallocx(p, 1, 0);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_free_vs_dallocx)
|
||||
{
|
||||
|
||||
compare_funcs(10*1000*1000, 100*1000*1000, "free", malloc_free,
|
||||
"dallocx", malloc_dallocx);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_dallocx_vs_sdallocx)
|
||||
{
|
||||
|
||||
compare_funcs(10*1000*1000, 100*1000*1000, "dallocx", malloc_dallocx,
|
||||
"sdallocx", malloc_sdallocx);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
malloc_mus_free(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
malloc_usable_size(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void
|
||||
malloc_sallocx_free(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
if (sallocx(p, 0) < 1)
|
||||
test_fail("Unexpected sallocx() failure");
|
||||
free(p);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_mus_vs_sallocx)
|
||||
{
|
||||
|
||||
compare_funcs(10*1000*1000, 100*1000*1000, "malloc_usable_size",
|
||||
malloc_mus_free, "sallocx", malloc_sallocx_free);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
malloc_nallocx_free(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = malloc(1);
|
||||
if (p == NULL) {
|
||||
test_fail("Unexpected malloc() failure");
|
||||
return;
|
||||
}
|
||||
if (nallocx(1, 0) < 1)
|
||||
test_fail("Unexpected nallocx() failure");
|
||||
free(p);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_sallocx_vs_nallocx)
|
||||
{
|
||||
|
||||
compare_funcs(10*1000*1000, 100*1000*1000, "sallocx",
|
||||
malloc_sallocx_free, "nallocx", malloc_nallocx_free);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_malloc_vs_mallocx,
|
||||
test_free_vs_dallocx,
|
||||
test_dallocx_vs_sdallocx,
|
||||
test_mus_vs_sallocx,
|
||||
test_sallocx_vs_nallocx));
|
||||
}
|
||||
53
memory/jemalloc/src/test/test.sh.in
Normal file
53
memory/jemalloc/src/test/test.sh.in
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/bin/sh
|
||||
|
||||
case @abi@ in
|
||||
macho)
|
||||
export DYLD_FALLBACK_LIBRARY_PATH="@objroot@lib"
|
||||
;;
|
||||
pecoff)
|
||||
export PATH="${PATH}:@objroot@lib"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Corresponds to test_status_t.
|
||||
pass_code=0
|
||||
skip_code=1
|
||||
fail_code=2
|
||||
|
||||
pass_count=0
|
||||
skip_count=0
|
||||
fail_count=0
|
||||
for t in $@; do
|
||||
if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then
|
||||
echo
|
||||
fi
|
||||
echo "=== ${t} ==="
|
||||
${t}@exe@ @abs_srcroot@ @abs_objroot@
|
||||
result_code=$?
|
||||
case ${result_code} in
|
||||
${pass_code})
|
||||
pass_count=$((pass_count+1))
|
||||
;;
|
||||
${skip_code})
|
||||
skip_count=$((skip_count+1))
|
||||
;;
|
||||
${fail_code})
|
||||
fail_count=$((fail_count+1))
|
||||
;;
|
||||
*)
|
||||
echo "Test harness error" 1>&2
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
|
||||
total_count=`expr ${pass_count} + ${skip_count} + ${fail_count}`
|
||||
echo
|
||||
echo "Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}"
|
||||
|
||||
if [ ${fail_count} -eq 0 ] ; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
1605
memory/jemalloc/src/test/unit/SFMT.c
Normal file
1605
memory/jemalloc/src/test/unit/SFMT.c
Normal file
File diff suppressed because it is too large
Load diff
19
memory/jemalloc/src/test/unit/a0.c
Normal file
19
memory/jemalloc/src/test/unit/a0.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_a0)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = a0malloc(1);
|
||||
assert_ptr_not_null(p, "Unexpected a0malloc() error");
|
||||
a0dalloc(p);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test_no_malloc_init(
|
||||
test_a0));
|
||||
}
|
||||
159
memory/jemalloc/src/test/unit/arena_reset.c
Normal file
159
memory/jemalloc/src/test/unit/arena_reset.c
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf = "prof:true,lg_prof_sample:0";
|
||||
#endif
|
||||
|
||||
static unsigned
|
||||
get_nsizes_impl(const char *cmd)
|
||||
{
|
||||
unsigned ret;
|
||||
size_t z;
|
||||
|
||||
z = sizeof(unsigned);
|
||||
assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
|
||||
"Unexpected mallctl(\"%s\", ...) failure", cmd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nsmall(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nbins"));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nlarge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nlruns"));
|
||||
}
|
||||
|
||||
static unsigned
|
||||
get_nhuge(void)
|
||||
{
|
||||
|
||||
return (get_nsizes_impl("arenas.nhchunks"));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_size_impl(const char *cmd, size_t ind)
|
||||
{
|
||||
size_t ret;
|
||||
size_t z;
|
||||
size_t mib[4];
|
||||
size_t miblen = 4;
|
||||
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
|
||||
0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
|
||||
mib[2] = ind;
|
||||
z = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
|
||||
0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_small_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.bin.0.size", ind));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_large_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.lrun.0.size", ind));
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_huge_size(size_t ind)
|
||||
{
|
||||
|
||||
return (get_size_impl("arenas.hchunk.0.size", ind));
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_arena_reset)
|
||||
{
|
||||
#define NHUGE 4
|
||||
unsigned arena_ind, nsmall, nlarge, nhuge, nptrs, i;
|
||||
size_t sz, miblen;
|
||||
void **ptrs;
|
||||
int flags;
|
||||
size_t mib[3];
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if((config_valgrind && unlikely(in_valgrind)) || (config_fill
|
||||
&& unlikely(opt_quarantine)));
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
||||
|
||||
nsmall = get_nsmall();
|
||||
nlarge = get_nlarge();
|
||||
nhuge = get_nhuge() > NHUGE ? NHUGE : get_nhuge();
|
||||
nptrs = nsmall + nlarge + nhuge;
|
||||
ptrs = (void **)malloc(nptrs * sizeof(void *));
|
||||
assert_ptr_not_null(ptrs, "Unexpected malloc() failure");
|
||||
|
||||
/* Allocate objects with a wide range of sizes. */
|
||||
for (i = 0; i < nsmall; i++) {
|
||||
sz = get_small_size(i);
|
||||
ptrs[i] = mallocx(sz, flags);
|
||||
assert_ptr_not_null(ptrs[i],
|
||||
"Unexpected mallocx(%zu, %#x) failure", sz, flags);
|
||||
}
|
||||
for (i = 0; i < nlarge; i++) {
|
||||
sz = get_large_size(i);
|
||||
ptrs[nsmall + i] = mallocx(sz, flags);
|
||||
assert_ptr_not_null(ptrs[i],
|
||||
"Unexpected mallocx(%zu, %#x) failure", sz, flags);
|
||||
}
|
||||
for (i = 0; i < nhuge; i++) {
|
||||
sz = get_huge_size(i);
|
||||
ptrs[nsmall + nlarge + i] = mallocx(sz, flags);
|
||||
assert_ptr_not_null(ptrs[i],
|
||||
"Unexpected mallocx(%zu, %#x) failure", sz, flags);
|
||||
}
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
/* Verify allocations. */
|
||||
for (i = 0; i < nptrs; i++) {
|
||||
assert_zu_gt(ivsalloc(tsdn, ptrs[i], false), 0,
|
||||
"Allocation should have queryable size");
|
||||
}
|
||||
|
||||
/* Reset. */
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arena.0.reset", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
mib[1] = (size_t)arena_ind;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctlbymib() failure");
|
||||
|
||||
/* Verify allocations no longer exist. */
|
||||
for (i = 0; i < nptrs; i++) {
|
||||
assert_zu_eq(ivsalloc(tsdn, ptrs[i], false), 0,
|
||||
"Allocation should no longer exist");
|
||||
}
|
||||
|
||||
free(ptrs);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_arena_reset));
|
||||
}
|
||||
122
memory/jemalloc/src/test/unit/atomic.c
Normal file
122
memory/jemalloc/src/test/unit/atomic.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define TEST_STRUCT(p, t) \
|
||||
struct p##_test_s { \
|
||||
t accum0; \
|
||||
t x; \
|
||||
t s; \
|
||||
}; \
|
||||
typedef struct p##_test_s p##_test_t;
|
||||
|
||||
#define TEST_BODY(p, t, tc, ta, FMT) do { \
|
||||
const p##_test_t tests[] = { \
|
||||
{(t)-1, (t)-1, (t)-2}, \
|
||||
{(t)-1, (t) 0, (t)-2}, \
|
||||
{(t)-1, (t) 1, (t)-2}, \
|
||||
\
|
||||
{(t) 0, (t)-1, (t)-2}, \
|
||||
{(t) 0, (t) 0, (t)-2}, \
|
||||
{(t) 0, (t) 1, (t)-2}, \
|
||||
\
|
||||
{(t) 1, (t)-1, (t)-2}, \
|
||||
{(t) 1, (t) 0, (t)-2}, \
|
||||
{(t) 1, (t) 1, (t)-2}, \
|
||||
\
|
||||
{(t)0, (t)-(1 << 22), (t)-2}, \
|
||||
{(t)0, (t)(1 << 22), (t)-2}, \
|
||||
{(t)(1 << 22), (t)-(1 << 22), (t)-2}, \
|
||||
{(t)(1 << 22), (t)(1 << 22), (t)-2} \
|
||||
}; \
|
||||
unsigned i; \
|
||||
\
|
||||
for (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) { \
|
||||
bool err; \
|
||||
t accum = tests[i].accum0; \
|
||||
assert_##ta##_eq(atomic_read_##p(&accum), \
|
||||
tests[i].accum0, \
|
||||
"Erroneous read, i=%u", i); \
|
||||
\
|
||||
assert_##ta##_eq(atomic_add_##p(&accum, tests[i].x), \
|
||||
(t)((tc)tests[i].accum0 + (tc)tests[i].x), \
|
||||
"i=%u, accum=%"FMT", x=%"FMT, \
|
||||
i, tests[i].accum0, tests[i].x); \
|
||||
assert_##ta##_eq(atomic_read_##p(&accum), accum, \
|
||||
"Erroneous add, i=%u", i); \
|
||||
\
|
||||
accum = tests[i].accum0; \
|
||||
assert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x), \
|
||||
(t)((tc)tests[i].accum0 - (tc)tests[i].x), \
|
||||
"i=%u, accum=%"FMT", x=%"FMT, \
|
||||
i, tests[i].accum0, tests[i].x); \
|
||||
assert_##ta##_eq(atomic_read_##p(&accum), accum, \
|
||||
"Erroneous sub, i=%u", i); \
|
||||
\
|
||||
accum = tests[i].accum0; \
|
||||
err = atomic_cas_##p(&accum, tests[i].x, tests[i].s); \
|
||||
assert_b_eq(err, tests[i].accum0 != tests[i].x, \
|
||||
"Erroneous cas success/failure result"); \
|
||||
assert_##ta##_eq(accum, err ? tests[i].accum0 : \
|
||||
tests[i].s, "Erroneous cas effect, i=%u", i); \
|
||||
\
|
||||
accum = tests[i].accum0; \
|
||||
atomic_write_##p(&accum, tests[i].s); \
|
||||
assert_##ta##_eq(accum, tests[i].s, \
|
||||
"Erroneous write, i=%u", i); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
TEST_STRUCT(uint64, uint64_t)
|
||||
TEST_BEGIN(test_atomic_uint64)
|
||||
{
|
||||
|
||||
#if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
|
||||
test_skip("64-bit atomic operations not supported");
|
||||
#else
|
||||
TEST_BODY(uint64, uint64_t, uint64_t, u64, FMTx64);
|
||||
#endif
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_STRUCT(uint32, uint32_t)
|
||||
TEST_BEGIN(test_atomic_uint32)
|
||||
{
|
||||
|
||||
TEST_BODY(uint32, uint32_t, uint32_t, u32, "#"FMTx32);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_STRUCT(p, void *)
|
||||
TEST_BEGIN(test_atomic_p)
|
||||
{
|
||||
|
||||
TEST_BODY(p, void *, uintptr_t, ptr, "p");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_STRUCT(z, size_t)
|
||||
TEST_BEGIN(test_atomic_z)
|
||||
{
|
||||
|
||||
TEST_BODY(z, size_t, size_t, zu, "#zx");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_STRUCT(u, unsigned)
|
||||
TEST_BEGIN(test_atomic_u)
|
||||
{
|
||||
|
||||
TEST_BODY(u, unsigned, unsigned, u, "#x");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_atomic_uint64,
|
||||
test_atomic_uint32,
|
||||
test_atomic_p,
|
||||
test_atomic_z,
|
||||
test_atomic_u));
|
||||
}
|
||||
163
memory/jemalloc/src/test/unit/bitmap.c
Normal file
163
memory/jemalloc/src/test/unit/bitmap.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_bitmap_size)
|
||||
{
|
||||
size_t i, prev_size;
|
||||
|
||||
prev_size = 0;
|
||||
for (i = 1; i <= BITMAP_MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
size_t size;
|
||||
|
||||
bitmap_info_init(&binfo, i);
|
||||
size = bitmap_size(&binfo);
|
||||
assert_true(size >= prev_size,
|
||||
"Bitmap size is smaller than expected");
|
||||
prev_size = size;
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_init)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= BITMAP_MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = (bitmap_t *)malloc(
|
||||
bitmap_size(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_false(bitmap_get(bitmap, &binfo, j),
|
||||
"Bit should be unset");
|
||||
}
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_set)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= BITMAP_MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = (bitmap_t *)malloc(
|
||||
bitmap_size(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_unset)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= BITMAP_MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = (bitmap_t *)malloc(
|
||||
bitmap_size(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
for (j = 0; j < i; j++)
|
||||
bitmap_set(bitmap, &binfo, j);
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_bitmap_sfu)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 1; i <= BITMAP_MAXBITS; i++) {
|
||||
bitmap_info_t binfo;
|
||||
bitmap_info_init(&binfo, i);
|
||||
{
|
||||
size_t j;
|
||||
bitmap_t *bitmap = (bitmap_t *)malloc(
|
||||
bitmap_size(&binfo));
|
||||
bitmap_init(bitmap, &binfo);
|
||||
|
||||
/* Iteratively set bits starting at the beginning. */
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should be just after "
|
||||
"previous first unset bit");
|
||||
}
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
|
||||
/*
|
||||
* Iteratively unset bits starting at the end, and
|
||||
* verify that bitmap_sfu() reaches the unset bits.
|
||||
*/
|
||||
for (j = i - 1; j < i; j--) { /* (i..0] */
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should the bit previously "
|
||||
"unset");
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
}
|
||||
assert_false(bitmap_get(bitmap, &binfo, 0),
|
||||
"Bit should be unset");
|
||||
|
||||
/*
|
||||
* Iteratively set bits starting at the beginning, and
|
||||
* verify that bitmap_sfu() looks past them.
|
||||
*/
|
||||
for (j = 1; j < i; j++) {
|
||||
bitmap_set(bitmap, &binfo, j - 1);
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), j,
|
||||
"First unset bit should be just after the "
|
||||
"bit previously set");
|
||||
bitmap_unset(bitmap, &binfo, j);
|
||||
}
|
||||
assert_zd_eq(bitmap_sfu(bitmap, &binfo), i - 1,
|
||||
"First unset bit should be the last bit");
|
||||
assert_true(bitmap_full(bitmap, &binfo),
|
||||
"All bits should be set");
|
||||
free(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_bitmap_size,
|
||||
test_bitmap_init,
|
||||
test_bitmap_set,
|
||||
test_bitmap_unset,
|
||||
test_bitmap_sfu));
|
||||
}
|
||||
214
memory/jemalloc/src/test/unit/ckh.c
Normal file
214
memory/jemalloc/src/test/unit/ckh.c
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_new_delete)
|
||||
{
|
||||
tsd_t *tsd;
|
||||
ckh_t ckh;
|
||||
|
||||
tsd = tsd_fetch();
|
||||
|
||||
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
|
||||
ckh_string_keycomp), "Unexpected ckh_new() error");
|
||||
ckh_delete(tsd, &ckh);
|
||||
|
||||
assert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,
|
||||
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
||||
ckh_delete(tsd, &ckh);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_count_insert_search_remove)
|
||||
{
|
||||
tsd_t *tsd;
|
||||
ckh_t ckh;
|
||||
const char *strs[] = {
|
||||
"a string",
|
||||
"A string",
|
||||
"a string.",
|
||||
"A string."
|
||||
};
|
||||
const char *missing = "A string not in the hash table.";
|
||||
size_t i;
|
||||
|
||||
tsd = tsd_fetch();
|
||||
|
||||
assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
|
||||
ckh_string_keycomp), "Unexpected ckh_new() error");
|
||||
assert_zu_eq(ckh_count(&ckh), 0,
|
||||
"ckh_count() should return %zu, but it returned %zu", ZU(0),
|
||||
ckh_count(&ckh));
|
||||
|
||||
/* Insert. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
ckh_insert(tsd, &ckh, strs[i], strs[i]);
|
||||
assert_zu_eq(ckh_count(&ckh), i+1,
|
||||
"ckh_count() should return %zu, but it returned %zu", i+1,
|
||||
ckh_count(&ckh));
|
||||
}
|
||||
|
||||
/* Search. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
union {
|
||||
void *p;
|
||||
const char *s;
|
||||
} k, v;
|
||||
void **kp, **vp;
|
||||
const char *ks, *vs;
|
||||
|
||||
kp = (i & 1) ? &k.p : NULL;
|
||||
vp = (i & 2) ? &v.p : NULL;
|
||||
k.p = NULL;
|
||||
v.p = NULL;
|
||||
assert_false(ckh_search(&ckh, strs[i], kp, vp),
|
||||
"Unexpected ckh_search() error");
|
||||
|
||||
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
||||
vs = (i & 2) ? strs[i] : (const char *)NULL;
|
||||
assert_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
|
||||
i);
|
||||
assert_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
|
||||
i);
|
||||
}
|
||||
assert_true(ckh_search(&ckh, missing, NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
|
||||
/* Remove. */
|
||||
for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
|
||||
union {
|
||||
void *p;
|
||||
const char *s;
|
||||
} k, v;
|
||||
void **kp, **vp;
|
||||
const char *ks, *vs;
|
||||
|
||||
kp = (i & 1) ? &k.p : NULL;
|
||||
vp = (i & 2) ? &v.p : NULL;
|
||||
k.p = NULL;
|
||||
v.p = NULL;
|
||||
assert_false(ckh_remove(tsd, &ckh, strs[i], kp, vp),
|
||||
"Unexpected ckh_remove() error");
|
||||
|
||||
ks = (i & 1) ? strs[i] : (const char *)NULL;
|
||||
vs = (i & 2) ? strs[i] : (const char *)NULL;
|
||||
assert_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
|
||||
i);
|
||||
assert_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
|
||||
i);
|
||||
assert_zu_eq(ckh_count(&ckh),
|
||||
sizeof(strs)/sizeof(const char *) - i - 1,
|
||||
"ckh_count() should return %zu, but it returned %zu",
|
||||
sizeof(strs)/sizeof(const char *) - i - 1,
|
||||
ckh_count(&ckh));
|
||||
}
|
||||
|
||||
ckh_delete(tsd, &ckh);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_insert_iter_remove)
|
||||
{
|
||||
#define NITEMS ZU(1000)
|
||||
tsd_t *tsd;
|
||||
ckh_t ckh;
|
||||
void **p[NITEMS];
|
||||
void *q, *r;
|
||||
size_t i;
|
||||
|
||||
tsd = tsd_fetch();
|
||||
|
||||
assert_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash,
|
||||
ckh_pointer_keycomp), "Unexpected ckh_new() error");
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
p[i] = mallocx(i+1, 0);
|
||||
assert_ptr_not_null(p[i], "Unexpected mallocx() failure");
|
||||
}
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
size_t j;
|
||||
|
||||
for (j = i; j < NITEMS; j++) {
|
||||
assert_false(ckh_insert(tsd, &ckh, p[j], p[j]),
|
||||
"Unexpected ckh_insert() failure");
|
||||
assert_false(ckh_search(&ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
||||
}
|
||||
|
||||
assert_zu_eq(ckh_count(&ckh), NITEMS,
|
||||
"ckh_count() should return %zu, but it returned %zu",
|
||||
NITEMS, ckh_count(&ckh));
|
||||
|
||||
for (j = i + 1; j < NITEMS; j++) {
|
||||
assert_false(ckh_search(&ckh, p[j], NULL, NULL),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_false(ckh_remove(tsd, &ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_remove() failure");
|
||||
assert_ptr_eq(p[j], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[j], r, "Value pointer mismatch");
|
||||
assert_true(ckh_search(&ckh, p[j], NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
assert_true(ckh_remove(tsd, &ckh, p[j], &q, &r),
|
||||
"Unexpected ckh_remove() success");
|
||||
}
|
||||
|
||||
{
|
||||
bool seen[NITEMS];
|
||||
size_t tabind;
|
||||
|
||||
memset(seen, 0, sizeof(seen));
|
||||
|
||||
for (tabind = 0; !ckh_iter(&ckh, &tabind, &q, &r);) {
|
||||
size_t k;
|
||||
|
||||
assert_ptr_eq(q, r, "Key and val not equal");
|
||||
|
||||
for (k = 0; k < NITEMS; k++) {
|
||||
if (p[k] == q) {
|
||||
assert_false(seen[k],
|
||||
"Item %zu already seen", k);
|
||||
seen[k] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < i + 1; j++)
|
||||
assert_true(seen[j], "Item %zu not seen", j);
|
||||
for (; j < NITEMS; j++)
|
||||
assert_false(seen[j], "Item %zu seen", j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NITEMS; i++) {
|
||||
assert_false(ckh_search(&ckh, p[i], NULL, NULL),
|
||||
"Unexpected ckh_search() failure");
|
||||
assert_false(ckh_remove(tsd, &ckh, p[i], &q, &r),
|
||||
"Unexpected ckh_remove() failure");
|
||||
assert_ptr_eq(p[i], q, "Key pointer mismatch");
|
||||
assert_ptr_eq(p[i], r, "Value pointer mismatch");
|
||||
assert_true(ckh_search(&ckh, p[i], NULL, NULL),
|
||||
"Unexpected ckh_search() success");
|
||||
assert_true(ckh_remove(tsd, &ckh, p[i], &q, &r),
|
||||
"Unexpected ckh_remove() success");
|
||||
dallocx(p[i], 0);
|
||||
}
|
||||
|
||||
assert_zu_eq(ckh_count(&ckh), 0,
|
||||
"ckh_count() should return %zu, but it returned %zu",
|
||||
ZU(0), ckh_count(&ckh));
|
||||
ckh_delete(tsd, &ckh);
|
||||
#undef NITEMS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_new_delete,
|
||||
test_count_insert_search_remove,
|
||||
test_insert_iter_remove));
|
||||
}
|
||||
374
memory/jemalloc/src/test/unit/decay.c
Normal file
374
memory/jemalloc/src/test/unit/decay.c
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
const char *malloc_conf = "purge:decay,decay_time:1";
|
||||
|
||||
static nstime_monotonic_t *nstime_monotonic_orig;
|
||||
static nstime_update_t *nstime_update_orig;
|
||||
|
||||
static unsigned nupdates_mock;
|
||||
static nstime_t time_mock;
|
||||
static bool monotonic_mock;
|
||||
|
||||
static bool
|
||||
nstime_monotonic_mock(void)
|
||||
{
|
||||
|
||||
return (monotonic_mock);
|
||||
}
|
||||
|
||||
static bool
|
||||
nstime_update_mock(nstime_t *time)
|
||||
{
|
||||
|
||||
nupdates_mock++;
|
||||
if (monotonic_mock)
|
||||
nstime_copy(time, &time_mock);
|
||||
return (!monotonic_mock);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_decay_ticks)
|
||||
{
|
||||
ticker_t *decay_ticker;
|
||||
unsigned tick0, tick1;
|
||||
size_t sz, huge0, large0;
|
||||
void *p;
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_decay);
|
||||
|
||||
decay_ticker = decay_ticker_get(tsd_fetch(), 0);
|
||||
assert_ptr_not_null(decay_ticker,
|
||||
"Unexpected failure getting decay ticker");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
/*
|
||||
* Test the standard APIs using a huge size class, since we can't
|
||||
* control tcache interactions (except by completely disabling tcache
|
||||
* for the entire test program).
|
||||
*/
|
||||
|
||||
/* malloc(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = malloc(huge0);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during malloc()");
|
||||
/* free(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
free(p);
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during free()");
|
||||
|
||||
/* calloc(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = calloc(1, huge0);
|
||||
assert_ptr_not_null(p, "Unexpected calloc() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during calloc()");
|
||||
free(p);
|
||||
|
||||
/* posix_memalign(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
assert_d_eq(posix_memalign(&p, sizeof(size_t), huge0), 0,
|
||||
"Unexpected posix_memalign() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during posix_memalign()");
|
||||
free(p);
|
||||
|
||||
/* aligned_alloc(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = aligned_alloc(sizeof(size_t), huge0);
|
||||
assert_ptr_not_null(p, "Unexpected aligned_alloc() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during aligned_alloc()");
|
||||
free(p);
|
||||
|
||||
/* realloc(). */
|
||||
/* Allocate. */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = realloc(NULL, huge0);
|
||||
assert_ptr_not_null(p, "Unexpected realloc() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
|
||||
/* Reallocate. */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = realloc(p, huge0);
|
||||
assert_ptr_not_null(p, "Unexpected realloc() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
|
||||
/* Deallocate. */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
realloc(p, 0);
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0, "Expected ticker to tick during realloc()");
|
||||
|
||||
/*
|
||||
* Test the *allocx() APIs using huge, large, and small size classes,
|
||||
* with tcache explicitly disabled.
|
||||
*/
|
||||
{
|
||||
unsigned i;
|
||||
size_t allocx_sizes[3];
|
||||
allocx_sizes[0] = huge0;
|
||||
allocx_sizes[1] = large0;
|
||||
allocx_sizes[2] = 1;
|
||||
|
||||
for (i = 0; i < sizeof(allocx_sizes) / sizeof(size_t); i++) {
|
||||
sz = allocx_sizes[i];
|
||||
|
||||
/* mallocx(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = mallocx(sz, MALLOCX_TCACHE_NONE);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during mallocx() (sz=%zu)",
|
||||
sz);
|
||||
/* rallocx(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = rallocx(p, sz, MALLOCX_TCACHE_NONE);
|
||||
assert_ptr_not_null(p, "Unexpected rallocx() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during rallocx() (sz=%zu)",
|
||||
sz);
|
||||
/* xallocx(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
xallocx(p, sz, 0, MALLOCX_TCACHE_NONE);
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during xallocx() (sz=%zu)",
|
||||
sz);
|
||||
/* dallocx(). */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
dallocx(p, MALLOCX_TCACHE_NONE);
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during dallocx() (sz=%zu)",
|
||||
sz);
|
||||
/* sdallocx(). */
|
||||
p = mallocx(sz, MALLOCX_TCACHE_NONE);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
sdallocx(p, sz, MALLOCX_TCACHE_NONE);
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during sdallocx() "
|
||||
"(sz=%zu)", sz);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test tcache fill/flush interactions for large and small size classes,
|
||||
* using an explicit tcache.
|
||||
*/
|
||||
if (config_tcache) {
|
||||
unsigned tcache_ind, i;
|
||||
size_t tcache_sizes[2];
|
||||
tcache_sizes[0] = large0;
|
||||
tcache_sizes[1] = 1;
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("tcache.create", &tcache_ind, &sz, NULL, 0),
|
||||
0, "Unexpected mallctl failure");
|
||||
|
||||
for (i = 0; i < sizeof(tcache_sizes) / sizeof(size_t); i++) {
|
||||
sz = tcache_sizes[i];
|
||||
|
||||
/* tcache fill. */
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
p = mallocx(sz, MALLOCX_TCACHE(tcache_ind));
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during tcache fill "
|
||||
"(sz=%zu)", sz);
|
||||
/* tcache flush. */
|
||||
dallocx(p, MALLOCX_TCACHE(tcache_ind));
|
||||
tick0 = ticker_read(decay_ticker);
|
||||
assert_d_eq(mallctl("tcache.flush", NULL, NULL,
|
||||
&tcache_ind, sizeof(unsigned)), 0,
|
||||
"Unexpected mallctl failure");
|
||||
tick1 = ticker_read(decay_ticker);
|
||||
assert_u32_ne(tick1, tick0,
|
||||
"Expected ticker to tick during tcache flush "
|
||||
"(sz=%zu)", sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_decay_ticker)
|
||||
{
|
||||
#define NPS 1024
|
||||
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
|
||||
void *ps[NPS];
|
||||
uint64_t epoch;
|
||||
uint64_t npurge0 = 0;
|
||||
uint64_t npurge1 = 0;
|
||||
size_t sz, large;
|
||||
unsigned i, nupdates0;
|
||||
nstime_t time, decay_time, deadline;
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_decay);
|
||||
|
||||
/*
|
||||
* Allocate a bunch of large objects, pause the clock, deallocate the
|
||||
* objects, restore the clock, then [md]allocx() in a tight loop to
|
||||
* verify the ticker triggers purging.
|
||||
*/
|
||||
|
||||
if (config_tcache) {
|
||||
size_t tcache_max;
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("arenas.tcache_max", &tcache_max, &sz, NULL,
|
||||
0), 0, "Unexpected mallctl failure");
|
||||
large = nallocx(tcache_max + 1, flags);
|
||||
} else {
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("arenas.lrun.0.size", &large, &sz, NULL, 0),
|
||||
0, "Unexpected mallctl failure");
|
||||
}
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
|
||||
"Unexpected mallctl failure");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0),
|
||||
config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
||||
|
||||
for (i = 0; i < NPS; i++) {
|
||||
ps[i] = mallocx(large, flags);
|
||||
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
|
||||
}
|
||||
|
||||
nupdates_mock = 0;
|
||||
nstime_init(&time_mock, 0);
|
||||
nstime_update(&time_mock);
|
||||
monotonic_mock = true;
|
||||
|
||||
nstime_monotonic_orig = nstime_monotonic;
|
||||
nstime_update_orig = nstime_update;
|
||||
nstime_monotonic = nstime_monotonic_mock;
|
||||
nstime_update = nstime_update_mock;
|
||||
|
||||
for (i = 0; i < NPS; i++) {
|
||||
dallocx(ps[i], flags);
|
||||
nupdates0 = nupdates_mock;
|
||||
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected arena.0.decay failure");
|
||||
assert_u_gt(nupdates_mock, nupdates0,
|
||||
"Expected nstime_update() to be called");
|
||||
}
|
||||
|
||||
nstime_monotonic = nstime_monotonic_orig;
|
||||
nstime_update = nstime_update_orig;
|
||||
|
||||
nstime_init(&time, 0);
|
||||
nstime_update(&time);
|
||||
nstime_init2(&decay_time, opt_decay_time, 0);
|
||||
nstime_copy(&deadline, &time);
|
||||
nstime_add(&deadline, &decay_time);
|
||||
do {
|
||||
for (i = 0; i < DECAY_NTICKS_PER_UPDATE / 2; i++) {
|
||||
void *p = mallocx(1, flags);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, flags);
|
||||
}
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch,
|
||||
sizeof(uint64_t)), 0, "Unexpected mallctl failure");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz,
|
||||
NULL, 0), config_stats ? 0 : ENOENT,
|
||||
"Unexpected mallctl result");
|
||||
|
||||
nstime_update(&time);
|
||||
} while (nstime_compare(&time, &deadline) <= 0 && npurge1 == npurge0);
|
||||
|
||||
if (config_stats)
|
||||
assert_u64_gt(npurge1, npurge0, "Expected purging to occur");
|
||||
#undef NPS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_decay_nonmonotonic)
|
||||
{
|
||||
#define NPS (SMOOTHSTEP_NSTEPS + 1)
|
||||
int flags = (MALLOCX_ARENA(0) | MALLOCX_TCACHE_NONE);
|
||||
void *ps[NPS];
|
||||
uint64_t epoch;
|
||||
uint64_t npurge0 = 0;
|
||||
uint64_t npurge1 = 0;
|
||||
size_t sz, large0;
|
||||
unsigned i, nupdates0;
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_decay);
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
|
||||
"Unexpected mallctl failure");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0),
|
||||
config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
||||
|
||||
nupdates_mock = 0;
|
||||
nstime_init(&time_mock, 0);
|
||||
nstime_update(&time_mock);
|
||||
monotonic_mock = false;
|
||||
|
||||
nstime_monotonic_orig = nstime_monotonic;
|
||||
nstime_update_orig = nstime_update;
|
||||
nstime_monotonic = nstime_monotonic_mock;
|
||||
nstime_update = nstime_update_mock;
|
||||
|
||||
for (i = 0; i < NPS; i++) {
|
||||
ps[i] = mallocx(large0, flags);
|
||||
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
|
||||
}
|
||||
|
||||
for (i = 0; i < NPS; i++) {
|
||||
dallocx(ps[i], flags);
|
||||
nupdates0 = nupdates_mock;
|
||||
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected arena.0.decay failure");
|
||||
assert_u_gt(nupdates_mock, nupdates0,
|
||||
"Expected nstime_update() to be called");
|
||||
}
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
|
||||
"Unexpected mallctl failure");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz, NULL, 0),
|
||||
config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
||||
|
||||
if (config_stats)
|
||||
assert_u64_eq(npurge0, npurge1, "Unexpected purging occurred");
|
||||
|
||||
nstime_monotonic = nstime_monotonic_orig;
|
||||
nstime_update = nstime_update_orig;
|
||||
#undef NPS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_decay_ticks,
|
||||
test_decay_ticker,
|
||||
test_decay_nonmonotonic));
|
||||
}
|
||||
64
memory/jemalloc/src/test/unit/fork.c
Normal file
64
memory/jemalloc/src/test/unit/fork.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
TEST_BEGIN(test_fork)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
void *p;
|
||||
pid_t pid;
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
|
||||
pid = fork();
|
||||
|
||||
free(p);
|
||||
|
||||
p = malloc(64);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
free(p);
|
||||
|
||||
if (pid == -1) {
|
||||
/* Error. */
|
||||
test_fail("Unexpected fork() failure");
|
||||
} else if (pid == 0) {
|
||||
/* Child. */
|
||||
_exit(0);
|
||||
} else {
|
||||
int status;
|
||||
|
||||
/* Parent. */
|
||||
while (true) {
|
||||
if (waitpid(pid, &status, 0) == -1)
|
||||
test_fail("Unexpected waitpid() failure");
|
||||
if (WIFSIGNALED(status)) {
|
||||
test_fail("Unexpected child termination due to "
|
||||
"signal %d", WTERMSIG(status));
|
||||
break;
|
||||
}
|
||||
if (WIFEXITED(status)) {
|
||||
if (WEXITSTATUS(status) != 0) {
|
||||
test_fail(
|
||||
"Unexpected child exit value %d",
|
||||
WEXITSTATUS(status));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
test_skip("fork(2) is irrelevant to Windows");
|
||||
#endif
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_fork));
|
||||
}
|
||||
185
memory/jemalloc/src/test/unit/hash.c
Normal file
185
memory/jemalloc/src/test/unit/hash.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* This file is based on code that is part of SMHasher
|
||||
* (https://code.google.com/p/smhasher/), and is subject to the MIT license
|
||||
* (http://www.opensource.org/licenses/mit-license.php). Both email addresses
|
||||
* associated with the source code's revision history belong to Austin Appleby,
|
||||
* and the revision history ranges from 2010 to 2012. Therefore the copyright
|
||||
* and license are here taken to be:
|
||||
*
|
||||
* Copyright (c) 2010-2012 Austin Appleby
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "test/jemalloc_test.h"
|
||||
|
||||
typedef enum {
|
||||
hash_variant_x86_32,
|
||||
hash_variant_x86_128,
|
||||
hash_variant_x64_128
|
||||
} hash_variant_t;
|
||||
|
||||
static int
|
||||
hash_variant_bits(hash_variant_t variant)
|
||||
{
|
||||
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: return (32);
|
||||
case hash_variant_x86_128: return (128);
|
||||
case hash_variant_x64_128: return (128);
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
hash_variant_string(hash_variant_t variant)
|
||||
{
|
||||
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: return ("hash_x86_32");
|
||||
case hash_variant_x86_128: return ("hash_x86_128");
|
||||
case hash_variant_x64_128: return ("hash_x64_128");
|
||||
default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
#define KEY_SIZE 256
|
||||
static void
|
||||
hash_variant_verify_key(hash_variant_t variant, uint8_t *key)
|
||||
{
|
||||
const int hashbytes = hash_variant_bits(variant) / 8;
|
||||
const int hashes_size = hashbytes * 256;
|
||||
VARIABLE_ARRAY(uint8_t, hashes, hashes_size);
|
||||
VARIABLE_ARRAY(uint8_t, final, hashbytes);
|
||||
unsigned i;
|
||||
uint32_t computed, expected;
|
||||
|
||||
memset(key, 0, KEY_SIZE);
|
||||
memset(hashes, 0, hashes_size);
|
||||
memset(final, 0, hashbytes);
|
||||
|
||||
/*
|
||||
* Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the
|
||||
* seed.
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
key[i] = (uint8_t)i;
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: {
|
||||
uint32_t out;
|
||||
out = hash_x86_32(key, i, 256-i);
|
||||
memcpy(&hashes[i*hashbytes], &out, hashbytes);
|
||||
break;
|
||||
} case hash_variant_x86_128: {
|
||||
uint64_t out[2];
|
||||
hash_x86_128(key, i, 256-i, out);
|
||||
memcpy(&hashes[i*hashbytes], out, hashbytes);
|
||||
break;
|
||||
} case hash_variant_x64_128: {
|
||||
uint64_t out[2];
|
||||
hash_x64_128(key, i, 256-i, out);
|
||||
memcpy(&hashes[i*hashbytes], out, hashbytes);
|
||||
break;
|
||||
} default: not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
/* Hash the result array. */
|
||||
switch (variant) {
|
||||
case hash_variant_x86_32: {
|
||||
uint32_t out = hash_x86_32(hashes, hashes_size, 0);
|
||||
memcpy(final, &out, sizeof(out));
|
||||
break;
|
||||
} case hash_variant_x86_128: {
|
||||
uint64_t out[2];
|
||||
hash_x86_128(hashes, hashes_size, 0, out);
|
||||
memcpy(final, out, sizeof(out));
|
||||
break;
|
||||
} case hash_variant_x64_128: {
|
||||
uint64_t out[2];
|
||||
hash_x64_128(hashes, hashes_size, 0, out);
|
||||
memcpy(final, out, sizeof(out));
|
||||
break;
|
||||
} default: not_reached();
|
||||
}
|
||||
|
||||
computed = (final[0] << 0) | (final[1] << 8) | (final[2] << 16) |
|
||||
(final[3] << 24);
|
||||
|
||||
switch (variant) {
|
||||
#ifdef JEMALLOC_BIG_ENDIAN
|
||||
case hash_variant_x86_32: expected = 0x6213303eU; break;
|
||||
case hash_variant_x86_128: expected = 0x266820caU; break;
|
||||
case hash_variant_x64_128: expected = 0xcc622b6fU; break;
|
||||
#else
|
||||
case hash_variant_x86_32: expected = 0xb0f57ee3U; break;
|
||||
case hash_variant_x86_128: expected = 0xb3ece62aU; break;
|
||||
case hash_variant_x64_128: expected = 0x6384ba69U; break;
|
||||
#endif
|
||||
default: not_reached();
|
||||
}
|
||||
|
||||
assert_u32_eq(computed, expected,
|
||||
"Hash mismatch for %s(): expected %#x but got %#x",
|
||||
hash_variant_string(variant), expected, computed);
|
||||
}
|
||||
|
||||
static void
|
||||
hash_variant_verify(hash_variant_t variant)
|
||||
{
|
||||
#define MAX_ALIGN 16
|
||||
uint8_t key[KEY_SIZE + (MAX_ALIGN - 1)];
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < MAX_ALIGN; i++)
|
||||
hash_variant_verify_key(variant, &key[i]);
|
||||
#undef MAX_ALIGN
|
||||
}
|
||||
#undef KEY_SIZE
|
||||
|
||||
TEST_BEGIN(test_hash_x86_32)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x86_32);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_hash_x86_128)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x86_128);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_hash_x64_128)
|
||||
{
|
||||
|
||||
hash_variant_verify(hash_variant_x64_128);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_hash_x86_32,
|
||||
test_hash_x86_128,
|
||||
test_hash_x64_128));
|
||||
}
|
||||
253
memory/jemalloc/src/test/unit/junk.c
Normal file
253
memory/jemalloc/src/test/unit/junk.c
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
# ifndef JEMALLOC_TEST_JUNK_OPT
|
||||
# define JEMALLOC_TEST_JUNK_OPT "junk:true"
|
||||
# endif
|
||||
const char *malloc_conf =
|
||||
"abort:false,zero:false,redzone:true,quarantine:0," JEMALLOC_TEST_JUNK_OPT;
|
||||
#endif
|
||||
|
||||
static arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig;
|
||||
static arena_dalloc_junk_large_t *arena_dalloc_junk_large_orig;
|
||||
static huge_dalloc_junk_t *huge_dalloc_junk_orig;
|
||||
static void *watch_for_junking;
|
||||
static bool saw_junking;
|
||||
|
||||
static void
|
||||
watch_junking(void *p)
|
||||
{
|
||||
|
||||
watch_for_junking = p;
|
||||
saw_junking = false;
|
||||
}
|
||||
|
||||
static void
|
||||
arena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
arena_dalloc_junk_small_orig(ptr, bin_info);
|
||||
for (i = 0; i < bin_info->reg_size; i++) {
|
||||
assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK,
|
||||
"Missing junk fill for byte %zu/%zu of deallocated region",
|
||||
i, bin_info->reg_size);
|
||||
}
|
||||
if (ptr == watch_for_junking)
|
||||
saw_junking = true;
|
||||
}
|
||||
|
||||
static void
|
||||
arena_dalloc_junk_large_intercept(void *ptr, size_t usize)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
arena_dalloc_junk_large_orig(ptr, usize);
|
||||
for (i = 0; i < usize; i++) {
|
||||
assert_u_eq(((uint8_t *)ptr)[i], JEMALLOC_FREE_JUNK,
|
||||
"Missing junk fill for byte %zu/%zu of deallocated region",
|
||||
i, usize);
|
||||
}
|
||||
if (ptr == watch_for_junking)
|
||||
saw_junking = true;
|
||||
}
|
||||
|
||||
static void
|
||||
huge_dalloc_junk_intercept(void *ptr, size_t usize)
|
||||
{
|
||||
|
||||
huge_dalloc_junk_orig(ptr, usize);
|
||||
/*
|
||||
* The conditions under which junk filling actually occurs are nuanced
|
||||
* enough that it doesn't make sense to duplicate the decision logic in
|
||||
* test code, so don't actually check that the region is junk-filled.
|
||||
*/
|
||||
if (ptr == watch_for_junking)
|
||||
saw_junking = true;
|
||||
}
|
||||
|
||||
static void
|
||||
test_junk(size_t sz_min, size_t sz_max)
|
||||
{
|
||||
uint8_t *s;
|
||||
size_t sz_prev, sz, i;
|
||||
|
||||
if (opt_junk_free) {
|
||||
arena_dalloc_junk_small_orig = arena_dalloc_junk_small;
|
||||
arena_dalloc_junk_small = arena_dalloc_junk_small_intercept;
|
||||
arena_dalloc_junk_large_orig = arena_dalloc_junk_large;
|
||||
arena_dalloc_junk_large = arena_dalloc_junk_large_intercept;
|
||||
huge_dalloc_junk_orig = huge_dalloc_junk;
|
||||
huge_dalloc_junk = huge_dalloc_junk_intercept;
|
||||
}
|
||||
|
||||
sz_prev = 0;
|
||||
s = (uint8_t *)mallocx(sz_min, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
|
||||
for (sz = sallocx(s, 0); sz <= sz_max;
|
||||
sz_prev = sz, sz = sallocx(s, 0)) {
|
||||
if (sz_prev > 0) {
|
||||
assert_u_eq(s[0], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
ZU(0), sz_prev);
|
||||
assert_u_eq(s[sz_prev-1], 'a',
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
sz_prev-1, sz_prev);
|
||||
}
|
||||
|
||||
for (i = sz_prev; i < sz; i++) {
|
||||
if (opt_junk_alloc) {
|
||||
assert_u_eq(s[i], JEMALLOC_ALLOC_JUNK,
|
||||
"Newly allocated byte %zu/%zu isn't "
|
||||
"junk-filled", i, sz);
|
||||
}
|
||||
s[i] = 'a';
|
||||
}
|
||||
|
||||
if (xallocx(s, sz+1, 0, 0) == sz) {
|
||||
watch_junking(s);
|
||||
s = (uint8_t *)rallocx(s, sz+1, 0);
|
||||
assert_ptr_not_null((void *)s,
|
||||
"Unexpected rallocx() failure");
|
||||
assert_true(!opt_junk_free || saw_junking,
|
||||
"Expected region of size %zu to be junk-filled",
|
||||
sz);
|
||||
}
|
||||
}
|
||||
|
||||
watch_junking(s);
|
||||
dallocx(s, 0);
|
||||
assert_true(!opt_junk_free || saw_junking,
|
||||
"Expected region of size %zu to be junk-filled", sz);
|
||||
|
||||
if (opt_junk_free) {
|
||||
arena_dalloc_junk_small = arena_dalloc_junk_small_orig;
|
||||
arena_dalloc_junk_large = arena_dalloc_junk_large_orig;
|
||||
huge_dalloc_junk = huge_dalloc_junk_orig;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_small)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(1, SMALL_MAXCLASS-1);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_junk_large)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(SMALL_MAXCLASS+1, large_maxclass);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_junk_huge)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_junk(large_maxclass+1, chunksize*2);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
arena_ralloc_junk_large_t *arena_ralloc_junk_large_orig;
|
||||
static void *most_recently_trimmed;
|
||||
|
||||
static size_t
|
||||
shrink_size(size_t size)
|
||||
{
|
||||
size_t shrink_size;
|
||||
|
||||
for (shrink_size = size - 1; nallocx(shrink_size, 0) == size;
|
||||
shrink_size--)
|
||||
; /* Do nothing. */
|
||||
|
||||
return (shrink_size);
|
||||
}
|
||||
|
||||
static void
|
||||
arena_ralloc_junk_large_intercept(void *ptr, size_t old_usize, size_t usize)
|
||||
{
|
||||
|
||||
arena_ralloc_junk_large_orig(ptr, old_usize, usize);
|
||||
assert_zu_eq(old_usize, large_maxclass, "Unexpected old_usize");
|
||||
assert_zu_eq(usize, shrink_size(large_maxclass), "Unexpected usize");
|
||||
most_recently_trimmed = ptr;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_large_ralloc_shrink)
|
||||
{
|
||||
void *p1, *p2;
|
||||
|
||||
p1 = mallocx(large_maxclass, 0);
|
||||
assert_ptr_not_null(p1, "Unexpected mallocx() failure");
|
||||
|
||||
arena_ralloc_junk_large_orig = arena_ralloc_junk_large;
|
||||
arena_ralloc_junk_large = arena_ralloc_junk_large_intercept;
|
||||
|
||||
p2 = rallocx(p1, shrink_size(large_maxclass), 0);
|
||||
assert_ptr_eq(p1, p2, "Unexpected move during shrink");
|
||||
|
||||
arena_ralloc_junk_large = arena_ralloc_junk_large_orig;
|
||||
|
||||
assert_ptr_eq(most_recently_trimmed, p1,
|
||||
"Expected trimmed portion of region to be junk-filled");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static bool detected_redzone_corruption;
|
||||
|
||||
static void
|
||||
arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,
|
||||
size_t offset, uint8_t byte)
|
||||
{
|
||||
|
||||
detected_redzone_corruption = true;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_junk_redzone)
|
||||
{
|
||||
char *s;
|
||||
arena_redzone_corruption_t *arena_redzone_corruption_orig;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_skip_if(!opt_junk_alloc || !opt_junk_free);
|
||||
|
||||
arena_redzone_corruption_orig = arena_redzone_corruption;
|
||||
arena_redzone_corruption = arena_redzone_corruption_replacement;
|
||||
|
||||
/* Test underflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[-1] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
/* Test overflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[sallocx(s, 0)] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
arena_redzone_corruption = arena_redzone_corruption_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_junk_small,
|
||||
test_junk_large,
|
||||
test_junk_huge,
|
||||
test_junk_large_ralloc_shrink,
|
||||
test_junk_redzone));
|
||||
}
|
||||
3
memory/jemalloc/src/test/unit/junk_alloc.c
Normal file
3
memory/jemalloc/src/test/unit/junk_alloc.c
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#define JEMALLOC_TEST_JUNK_OPT "junk:alloc"
|
||||
#include "junk.c"
|
||||
#undef JEMALLOC_TEST_JUNK_OPT
|
||||
3
memory/jemalloc/src/test/unit/junk_free.c
Normal file
3
memory/jemalloc/src/test/unit/junk_free.c
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#define JEMALLOC_TEST_JUNK_OPT "junk:free"
|
||||
#include "junk.c"
|
||||
#undef JEMALLOC_TEST_JUNK_OPT
|
||||
26
memory/jemalloc/src/test/unit/lg_chunk.c
Normal file
26
memory/jemalloc/src/test/unit/lg_chunk.c
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
/*
|
||||
* Make sure that opt.lg_chunk clamping is sufficient. In practice, this test
|
||||
* program will fail a debug assertion during initialization and abort (rather
|
||||
* than the test soft-failing) if clamping is insufficient.
|
||||
*/
|
||||
const char *malloc_conf = "lg_chunk:0";
|
||||
|
||||
TEST_BEGIN(test_lg_chunk_clamp)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_lg_chunk_clamp));
|
||||
}
|
||||
731
memory/jemalloc/src/test/unit/mallctl.c
Normal file
731
memory/jemalloc/src/test/unit/mallctl.c
Normal file
|
|
@ -0,0 +1,731 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_mallctl_errors)
|
||||
{
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
|
||||
assert_d_eq(mallctl("no_such_name", NULL, NULL, NULL, 0), ENOENT,
|
||||
"mallctl() should return ENOENT for non-existent names");
|
||||
|
||||
assert_d_eq(mallctl("version", NULL, NULL, "0.0.0", strlen("0.0.0")),
|
||||
EPERM, "mallctl() should return EPERM on attempt to write "
|
||||
"read-only value");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)-1),
|
||||
EINVAL, "mallctl() should return EINVAL for input size mismatch");
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)+1),
|
||||
EINVAL, "mallctl() should return EINVAL for input size mismatch");
|
||||
|
||||
sz = sizeof(epoch)-1;
|
||||
assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctl() should return EINVAL for output size mismatch");
|
||||
sz = sizeof(epoch)+1;
|
||||
assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctl() should return EINVAL for output size mismatch");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlnametomib_errors)
|
||||
{
|
||||
size_t mib[1];
|
||||
size_t miblen;
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("no_such_name", mib, &miblen), ENOENT,
|
||||
"mallctlnametomib() should return ENOENT for non-existent names");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlbymib_errors)
|
||||
{
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
size_t mib[1];
|
||||
size_t miblen;
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("version", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, "0.0.0",
|
||||
strlen("0.0.0")), EPERM, "mallctl() should return EPERM on "
|
||||
"attempt to write read-only value");
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
|
||||
sizeof(epoch)-1), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for input size mismatch");
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
|
||||
sizeof(epoch)+1), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for input size mismatch");
|
||||
|
||||
sz = sizeof(epoch)-1;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for output size mismatch");
|
||||
sz = sizeof(epoch)+1;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL,
|
||||
"mallctlbymib() should return EINVAL for output size mismatch");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_read_write)
|
||||
{
|
||||
uint64_t old_epoch, new_epoch;
|
||||
size_t sz = sizeof(old_epoch);
|
||||
|
||||
/* Blind. */
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Read. */
|
||||
assert_d_eq(mallctl("epoch", &old_epoch, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Write. */
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &new_epoch, sizeof(new_epoch)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
|
||||
/* Read+write. */
|
||||
assert_d_eq(mallctl("epoch", &old_epoch, &sz, &new_epoch,
|
||||
sizeof(new_epoch)), 0, "Unexpected mallctl() failure");
|
||||
assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctlnametomib_short_mib)
|
||||
{
|
||||
size_t mib[4];
|
||||
size_t miblen;
|
||||
|
||||
miblen = 3;
|
||||
mib[3] = 42;
|
||||
assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
assert_zu_eq(miblen, 3, "Unexpected mib output length");
|
||||
assert_zu_eq(mib[3], 42,
|
||||
"mallctlnametomib() wrote past the end of the input mib");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_config)
|
||||
{
|
||||
|
||||
#define TEST_MALLCTL_CONFIG(config, t) do { \
|
||||
t oldval; \
|
||||
size_t sz = sizeof(oldval); \
|
||||
assert_d_eq(mallctl("config."#config, &oldval, &sz, NULL, 0), \
|
||||
0, "Unexpected mallctl() failure"); \
|
||||
assert_b_eq(oldval, config_##config, "Incorrect config value"); \
|
||||
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_MALLCTL_CONFIG(cache_oblivious, bool);
|
||||
TEST_MALLCTL_CONFIG(debug, bool);
|
||||
TEST_MALLCTL_CONFIG(fill, bool);
|
||||
TEST_MALLCTL_CONFIG(lazy_lock, bool);
|
||||
TEST_MALLCTL_CONFIG(malloc_conf, const char *);
|
||||
TEST_MALLCTL_CONFIG(munmap, bool);
|
||||
TEST_MALLCTL_CONFIG(prof, bool);
|
||||
TEST_MALLCTL_CONFIG(prof_libgcc, bool);
|
||||
TEST_MALLCTL_CONFIG(prof_libunwind, bool);
|
||||
TEST_MALLCTL_CONFIG(stats, bool);
|
||||
TEST_MALLCTL_CONFIG(tcache, bool);
|
||||
TEST_MALLCTL_CONFIG(tls, bool);
|
||||
TEST_MALLCTL_CONFIG(utrace, bool);
|
||||
TEST_MALLCTL_CONFIG(valgrind, bool);
|
||||
TEST_MALLCTL_CONFIG(xmalloc, bool);
|
||||
|
||||
#undef TEST_MALLCTL_CONFIG
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_mallctl_opt)
|
||||
{
|
||||
bool config_always = true;
|
||||
|
||||
#define TEST_MALLCTL_OPT(t, opt, config) do { \
|
||||
t oldval; \
|
||||
size_t sz = sizeof(oldval); \
|
||||
int expected = config_##config ? 0 : ENOENT; \
|
||||
int result = mallctl("opt."#opt, &oldval, &sz, NULL, 0); \
|
||||
assert_d_eq(result, expected, \
|
||||
"Unexpected mallctl() result for opt."#opt); \
|
||||
assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_MALLCTL_OPT(bool, abort, always);
|
||||
TEST_MALLCTL_OPT(size_t, lg_chunk, always);
|
||||
TEST_MALLCTL_OPT(const char *, dss, always);
|
||||
TEST_MALLCTL_OPT(unsigned, narenas, always);
|
||||
TEST_MALLCTL_OPT(const char *, purge, always);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);
|
||||
TEST_MALLCTL_OPT(ssize_t, decay_time, always);
|
||||
TEST_MALLCTL_OPT(bool, stats_print, always);
|
||||
TEST_MALLCTL_OPT(const char *, junk, fill);
|
||||
TEST_MALLCTL_OPT(size_t, quarantine, fill);
|
||||
TEST_MALLCTL_OPT(bool, redzone, fill);
|
||||
TEST_MALLCTL_OPT(bool, zero, fill);
|
||||
TEST_MALLCTL_OPT(bool, utrace, utrace);
|
||||
TEST_MALLCTL_OPT(bool, xmalloc, xmalloc);
|
||||
TEST_MALLCTL_OPT(bool, tcache, tcache);
|
||||
TEST_MALLCTL_OPT(size_t, lg_tcache_max, tcache);
|
||||
TEST_MALLCTL_OPT(bool, prof, prof);
|
||||
TEST_MALLCTL_OPT(const char *, prof_prefix, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_active, prof);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_prof_sample, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_accum, prof);
|
||||
TEST_MALLCTL_OPT(ssize_t, lg_prof_interval, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_gdump, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_final, prof);
|
||||
TEST_MALLCTL_OPT(bool, prof_leak, prof);
|
||||
|
||||
#undef TEST_MALLCTL_OPT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_manpage_example)
|
||||
{
|
||||
unsigned nbins, i;
|
||||
size_t mib[4];
|
||||
size_t len, miblen;
|
||||
|
||||
len = sizeof(nbins);
|
||||
assert_d_eq(mallctl("arenas.nbins", &nbins, &len, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
miblen = 4;
|
||||
assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
for (i = 0; i < nbins; i++) {
|
||||
size_t bin_size;
|
||||
|
||||
mib[2] = i;
|
||||
len = sizeof(bin_size);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0),
|
||||
0, "Unexpected mallctlbymib() failure");
|
||||
/* Do something with bin_size... */
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_tcache_none)
|
||||
{
|
||||
void *p0, *q, *p1;
|
||||
|
||||
test_skip_if(!config_tcache);
|
||||
|
||||
/* Allocate p and q. */
|
||||
p0 = mallocx(42, 0);
|
||||
assert_ptr_not_null(p0, "Unexpected mallocx() failure");
|
||||
q = mallocx(42, 0);
|
||||
assert_ptr_not_null(q, "Unexpected mallocx() failure");
|
||||
|
||||
/* Deallocate p and q, but bypass the tcache for q. */
|
||||
dallocx(p0, 0);
|
||||
dallocx(q, MALLOCX_TCACHE_NONE);
|
||||
|
||||
/* Make sure that tcache-based allocation returns p, not q. */
|
||||
p1 = mallocx(42, 0);
|
||||
assert_ptr_not_null(p1, "Unexpected mallocx() failure");
|
||||
assert_ptr_eq(p0, p1, "Expected tcache to allocate cached region");
|
||||
|
||||
/* Clean up. */
|
||||
dallocx(p1, MALLOCX_TCACHE_NONE);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_tcache)
|
||||
{
|
||||
#define NTCACHES 10
|
||||
unsigned tis[NTCACHES];
|
||||
void *ps[NTCACHES];
|
||||
void *qs[NTCACHES];
|
||||
unsigned i;
|
||||
size_t sz, psz, qsz;
|
||||
|
||||
test_skip_if(!config_tcache);
|
||||
|
||||
psz = 42;
|
||||
qsz = nallocx(psz, 0) + 1;
|
||||
|
||||
/* Create tcaches. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure, i=%u", i);
|
||||
}
|
||||
|
||||
/* Exercise tcache ID recycling. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i],
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
|
||||
i);
|
||||
}
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure, i=%u", i);
|
||||
}
|
||||
|
||||
/* Flush empty tcaches. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i],
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
|
||||
i);
|
||||
}
|
||||
|
||||
/* Cache some allocations. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
|
||||
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
|
||||
i);
|
||||
dallocx(ps[i], MALLOCX_TCACHE(tis[i]));
|
||||
|
||||
qs[i] = mallocx(qsz, MALLOCX_TCACHE(tis[i]));
|
||||
assert_ptr_not_null(qs[i], "Unexpected mallocx() failure, i=%u",
|
||||
i);
|
||||
dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
|
||||
}
|
||||
|
||||
/* Verify that tcaches allocate cached regions. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
void *p0 = ps[i];
|
||||
ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
|
||||
assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
|
||||
i);
|
||||
assert_ptr_eq(ps[i], p0,
|
||||
"Expected mallocx() to allocate cached region, i=%u", i);
|
||||
}
|
||||
|
||||
/* Verify that reallocation uses cached regions. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
void *q0 = qs[i];
|
||||
qs[i] = rallocx(ps[i], qsz, MALLOCX_TCACHE(tis[i]));
|
||||
assert_ptr_not_null(qs[i], "Unexpected rallocx() failure, i=%u",
|
||||
i);
|
||||
assert_ptr_eq(qs[i], q0,
|
||||
"Expected rallocx() to allocate cached region, i=%u", i);
|
||||
/* Avoid undefined behavior in case of test failure. */
|
||||
if (qs[i] == NULL)
|
||||
qs[i] = ps[i];
|
||||
}
|
||||
for (i = 0; i < NTCACHES; i++)
|
||||
dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
|
||||
|
||||
/* Flush some non-empty tcaches. */
|
||||
for (i = 0; i < NTCACHES/2; i++) {
|
||||
assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i],
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
|
||||
i);
|
||||
}
|
||||
|
||||
/* Destroy tcaches. */
|
||||
for (i = 0; i < NTCACHES; i++) {
|
||||
assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i],
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
|
||||
i);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_thread_arena)
|
||||
{
|
||||
unsigned arena_old, arena_new, narenas;
|
||||
size_t sz = sizeof(unsigned);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect");
|
||||
arena_new = narenas - 1;
|
||||
assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure");
|
||||
arena_new = 0;
|
||||
assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new,
|
||||
sizeof(unsigned)), 0, "Unexpected mallctl() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_lg_dirty_mult)
|
||||
{
|
||||
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
|
||||
size_t sz = sizeof(ssize_t);
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_ratio);
|
||||
|
||||
assert_d_eq(mallctl("arena.0.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
|
||||
lg_dirty_mult = -2;
|
||||
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
|
||||
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
lg_dirty_mult = (sizeof(size_t) << 3);
|
||||
assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
|
||||
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
|
||||
lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult
|
||||
= lg_dirty_mult, lg_dirty_mult++) {
|
||||
ssize_t old_lg_dirty_mult;
|
||||
|
||||
assert_d_eq(mallctl("arena.0.lg_dirty_mult", &old_lg_dirty_mult,
|
||||
&sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
|
||||
"Unexpected old arena.0.lg_dirty_mult");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_decay_time)
|
||||
{
|
||||
ssize_t decay_time, orig_decay_time, prev_decay_time;
|
||||
size_t sz = sizeof(ssize_t);
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_decay);
|
||||
|
||||
assert_d_eq(mallctl("arena.0.decay_time", &orig_decay_time, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
|
||||
decay_time = -2;
|
||||
assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
|
||||
&decay_time, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
decay_time = 0x7fffffff;
|
||||
assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
|
||||
&decay_time, sizeof(ssize_t)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
for (prev_decay_time = decay_time, decay_time = -1;
|
||||
decay_time < 20; prev_decay_time = decay_time, decay_time++) {
|
||||
ssize_t old_decay_time;
|
||||
|
||||
assert_d_eq(mallctl("arena.0.decay_time", &old_decay_time,
|
||||
&sz, &decay_time, sizeof(ssize_t)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zd_eq(old_decay_time, prev_decay_time,
|
||||
"Unexpected old arena.0.decay_time");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_purge)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t sz = sizeof(unsigned);
|
||||
size_t mib[3];
|
||||
size_t miblen = 3;
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_d_eq(mallctlnametomib("arena.0.purge", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
mib[1] = narenas;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctlbymib() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_decay)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t sz = sizeof(unsigned);
|
||||
size_t mib[3];
|
||||
size_t miblen = 3;
|
||||
|
||||
assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_d_eq(mallctlnametomib("arena.0.decay", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() failure");
|
||||
mib[1] = narenas;
|
||||
assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctlbymib() failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arena_i_dss)
|
||||
{
|
||||
const char *dss_prec_old, *dss_prec_new;
|
||||
size_t sz = sizeof(dss_prec_old);
|
||||
size_t mib[3];
|
||||
size_t miblen;
|
||||
|
||||
miblen = sizeof(mib)/sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() error");
|
||||
|
||||
dss_prec_new = "disabled";
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
|
||||
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
|
||||
assert_str_ne(dss_prec_old, "primary",
|
||||
"Unexpected default for dss precedence");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
|
||||
sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_str_ne(dss_prec_old, "primary",
|
||||
"Unexpected value for dss precedence");
|
||||
|
||||
mib[1] = narenas_total_get();
|
||||
dss_prec_new = "disabled";
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new,
|
||||
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
|
||||
assert_str_ne(dss_prec_old, "primary",
|
||||
"Unexpected default for dss precedence");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old,
|
||||
sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_str_ne(dss_prec_old, "primary",
|
||||
"Unexpected value for dss precedence");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_initialized)
|
||||
{
|
||||
unsigned narenas;
|
||||
size_t sz = sizeof(narenas);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
{
|
||||
VARIABLE_ARRAY(bool, initialized, narenas);
|
||||
|
||||
sz = narenas * sizeof(bool);
|
||||
assert_d_eq(mallctl("arenas.initialized", initialized, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_lg_dirty_mult)
|
||||
{
|
||||
ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
|
||||
size_t sz = sizeof(ssize_t);
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_ratio);
|
||||
|
||||
assert_d_eq(mallctl("arenas.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
|
||||
lg_dirty_mult = -2;
|
||||
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
|
||||
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
lg_dirty_mult = (sizeof(size_t) << 3);
|
||||
assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
|
||||
&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
|
||||
lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult =
|
||||
lg_dirty_mult, lg_dirty_mult++) {
|
||||
ssize_t old_lg_dirty_mult;
|
||||
|
||||
assert_d_eq(mallctl("arenas.lg_dirty_mult", &old_lg_dirty_mult,
|
||||
&sz, &lg_dirty_mult, sizeof(ssize_t)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
|
||||
"Unexpected old arenas.lg_dirty_mult");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_decay_time)
|
||||
{
|
||||
ssize_t decay_time, orig_decay_time, prev_decay_time;
|
||||
size_t sz = sizeof(ssize_t);
|
||||
|
||||
test_skip_if(opt_purge != purge_mode_decay);
|
||||
|
||||
assert_d_eq(mallctl("arenas.decay_time", &orig_decay_time, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl() failure");
|
||||
|
||||
decay_time = -2;
|
||||
assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
|
||||
&decay_time, sizeof(ssize_t)), EFAULT,
|
||||
"Unexpected mallctl() success");
|
||||
|
||||
decay_time = 0x7fffffff;
|
||||
assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
|
||||
&decay_time, sizeof(ssize_t)), 0,
|
||||
"Expected mallctl() failure");
|
||||
|
||||
for (prev_decay_time = decay_time, decay_time = -1;
|
||||
decay_time < 20; prev_decay_time = decay_time, decay_time++) {
|
||||
ssize_t old_decay_time;
|
||||
|
||||
assert_d_eq(mallctl("arenas.decay_time", &old_decay_time,
|
||||
&sz, &decay_time, sizeof(ssize_t)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_zd_eq(old_decay_time, prev_decay_time,
|
||||
"Unexpected old arenas.decay_time");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas."#name, &name, &sz, NULL, 0), 0, \
|
||||
"Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_CONSTANT(size_t, quantum, QUANTUM);
|
||||
TEST_ARENAS_CONSTANT(size_t, page, PAGE);
|
||||
TEST_ARENAS_CONSTANT(unsigned, nbins, NBINS);
|
||||
TEST_ARENAS_CONSTANT(unsigned, nlruns, nlclasses);
|
||||
TEST_ARENAS_CONSTANT(unsigned, nhchunks, nhclasses);
|
||||
|
||||
#undef TEST_ARENAS_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_bin_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas.bin.0."#name, &name, &sz, NULL, 0), \
|
||||
0, "Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_BIN_CONSTANT(size_t, size, arena_bin_info[0].reg_size);
|
||||
TEST_ARENAS_BIN_CONSTANT(uint32_t, nregs, arena_bin_info[0].nregs);
|
||||
TEST_ARENAS_BIN_CONSTANT(size_t, run_size, arena_bin_info[0].run_size);
|
||||
|
||||
#undef TEST_ARENAS_BIN_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_lrun_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas.lrun.0."#name, &name, &sz, NULL, \
|
||||
0), 0, "Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_LRUN_CONSTANT(size_t, size, LARGE_MINCLASS);
|
||||
|
||||
#undef TEST_ARENAS_LRUN_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_hchunk_constants)
|
||||
{
|
||||
|
||||
#define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("arenas.hchunk.0."#name, &name, &sz, NULL, \
|
||||
0), 0, "Unexpected mallctl() failure"); \
|
||||
assert_zu_eq(name, expected, "Incorrect "#name" size"); \
|
||||
} while (0)
|
||||
|
||||
TEST_ARENAS_HCHUNK_CONSTANT(size_t, size, chunksize);
|
||||
|
||||
#undef TEST_ARENAS_HCHUNK_CONSTANT
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_arenas_extend)
|
||||
{
|
||||
unsigned narenas_before, arena, narenas_after;
|
||||
size_t sz = sizeof(unsigned);
|
||||
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas_before, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_d_eq(mallctl("arenas.extend", &arena, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
assert_d_eq(mallctl("arenas.narenas", &narenas_after, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_u_eq(narenas_before+1, narenas_after,
|
||||
"Unexpected number of arenas before versus after extension");
|
||||
assert_u_eq(arena, narenas_after-1, "Unexpected arena index");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas)
|
||||
{
|
||||
|
||||
#define TEST_STATS_ARENAS(t, name) do { \
|
||||
t name; \
|
||||
size_t sz = sizeof(t); \
|
||||
assert_d_eq(mallctl("stats.arenas.0."#name, &name, &sz, NULL, \
|
||||
0), 0, "Unexpected mallctl() failure"); \
|
||||
} while (0)
|
||||
|
||||
TEST_STATS_ARENAS(unsigned, nthreads);
|
||||
TEST_STATS_ARENAS(const char *, dss);
|
||||
TEST_STATS_ARENAS(ssize_t, lg_dirty_mult);
|
||||
TEST_STATS_ARENAS(ssize_t, decay_time);
|
||||
TEST_STATS_ARENAS(size_t, pactive);
|
||||
TEST_STATS_ARENAS(size_t, pdirty);
|
||||
|
||||
#undef TEST_STATS_ARENAS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_mallctl_errors,
|
||||
test_mallctlnametomib_errors,
|
||||
test_mallctlbymib_errors,
|
||||
test_mallctl_read_write,
|
||||
test_mallctlnametomib_short_mib,
|
||||
test_mallctl_config,
|
||||
test_mallctl_opt,
|
||||
test_manpage_example,
|
||||
test_tcache_none,
|
||||
test_tcache,
|
||||
test_thread_arena,
|
||||
test_arena_i_lg_dirty_mult,
|
||||
test_arena_i_decay_time,
|
||||
test_arena_i_purge,
|
||||
test_arena_i_decay,
|
||||
test_arena_i_dss,
|
||||
test_arenas_initialized,
|
||||
test_arenas_lg_dirty_mult,
|
||||
test_arenas_decay_time,
|
||||
test_arenas_constants,
|
||||
test_arenas_bin_constants,
|
||||
test_arenas_lrun_constants,
|
||||
test_arenas_hchunk_constants,
|
||||
test_arenas_extend,
|
||||
test_stats_arenas));
|
||||
}
|
||||
398
memory/jemalloc/src/test/unit/math.c
Normal file
398
memory/jemalloc/src/test/unit/math.c
Normal file
|
|
@ -0,0 +1,398 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define MAX_REL_ERR 1.0e-9
|
||||
#define MAX_ABS_ERR 1.0e-9
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#ifdef __PGI
|
||||
#undef INFINITY
|
||||
#endif
|
||||
|
||||
#ifndef INFINITY
|
||||
#define INFINITY (DBL_MAX + DBL_MAX)
|
||||
#endif
|
||||
|
||||
static bool
|
||||
double_eq_rel(double a, double b, double max_rel_err, double max_abs_err)
|
||||
{
|
||||
double rel_err;
|
||||
|
||||
if (fabs(a - b) < max_abs_err)
|
||||
return (true);
|
||||
rel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a);
|
||||
return (rel_err < max_rel_err);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
factorial(unsigned x)
|
||||
{
|
||||
uint64_t ret = 1;
|
||||
unsigned i;
|
||||
|
||||
for (i = 2; i <= x; i++)
|
||||
ret *= (uint64_t)i;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ln_gamma_factorial)
|
||||
{
|
||||
unsigned x;
|
||||
|
||||
/* exp(ln_gamma(x)) == (x-1)! for integer x. */
|
||||
for (x = 1; x <= 21; x++) {
|
||||
assert_true(double_eq_rel(exp(ln_gamma(x)),
|
||||
(double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect factorial result for x=%u", x);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/* Expected ln_gamma([0.0..100.0] increment=0.25). */
|
||||
static const double ln_gamma_misc_expected[] = {
|
||||
INFINITY,
|
||||
1.28802252469807743, 0.57236494292470008, 0.20328095143129538,
|
||||
0.00000000000000000, -0.09827183642181320, -0.12078223763524518,
|
||||
-0.08440112102048555, 0.00000000000000000, 0.12487171489239651,
|
||||
0.28468287047291918, 0.47521466691493719, 0.69314718055994529,
|
||||
0.93580193110872523, 1.20097360234707429, 1.48681557859341718,
|
||||
1.79175946922805496, 2.11445692745037128, 2.45373657084244234,
|
||||
2.80857141857573644, 3.17805383034794575, 3.56137591038669710,
|
||||
3.95781396761871651, 4.36671603662228680, 4.78749174278204581,
|
||||
5.21960398699022932, 5.66256205985714178, 6.11591589143154568,
|
||||
6.57925121201010121, 7.05218545073853953, 7.53436423675873268,
|
||||
8.02545839631598312, 8.52516136106541467, 9.03318691960512332,
|
||||
9.54926725730099690, 10.07315123968123949, 10.60460290274525086,
|
||||
11.14340011995171231, 11.68933342079726856, 12.24220494005076176,
|
||||
12.80182748008146909, 13.36802367147604720, 13.94062521940376342,
|
||||
14.51947222506051816, 15.10441257307551943, 15.69530137706046524,
|
||||
16.29200047656724237, 16.89437797963419285, 17.50230784587389010,
|
||||
18.11566950571089407, 18.73434751193644843, 19.35823122022435427,
|
||||
19.98721449566188468, 20.62119544270163018, 21.26007615624470048,
|
||||
21.90376249182879320, 22.55216385312342098, 23.20519299513386002,
|
||||
23.86276584168908954, 24.52480131594137802, 25.19122118273868338,
|
||||
25.86194990184851861, 26.53691449111561340, 27.21604439872720604,
|
||||
27.89927138384089389, 28.58652940490193828, 29.27775451504081516,
|
||||
29.97288476399884871, 30.67186010608067548, 31.37462231367769050,
|
||||
32.08111489594735843, 32.79128302226991565, 33.50507345013689076,
|
||||
34.22243445715505317, 34.94331577687681545, 35.66766853819134298,
|
||||
36.39544520803305261, 37.12659953718355865, 37.86108650896109395,
|
||||
38.59886229060776230, 39.33988418719949465, 40.08411059791735198,
|
||||
40.83150097453079752, 41.58201578195490100, 42.33561646075348506,
|
||||
43.09226539146988699, 43.85192586067515208, 44.61456202863158893,
|
||||
45.38013889847690052, 46.14862228684032885, 46.91997879580877395,
|
||||
47.69417578616628361, 48.47118135183522014, 49.25096429545256882,
|
||||
50.03349410501914463, 50.81874093156324790, 51.60667556776436982,
|
||||
52.39726942748592364, 53.19049452616926743, 53.98632346204390586,
|
||||
54.78472939811231157, 55.58568604486942633, 56.38916764371992940,
|
||||
57.19514895105859864, 58.00360522298051080, 58.81451220059079787,
|
||||
59.62784609588432261, 60.44358357816834371, 61.26170176100199427,
|
||||
62.08217818962842927, 62.90499082887649962, 63.73011805151035958,
|
||||
64.55753862700632340, 65.38723171073768015, 66.21917683354901385,
|
||||
67.05335389170279825, 67.88974313718154008, 68.72832516833013017,
|
||||
69.56908092082363737, 70.41199165894616385, 71.25703896716800045,
|
||||
72.10420474200799390, 72.95347118416940191, 73.80482079093779646,
|
||||
74.65823634883015814, 75.51370092648485866, 76.37119786778275454,
|
||||
77.23071078519033961, 78.09222355331530707, 78.95572030266725960,
|
||||
79.82118541361435859, 80.68860351052903468, 81.55795945611502873,
|
||||
82.42923834590904164, 83.30242550295004378, 84.17750647261028973,
|
||||
85.05446701758152983, 85.93329311301090456, 86.81397094178107920,
|
||||
87.69648688992882057, 88.58082754219766741, 89.46697967771913795,
|
||||
90.35493026581838194, 91.24466646193963015, 92.13617560368709292,
|
||||
93.02944520697742803, 93.92446296229978486, 94.82121673107967297,
|
||||
95.71969454214321615, 96.61988458827809723, 97.52177522288820910,
|
||||
98.42535495673848800, 99.33061245478741341, 100.23753653310367895,
|
||||
101.14611615586458981, 102.05634043243354370, 102.96819861451382394,
|
||||
103.88168009337621811, 104.79677439715833032, 105.71347118823287303,
|
||||
106.63176026064346047, 107.55163153760463501, 108.47307506906540198,
|
||||
109.39608102933323153, 110.32063971475740516, 111.24674154146920557,
|
||||
112.17437704317786995, 113.10353686902013237, 114.03421178146170689,
|
||||
114.96639265424990128, 115.90007047041454769, 116.83523632031698014,
|
||||
117.77188139974506953, 118.70999700805310795, 119.64957454634490830,
|
||||
120.59060551569974962, 121.53308151543865279, 122.47699424143097247,
|
||||
123.42233548443955726, 124.36909712850338394, 125.31727114935689826,
|
||||
126.26684961288492559, 127.21782467361175861, 128.17018857322420899,
|
||||
129.12393363912724453, 130.07905228303084755, 131.03553699956862033,
|
||||
131.99338036494577864, 132.95257503561629164, 133.91311374698926784,
|
||||
134.87498931216194364, 135.83819462068046846, 136.80272263732638294,
|
||||
137.76856640092901785, 138.73571902320256299, 139.70417368760718091,
|
||||
140.67392364823425055, 141.64496222871400732, 142.61728282114600574,
|
||||
143.59087888505104047, 144.56574394634486680, 145.54187159633210058,
|
||||
146.51925549072063859, 147.49788934865566148, 148.47776695177302031,
|
||||
149.45888214327129617, 150.44122882700193600, 151.42480096657754984,
|
||||
152.40959258449737490, 153.39559776128982094, 154.38281063467164245,
|
||||
155.37122539872302696, 156.36083630307879844, 157.35163765213474107,
|
||||
158.34362380426921391, 159.33678917107920370, 160.33112821663092973,
|
||||
161.32663545672428995, 162.32330545817117695, 163.32113283808695314,
|
||||
164.32011226319519892, 165.32023844914485267, 166.32150615984036790,
|
||||
167.32391020678358018, 168.32744544842768164, 169.33210678954270634,
|
||||
170.33788918059275375, 171.34478761712384198, 172.35279713916281707,
|
||||
173.36191283062726143, 174.37212981874515094, 175.38344327348534080,
|
||||
176.39584840699734514, 177.40934047306160437, 178.42391476654847793,
|
||||
179.43956662288721304, 180.45629141754378111, 181.47408456550741107,
|
||||
182.49294152078630304, 183.51285777591152737, 184.53382886144947861,
|
||||
185.55585034552262869, 186.57891783333786861, 187.60302696672312095,
|
||||
188.62817342367162610, 189.65435291789341932, 190.68156119837468054,
|
||||
191.70979404894376330, 192.73904728784492590, 193.76931676731820176,
|
||||
194.80059837318714244, 195.83288802445184729, 196.86618167288995096,
|
||||
197.90047530266301123, 198.93576492992946214, 199.97204660246373464,
|
||||
201.00931639928148797, 202.04757043027063901, 203.08680483582807597,
|
||||
204.12701578650228385, 205.16819948264117102, 206.21035215404597807,
|
||||
207.25347005962987623, 208.29754948708190909, 209.34258675253678916,
|
||||
210.38857820024875878, 211.43552020227099320, 212.48340915813977858,
|
||||
213.53224149456323744, 214.58201366511514152, 215.63272214993284592,
|
||||
216.68436345542014010, 217.73693411395422004, 218.79043068359703739,
|
||||
219.84484974781133815, 220.90018791517996988, 221.95644181913033322,
|
||||
223.01360811766215875, 224.07168349307951871, 225.13066465172661879,
|
||||
226.19054832372759734, 227.25133126272962159, 228.31301024565024704,
|
||||
229.37558207242807384, 230.43904356577689896, 231.50339157094342113,
|
||||
232.56862295546847008, 233.63473460895144740, 234.70172344281823484,
|
||||
235.76958639009222907, 236.83832040516844586, 237.90792246359117712,
|
||||
238.97838956183431947, 240.04971871708477238, 241.12190696702904802,
|
||||
242.19495136964280846, 243.26884900298270509, 244.34359696498191283,
|
||||
245.41919237324782443, 246.49563236486270057, 247.57291409618682110,
|
||||
248.65103474266476269, 249.72999149863338175, 250.80978157713354904,
|
||||
251.89040220972316320, 252.97185064629374551, 254.05412415488834199,
|
||||
255.13722002152300661, 256.22113555000953511, 257.30586806178126835,
|
||||
258.39141489572085675, 259.47777340799029844, 260.56494097186322279,
|
||||
261.65291497755913497, 262.74169283208021852, 263.83127195904967266,
|
||||
264.92164979855277807, 266.01282380697938379, 267.10479145686849733,
|
||||
268.19755023675537586, 269.29109765101975427, 270.38543121973674488,
|
||||
271.48054847852881721, 272.57644697842033565, 273.67312428569374561,
|
||||
274.77057798174683967, 275.86880566295326389, 276.96780494052313770,
|
||||
278.06757344036617496, 279.16810880295668085, 280.26940868320008349,
|
||||
281.37147075030043197, 282.47429268763045229, 283.57787219260217171,
|
||||
284.68220697654078322, 285.78729476455760050, 286.89313329542699194,
|
||||
287.99972032146268930, 289.10705360839756395, 290.21513093526289140,
|
||||
291.32395009427028754, 292.43350889069523646, 293.54380514276073200,
|
||||
294.65483668152336350, 295.76660135076059532, 296.87909700685889902,
|
||||
297.99232151870342022, 299.10627276756946458, 300.22094864701409733,
|
||||
301.33634706277030091, 302.45246593264130297, 303.56930318639643929,
|
||||
304.68685676566872189, 305.80512462385280514, 306.92410472600477078,
|
||||
308.04379504874236773, 309.16419358014690033, 310.28529831966631036,
|
||||
311.40710727801865687, 312.52961847709792664, 313.65282994987899201,
|
||||
314.77673974032603610, 315.90134590329950015, 317.02664650446632777,
|
||||
318.15263962020929966, 319.27932333753892635, 320.40669575400545455,
|
||||
321.53475497761127144, 322.66349912672620803, 323.79292633000159185,
|
||||
324.92303472628691452, 326.05382246454587403, 327.18528770377525916,
|
||||
328.31742861292224234, 329.45024337080525356, 330.58373016603343331,
|
||||
331.71788719692847280, 332.85271267144611329, 333.98820480709991898,
|
||||
335.12436183088397001, 336.26118197919845443, 337.39866349777429377,
|
||||
338.53680464159958774, 339.67560367484657036, 340.81505887079896411,
|
||||
341.95516851178109619, 343.09593088908627578, 344.23734430290727460,
|
||||
345.37940706226686416, 346.52211748494903532, 347.66547389743118401,
|
||||
348.80947463481720661, 349.95411804077025408, 351.09940246744753267,
|
||||
352.24532627543504759, 353.39188783368263103, 354.53908551944078908,
|
||||
355.68691771819692349, 356.83538282361303118, 357.98447923746385868,
|
||||
359.13420536957539753
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_ln_gamma_misc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) {
|
||||
double x = (double)i * 0.25;
|
||||
assert_true(double_eq_rel(ln_gamma(x),
|
||||
ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect ln_gamma result for i=%u", i);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/* Expected pt_norm([0.01..0.99] increment=0.01). */
|
||||
static const double pt_norm_expected[] = {
|
||||
-INFINITY,
|
||||
-2.32634787404084076, -2.05374891063182252, -1.88079360815125085,
|
||||
-1.75068607125216946, -1.64485362695147264, -1.55477359459685305,
|
||||
-1.47579102817917063, -1.40507156030963221, -1.34075503369021654,
|
||||
-1.28155156554460081, -1.22652812003661049, -1.17498679206608991,
|
||||
-1.12639112903880045, -1.08031934081495606, -1.03643338949378938,
|
||||
-0.99445788320975281, -0.95416525314619416, -0.91536508784281390,
|
||||
-0.87789629505122846, -0.84162123357291418, -0.80642124701824025,
|
||||
-0.77219321418868492, -0.73884684918521371, -0.70630256284008752,
|
||||
-0.67448975019608171, -0.64334540539291685, -0.61281299101662701,
|
||||
-0.58284150727121620, -0.55338471955567281, -0.52440051270804067,
|
||||
-0.49585034734745320, -0.46769879911450812, -0.43991316567323380,
|
||||
-0.41246312944140462, -0.38532046640756751, -0.35845879325119373,
|
||||
-0.33185334643681652, -0.30548078809939738, -0.27931903444745404,
|
||||
-0.25334710313579978, -0.22754497664114931, -0.20189347914185077,
|
||||
-0.17637416478086135, -0.15096921549677725, -0.12566134685507399,
|
||||
-0.10043372051146975, -0.07526986209982976, -0.05015358346473352,
|
||||
-0.02506890825871106, 0.00000000000000000, 0.02506890825871106,
|
||||
0.05015358346473366, 0.07526986209982990, 0.10043372051146990,
|
||||
0.12566134685507413, 0.15096921549677739, 0.17637416478086146,
|
||||
0.20189347914185105, 0.22754497664114931, 0.25334710313579978,
|
||||
0.27931903444745404, 0.30548078809939738, 0.33185334643681652,
|
||||
0.35845879325119373, 0.38532046640756762, 0.41246312944140484,
|
||||
0.43991316567323391, 0.46769879911450835, 0.49585034734745348,
|
||||
0.52440051270804111, 0.55338471955567303, 0.58284150727121620,
|
||||
0.61281299101662701, 0.64334540539291685, 0.67448975019608171,
|
||||
0.70630256284008752, 0.73884684918521371, 0.77219321418868492,
|
||||
0.80642124701824036, 0.84162123357291441, 0.87789629505122879,
|
||||
0.91536508784281423, 0.95416525314619460, 0.99445788320975348,
|
||||
1.03643338949378938, 1.08031934081495606, 1.12639112903880045,
|
||||
1.17498679206608991, 1.22652812003661049, 1.28155156554460081,
|
||||
1.34075503369021654, 1.40507156030963265, 1.47579102817917085,
|
||||
1.55477359459685394, 1.64485362695147308, 1.75068607125217102,
|
||||
1.88079360815125041, 2.05374891063182208, 2.32634787404084076
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_norm)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) {
|
||||
double p = (double)i * 0.01;
|
||||
assert_true(double_eq_rel(pt_norm(p), pt_norm_expected[i],
|
||||
MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect pt_norm result for i=%u", i);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/*
|
||||
* Expected pt_chi2(p=[0.01..0.99] increment=0.07,
|
||||
* df={0.1, 1.1, 10.1, 100.1, 1000.1}).
|
||||
*/
|
||||
static const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1};
|
||||
static const double pt_chi2_expected[] = {
|
||||
1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17,
|
||||
8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09,
|
||||
5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05,
|
||||
1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03,
|
||||
4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00,
|
||||
|
||||
0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113,
|
||||
0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931,
|
||||
0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259,
|
||||
0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304,
|
||||
2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839,
|
||||
|
||||
2.606673548632508, 4.602913725294877, 5.646152813924212,
|
||||
6.488971315540869, 7.249823275816285, 7.977314231410841,
|
||||
8.700354939944047, 9.441728024225892, 10.224338321374127,
|
||||
11.076435368801061, 12.039320937038386, 13.183878752697167,
|
||||
14.657791935084575, 16.885728216339373, 23.361991680031817,
|
||||
|
||||
70.14844087392152, 80.92379498849355, 85.53325420085891,
|
||||
88.94433120715347, 91.83732712857017, 94.46719943606301,
|
||||
96.96896479994635, 99.43412843510363, 101.94074719829733,
|
||||
104.57228644307247, 107.43900093448734, 110.71844673417287,
|
||||
114.76616819871325, 120.57422505959563, 135.92318818757556,
|
||||
|
||||
899.0072447849649, 937.9271278858220, 953.8117189560207,
|
||||
965.3079371501154, 974.8974061207954, 983.4936235182347,
|
||||
991.5691170518946, 999.4334123954690, 1007.3391826856553,
|
||||
1015.5445154999951, 1024.3777075619569, 1034.3538789836223,
|
||||
1046.4872561869577, 1063.5717461999654, 1107.0741966053859
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_chi2)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned e = 0;
|
||||
|
||||
for (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) {
|
||||
double df = pt_chi2_df[i];
|
||||
double ln_gamma_df = ln_gamma(df * 0.5);
|
||||
for (j = 1; j < 100; j += 7) {
|
||||
double p = (double)j * 0.01;
|
||||
assert_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df),
|
||||
pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR),
|
||||
"Incorrect pt_chi2 result for i=%u, j=%u", i, j);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/*
|
||||
* Expected pt_gamma(p=[0.1..0.99] increment=0.07,
|
||||
* shape=[0.5..3.0] increment=0.5).
|
||||
*/
|
||||
static const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0};
|
||||
static const double pt_gamma_expected[] = {
|
||||
7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02,
|
||||
3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01,
|
||||
1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01,
|
||||
4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01,
|
||||
1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00,
|
||||
|
||||
0.01005033585350144, 0.08338160893905107, 0.16251892949777497,
|
||||
0.24846135929849966, 0.34249030894677596, 0.44628710262841947,
|
||||
0.56211891815354142, 0.69314718055994529, 0.84397007029452920,
|
||||
1.02165124753198167, 1.23787435600161766, 1.51412773262977574,
|
||||
1.89711998488588196, 2.52572864430825783, 4.60517018598809091,
|
||||
|
||||
0.05741590094955853, 0.24747378084860744, 0.39888572212236084,
|
||||
0.54394139997444901, 0.69048812513915159, 0.84311389861296104,
|
||||
1.00580622221479898, 1.18298694218766931, 1.38038096305861213,
|
||||
1.60627736383027453, 1.87396970522337947, 2.20749220408081070,
|
||||
2.65852391865854942, 3.37934630984842244, 5.67243336507218476,
|
||||
|
||||
0.1485547402532659, 0.4657458011640391, 0.6832386130709406,
|
||||
0.8794297834672100, 1.0700752852474524, 1.2629614217350744,
|
||||
1.4638400448580779, 1.6783469900166610, 1.9132338090606940,
|
||||
2.1778589228618777, 2.4868823970010991, 2.8664695666264195,
|
||||
3.3724415436062114, 4.1682658512758071, 6.6383520679938108,
|
||||
|
||||
0.2771490383641385, 0.7195001279643727, 0.9969081732265243,
|
||||
1.2383497880608061, 1.4675206597269927, 1.6953064251816552,
|
||||
1.9291243435606809, 2.1757300955477641, 2.4428032131216391,
|
||||
2.7406534569230616, 3.0851445039665513, 3.5043101122033367,
|
||||
4.0575997065264637, 4.9182956424675286, 7.5431362346944937,
|
||||
|
||||
0.4360451650782932, 0.9983600902486267, 1.3306365880734528,
|
||||
1.6129750834753802, 1.8767241606994294, 2.1357032436097660,
|
||||
2.3988853336865565, 2.6740603137235603, 2.9697561737517959,
|
||||
3.2971457713883265, 3.6731795898504660, 4.1275751617770631,
|
||||
4.7230515633946677, 5.6417477865306020, 8.4059469148854635
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_pt_gamma_shape)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned e = 0;
|
||||
|
||||
for (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) {
|
||||
double shape = pt_gamma_shape[i];
|
||||
double ln_gamma_shape = ln_gamma(shape);
|
||||
for (j = 1; j < 100; j += 7) {
|
||||
double p = (double)j * 0.01;
|
||||
assert_true(double_eq_rel(pt_gamma(p, shape, 1.0,
|
||||
ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR,
|
||||
MAX_ABS_ERR),
|
||||
"Incorrect pt_gamma result for i=%u, j=%u", i, j);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_pt_gamma_scale)
|
||||
{
|
||||
double shape = 1.0;
|
||||
double ln_gamma_shape = ln_gamma(shape);
|
||||
|
||||
assert_true(double_eq_rel(
|
||||
pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0,
|
||||
pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR,
|
||||
MAX_ABS_ERR),
|
||||
"Scale should be trivially equivalent to external multiplication");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ln_gamma_factorial,
|
||||
test_ln_gamma_misc,
|
||||
test_pt_norm,
|
||||
test_pt_chi2,
|
||||
test_pt_gamma_shape,
|
||||
test_pt_gamma_scale));
|
||||
}
|
||||
93
memory/jemalloc/src/test/unit/mq.c
Normal file
93
memory/jemalloc/src/test/unit/mq.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NSENDERS 3
|
||||
#define NMSGS 100000
|
||||
|
||||
typedef struct mq_msg_s mq_msg_t;
|
||||
struct mq_msg_s {
|
||||
mq_msg(mq_msg_t) link;
|
||||
};
|
||||
mq_gen(static, mq_, mq_t, mq_msg_t, link)
|
||||
|
||||
TEST_BEGIN(test_mq_basic)
|
||||
{
|
||||
mq_t mq;
|
||||
mq_msg_t msg;
|
||||
|
||||
assert_false(mq_init(&mq), "Unexpected mq_init() failure");
|
||||
assert_u_eq(mq_count(&mq), 0, "mq should be empty");
|
||||
assert_ptr_null(mq_tryget(&mq),
|
||||
"mq_tryget() should fail when the queue is empty");
|
||||
|
||||
mq_put(&mq, &msg);
|
||||
assert_u_eq(mq_count(&mq), 1, "mq should contain one message");
|
||||
assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg");
|
||||
|
||||
mq_put(&mq, &msg);
|
||||
assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg");
|
||||
|
||||
mq_fini(&mq);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void *
|
||||
thd_receiver_start(void *arg)
|
||||
{
|
||||
mq_t *mq = (mq_t *)arg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < (NSENDERS * NMSGS); i++) {
|
||||
mq_msg_t *msg = mq_get(mq);
|
||||
assert_ptr_not_null(msg, "mq_get() should never return NULL");
|
||||
dallocx(msg, 0);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void *
|
||||
thd_sender_start(void *arg)
|
||||
{
|
||||
mq_t *mq = (mq_t *)arg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NMSGS; i++) {
|
||||
mq_msg_t *msg;
|
||||
void *p;
|
||||
p = mallocx(sizeof(mq_msg_t), 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
msg = (mq_msg_t *)p;
|
||||
mq_put(mq, msg);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_mq_threaded)
|
||||
{
|
||||
mq_t mq;
|
||||
thd_t receiver;
|
||||
thd_t senders[NSENDERS];
|
||||
unsigned i;
|
||||
|
||||
assert_false(mq_init(&mq), "Unexpected mq_init() failure");
|
||||
|
||||
thd_create(&receiver, thd_receiver_start, (void *)&mq);
|
||||
for (i = 0; i < NSENDERS; i++)
|
||||
thd_create(&senders[i], thd_sender_start, (void *)&mq);
|
||||
|
||||
thd_join(receiver, NULL);
|
||||
for (i = 0; i < NSENDERS; i++)
|
||||
thd_join(senders[i], NULL);
|
||||
|
||||
mq_fini(&mq);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_mq_basic,
|
||||
test_mq_threaded));
|
||||
}
|
||||
|
||||
60
memory/jemalloc/src/test/unit/mtx.c
Normal file
60
memory/jemalloc/src/test/unit/mtx.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 2
|
||||
#define NINCRS 2000000
|
||||
|
||||
TEST_BEGIN(test_mtx_basic)
|
||||
{
|
||||
mtx_t mtx;
|
||||
|
||||
assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure");
|
||||
mtx_lock(&mtx);
|
||||
mtx_unlock(&mtx);
|
||||
mtx_fini(&mtx);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
typedef struct {
|
||||
mtx_t mtx;
|
||||
unsigned x;
|
||||
} thd_start_arg_t;
|
||||
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
thd_start_arg_t *arg = (thd_start_arg_t *)varg;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NINCRS; i++) {
|
||||
mtx_lock(&arg->mtx);
|
||||
arg->x++;
|
||||
mtx_unlock(&arg->mtx);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_mtx_race)
|
||||
{
|
||||
thd_start_arg_t arg;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure");
|
||||
arg.x = 0;
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_create(&thds[i], thd_start, (void *)&arg);
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
assert_u_eq(arg.x, NTHREADS * NINCRS,
|
||||
"Race-related counter corruption");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_mtx_basic,
|
||||
test_mtx_race));
|
||||
}
|
||||
227
memory/jemalloc/src/test/unit/nstime.c
Normal file
227
memory/jemalloc/src/test/unit/nstime.c
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define BILLION UINT64_C(1000000000)
|
||||
|
||||
TEST_BEGIN(test_nstime_init)
|
||||
{
|
||||
nstime_t nst;
|
||||
|
||||
nstime_init(&nst, 42000000043);
|
||||
assert_u64_eq(nstime_ns(&nst), 42000000043, "ns incorrectly read");
|
||||
assert_u64_eq(nstime_sec(&nst), 42, "sec incorrectly read");
|
||||
assert_u64_eq(nstime_nsec(&nst), 43, "nsec incorrectly read");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_init2)
|
||||
{
|
||||
nstime_t nst;
|
||||
|
||||
nstime_init2(&nst, 42, 43);
|
||||
assert_u64_eq(nstime_sec(&nst), 42, "sec incorrectly read");
|
||||
assert_u64_eq(nstime_nsec(&nst), 43, "nsec incorrectly read");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_copy)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_init(&nstb, 0);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
assert_u64_eq(nstime_sec(&nstb), 42, "sec incorrectly copied");
|
||||
assert_u64_eq(nstime_nsec(&nstb), 43, "nsec incorrectly copied");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_compare)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0, "Times should be equal");
|
||||
assert_d_eq(nstime_compare(&nstb, &nsta), 0, "Times should be equal");
|
||||
|
||||
nstime_init2(&nstb, 42, 42);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 1,
|
||||
"nsta should be greater than nstb");
|
||||
assert_d_eq(nstime_compare(&nstb, &nsta), -1,
|
||||
"nstb should be less than nsta");
|
||||
|
||||
nstime_init2(&nstb, 42, 44);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), -1,
|
||||
"nsta should be less than nstb");
|
||||
assert_d_eq(nstime_compare(&nstb, &nsta), 1,
|
||||
"nstb should be greater than nsta");
|
||||
|
||||
nstime_init2(&nstb, 41, BILLION - 1);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 1,
|
||||
"nsta should be greater than nstb");
|
||||
assert_d_eq(nstime_compare(&nstb, &nsta), -1,
|
||||
"nstb should be less than nsta");
|
||||
|
||||
nstime_init2(&nstb, 43, 0);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), -1,
|
||||
"nsta should be less than nstb");
|
||||
assert_d_eq(nstime_compare(&nstb, &nsta), 1,
|
||||
"nstb should be greater than nsta");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_add)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_add(&nsta, &nstb);
|
||||
nstime_init2(&nstb, 84, 86);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect addition result");
|
||||
|
||||
nstime_init2(&nsta, 42, BILLION - 1);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_add(&nsta, &nstb);
|
||||
nstime_init2(&nstb, 85, BILLION - 2);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect addition result");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_subtract)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_subtract(&nsta, &nstb);
|
||||
nstime_init(&nstb, 0);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect subtraction result");
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_init2(&nstb, 41, 44);
|
||||
nstime_subtract(&nsta, &nstb);
|
||||
nstime_init2(&nstb, 0, BILLION - 1);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect subtraction result");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_imultiply)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_imultiply(&nsta, 10);
|
||||
nstime_init2(&nstb, 420, 430);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect multiplication result");
|
||||
|
||||
nstime_init2(&nsta, 42, 666666666);
|
||||
nstime_imultiply(&nsta, 3);
|
||||
nstime_init2(&nstb, 127, 999999998);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect multiplication result");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_idivide)
|
||||
{
|
||||
nstime_t nsta, nstb;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_imultiply(&nsta, 10);
|
||||
nstime_idivide(&nsta, 10);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect division result");
|
||||
|
||||
nstime_init2(&nsta, 42, 666666666);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_imultiply(&nsta, 3);
|
||||
nstime_idivide(&nsta, 3);
|
||||
assert_d_eq(nstime_compare(&nsta, &nstb), 0,
|
||||
"Incorrect division result");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_divide)
|
||||
{
|
||||
nstime_t nsta, nstb, nstc;
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_imultiply(&nsta, 10);
|
||||
assert_u64_eq(nstime_divide(&nsta, &nstb), 10,
|
||||
"Incorrect division result");
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_imultiply(&nsta, 10);
|
||||
nstime_init(&nstc, 1);
|
||||
nstime_add(&nsta, &nstc);
|
||||
assert_u64_eq(nstime_divide(&nsta, &nstb), 10,
|
||||
"Incorrect division result");
|
||||
|
||||
nstime_init2(&nsta, 42, 43);
|
||||
nstime_copy(&nstb, &nsta);
|
||||
nstime_imultiply(&nsta, 10);
|
||||
nstime_init(&nstc, 1);
|
||||
nstime_subtract(&nsta, &nstc);
|
||||
assert_u64_eq(nstime_divide(&nsta, &nstb), 9,
|
||||
"Incorrect division result");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_monotonic)
|
||||
{
|
||||
|
||||
nstime_monotonic();
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_nstime_update)
|
||||
{
|
||||
nstime_t nst;
|
||||
|
||||
nstime_init(&nst, 0);
|
||||
|
||||
assert_false(nstime_update(&nst), "Basic time update failed.");
|
||||
|
||||
/* Only Rip Van Winkle sleeps this long. */
|
||||
{
|
||||
nstime_t addend;
|
||||
nstime_init2(&addend, 631152000, 0);
|
||||
nstime_add(&nst, &addend);
|
||||
}
|
||||
{
|
||||
nstime_t nst0;
|
||||
nstime_copy(&nst0, &nst);
|
||||
assert_true(nstime_update(&nst),
|
||||
"Update should detect time roll-back.");
|
||||
assert_d_eq(nstime_compare(&nst, &nst0), 0,
|
||||
"Time should not have been modified");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_nstime_init,
|
||||
test_nstime_init2,
|
||||
test_nstime_copy,
|
||||
test_nstime_compare,
|
||||
test_nstime_add,
|
||||
test_nstime_subtract,
|
||||
test_nstime_imultiply,
|
||||
test_nstime_idivide,
|
||||
test_nstime_divide,
|
||||
test_nstime_monotonic,
|
||||
test_nstime_update));
|
||||
}
|
||||
290
memory/jemalloc/src/test/unit/ph.c
Normal file
290
memory/jemalloc/src/test/unit/ph.c
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
typedef struct node_s node_t;
|
||||
|
||||
struct node_s {
|
||||
#define NODE_MAGIC 0x9823af7e
|
||||
uint32_t magic;
|
||||
phn(node_t) link;
|
||||
uint64_t key;
|
||||
};
|
||||
|
||||
static int
|
||||
node_cmp(const node_t *a, const node_t *b)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (a->key > b->key) - (a->key < b->key);
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Duplicates are not allowed in the heap, so force an
|
||||
* arbitrary ordering for non-identical items with equal keys.
|
||||
*/
|
||||
ret = (((uintptr_t)a) > ((uintptr_t)b))
|
||||
- (((uintptr_t)a) < ((uintptr_t)b));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
node_cmp_magic(const node_t *a, const node_t *b) {
|
||||
|
||||
assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
|
||||
assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
return (node_cmp(a, b));
|
||||
}
|
||||
|
||||
typedef ph(node_t) heap_t;
|
||||
ph_gen(static, heap_, heap_t, node_t, link, node_cmp_magic);
|
||||
|
||||
static void
|
||||
node_print(const node_t *node, unsigned depth)
|
||||
{
|
||||
unsigned i;
|
||||
node_t *leftmost_child, *sibling;
|
||||
|
||||
for (i = 0; i < depth; i++)
|
||||
malloc_printf("\t");
|
||||
malloc_printf("%2"FMTu64"\n", node->key);
|
||||
|
||||
leftmost_child = phn_lchild_get(node_t, link, node);
|
||||
if (leftmost_child == NULL)
|
||||
return;
|
||||
node_print(leftmost_child, depth + 1);
|
||||
|
||||
for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
|
||||
NULL; sibling = phn_next_get(node_t, link, sibling)) {
|
||||
node_print(sibling, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
heap_print(const heap_t *heap)
|
||||
{
|
||||
node_t *auxelm;
|
||||
|
||||
malloc_printf("vvv heap %p vvv\n", heap);
|
||||
if (heap->ph_root == NULL)
|
||||
goto label_return;
|
||||
|
||||
node_print(heap->ph_root, 0);
|
||||
|
||||
for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
|
||||
auxelm = phn_next_get(node_t, link, auxelm)) {
|
||||
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
|
||||
link, auxelm)), auxelm,
|
||||
"auxelm's prev doesn't link to auxelm");
|
||||
node_print(auxelm, 0);
|
||||
}
|
||||
|
||||
label_return:
|
||||
malloc_printf("^^^ heap %p ^^^\n", heap);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
node_validate(const node_t *node, const node_t *parent)
|
||||
{
|
||||
unsigned nnodes = 1;
|
||||
node_t *leftmost_child, *sibling;
|
||||
|
||||
if (parent != NULL) {
|
||||
assert_d_ge(node_cmp_magic(node, parent), 0,
|
||||
"Child is less than parent");
|
||||
}
|
||||
|
||||
leftmost_child = phn_lchild_get(node_t, link, node);
|
||||
if (leftmost_child == NULL)
|
||||
return (nnodes);
|
||||
assert_ptr_eq((void *)phn_prev_get(node_t, link, leftmost_child),
|
||||
(void *)node, "Leftmost child does not link to node");
|
||||
nnodes += node_validate(leftmost_child, node);
|
||||
|
||||
for (sibling = phn_next_get(node_t, link, leftmost_child); sibling !=
|
||||
NULL; sibling = phn_next_get(node_t, link, sibling)) {
|
||||
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
|
||||
link, sibling)), sibling,
|
||||
"sibling's prev doesn't link to sibling");
|
||||
nnodes += node_validate(sibling, node);
|
||||
}
|
||||
return (nnodes);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
heap_validate(const heap_t *heap)
|
||||
{
|
||||
unsigned nnodes = 0;
|
||||
node_t *auxelm;
|
||||
|
||||
if (heap->ph_root == NULL)
|
||||
goto label_return;
|
||||
|
||||
nnodes += node_validate(heap->ph_root, NULL);
|
||||
|
||||
for (auxelm = phn_next_get(node_t, link, heap->ph_root); auxelm != NULL;
|
||||
auxelm = phn_next_get(node_t, link, auxelm)) {
|
||||
assert_ptr_eq(phn_next_get(node_t, link, phn_prev_get(node_t,
|
||||
link, auxelm)), auxelm,
|
||||
"auxelm's prev doesn't link to auxelm");
|
||||
nnodes += node_validate(auxelm, NULL);
|
||||
}
|
||||
|
||||
label_return:
|
||||
if (false)
|
||||
heap_print(heap);
|
||||
return (nnodes);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ph_empty)
|
||||
{
|
||||
heap_t heap;
|
||||
|
||||
heap_new(&heap);
|
||||
assert_true(heap_empty(&heap), "Heap should be empty");
|
||||
assert_ptr_null(heap_first(&heap), "Unexpected node");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
node_remove(heap_t *heap, node_t *node)
|
||||
{
|
||||
|
||||
heap_remove(heap, node);
|
||||
|
||||
node->magic = 0;
|
||||
}
|
||||
|
||||
static node_t *
|
||||
node_remove_first(heap_t *heap)
|
||||
{
|
||||
node_t *node = heap_remove_first(heap);
|
||||
node->magic = 0;
|
||||
return (node);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ph_random)
|
||||
{
|
||||
#define NNODES 25
|
||||
#define NBAGS 250
|
||||
#define SEED 42
|
||||
sfmt_t *sfmt;
|
||||
uint64_t bag[NNODES];
|
||||
heap_t heap;
|
||||
node_t nodes[NNODES];
|
||||
unsigned i, j, k;
|
||||
|
||||
sfmt = init_gen_rand(SEED);
|
||||
for (i = 0; i < NBAGS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
/* Insert in order. */
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = j;
|
||||
break;
|
||||
case 1:
|
||||
/* Insert in reverse order. */
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = NNODES - j - 1;
|
||||
break;
|
||||
default:
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = gen_rand64_range(sfmt, NNODES);
|
||||
}
|
||||
|
||||
for (j = 1; j <= NNODES; j++) {
|
||||
/* Initialize heap and nodes. */
|
||||
heap_new(&heap);
|
||||
assert_u_eq(heap_validate(&heap), 0,
|
||||
"Incorrect node count");
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
for (k = 0; k < j; k++) {
|
||||
heap_insert(&heap, &nodes[k]);
|
||||
if (i % 13 == 12) {
|
||||
/* Trigger merging. */
|
||||
assert_ptr_not_null(heap_first(&heap),
|
||||
"Heap should not be empty");
|
||||
}
|
||||
assert_u_eq(heap_validate(&heap), k + 1,
|
||||
"Incorrect node count");
|
||||
}
|
||||
|
||||
assert_false(heap_empty(&heap),
|
||||
"Heap should not be empty");
|
||||
|
||||
/* Remove nodes. */
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
for (k = 0; k < j; k++) {
|
||||
assert_u_eq(heap_validate(&heap), j - k,
|
||||
"Incorrect node count");
|
||||
node_remove(&heap, &nodes[k]);
|
||||
assert_u_eq(heap_validate(&heap), j - k
|
||||
- 1, "Incorrect node count");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (k = j; k > 0; k--) {
|
||||
node_remove(&heap, &nodes[k-1]);
|
||||
assert_u_eq(heap_validate(&heap), k - 1,
|
||||
"Incorrect node count");
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
node_t *prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
node_t *node = node_remove_first(&heap);
|
||||
assert_u_eq(heap_validate(&heap), j - k
|
||||
- 1, "Incorrect node count");
|
||||
if (prev != NULL) {
|
||||
assert_d_ge(node_cmp(node,
|
||||
prev), 0,
|
||||
"Bad removal order");
|
||||
}
|
||||
prev = node;
|
||||
}
|
||||
break;
|
||||
} case 3: {
|
||||
node_t *prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
node_t *node = heap_first(&heap);
|
||||
assert_u_eq(heap_validate(&heap), j - k,
|
||||
"Incorrect node count");
|
||||
if (prev != NULL) {
|
||||
assert_d_ge(node_cmp(node,
|
||||
prev), 0,
|
||||
"Bad removal order");
|
||||
}
|
||||
node_remove(&heap, node);
|
||||
assert_u_eq(heap_validate(&heap), j - k
|
||||
- 1, "Incorrect node count");
|
||||
prev = node;
|
||||
}
|
||||
break;
|
||||
} default:
|
||||
not_reached();
|
||||
}
|
||||
|
||||
assert_ptr_null(heap_first(&heap),
|
||||
"Heap should be empty");
|
||||
assert_true(heap_empty(&heap), "Heap should be empty");
|
||||
}
|
||||
}
|
||||
fini_gen_rand(sfmt);
|
||||
#undef NNODES
|
||||
#undef SEED
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ph_empty,
|
||||
test_ph_random));
|
||||
}
|
||||
263
memory/jemalloc/src/test/unit/prng.c
Normal file
263
memory/jemalloc/src/test/unit/prng.c
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static void
|
||||
test_prng_lg_range_u32(bool atomic)
|
||||
{
|
||||
uint32_t sa, sb, ra, rb;
|
||||
unsigned lg_range;
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u32(&sa, 32, atomic);
|
||||
sa = 42;
|
||||
rb = prng_lg_range_u32(&sa, 32, atomic);
|
||||
assert_u32_eq(ra, rb,
|
||||
"Repeated generation should produce repeated results");
|
||||
|
||||
sb = 42;
|
||||
rb = prng_lg_range_u32(&sb, 32, atomic);
|
||||
assert_u32_eq(ra, rb,
|
||||
"Equivalent generation should produce equivalent results");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u32(&sa, 32, atomic);
|
||||
rb = prng_lg_range_u32(&sa, 32, atomic);
|
||||
assert_u32_ne(ra, rb,
|
||||
"Full-width results must not immediately repeat");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u32(&sa, 32, atomic);
|
||||
for (lg_range = 31; lg_range > 0; lg_range--) {
|
||||
sb = 42;
|
||||
rb = prng_lg_range_u32(&sb, lg_range, atomic);
|
||||
assert_u32_eq((rb & (UINT32_C(0xffffffff) << lg_range)),
|
||||
0, "High order bits should be 0, lg_range=%u", lg_range);
|
||||
assert_u32_eq(rb, (ra >> (32 - lg_range)),
|
||||
"Expected high order bits of full-width result, "
|
||||
"lg_range=%u", lg_range);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_prng_lg_range_u64(void)
|
||||
{
|
||||
uint64_t sa, sb, ra, rb;
|
||||
unsigned lg_range;
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u64(&sa, 64);
|
||||
sa = 42;
|
||||
rb = prng_lg_range_u64(&sa, 64);
|
||||
assert_u64_eq(ra, rb,
|
||||
"Repeated generation should produce repeated results");
|
||||
|
||||
sb = 42;
|
||||
rb = prng_lg_range_u64(&sb, 64);
|
||||
assert_u64_eq(ra, rb,
|
||||
"Equivalent generation should produce equivalent results");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u64(&sa, 64);
|
||||
rb = prng_lg_range_u64(&sa, 64);
|
||||
assert_u64_ne(ra, rb,
|
||||
"Full-width results must not immediately repeat");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_u64(&sa, 64);
|
||||
for (lg_range = 63; lg_range > 0; lg_range--) {
|
||||
sb = 42;
|
||||
rb = prng_lg_range_u64(&sb, lg_range);
|
||||
assert_u64_eq((rb & (UINT64_C(0xffffffffffffffff) << lg_range)),
|
||||
0, "High order bits should be 0, lg_range=%u", lg_range);
|
||||
assert_u64_eq(rb, (ra >> (64 - lg_range)),
|
||||
"Expected high order bits of full-width result, "
|
||||
"lg_range=%u", lg_range);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_prng_lg_range_zu(bool atomic)
|
||||
{
|
||||
size_t sa, sb, ra, rb;
|
||||
unsigned lg_range;
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
sa = 42;
|
||||
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
assert_zu_eq(ra, rb,
|
||||
"Repeated generation should produce repeated results");
|
||||
|
||||
sb = 42;
|
||||
rb = prng_lg_range_zu(&sb, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
assert_zu_eq(ra, rb,
|
||||
"Equivalent generation should produce equivalent results");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
assert_zu_ne(ra, rb,
|
||||
"Full-width results must not immediately repeat");
|
||||
|
||||
sa = 42;
|
||||
ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
|
||||
for (lg_range = (ZU(1) << (3 + LG_SIZEOF_PTR)) - 1; lg_range > 0;
|
||||
lg_range--) {
|
||||
sb = 42;
|
||||
rb = prng_lg_range_zu(&sb, lg_range, atomic);
|
||||
assert_zu_eq((rb & (SIZE_T_MAX << lg_range)),
|
||||
0, "High order bits should be 0, lg_range=%u", lg_range);
|
||||
assert_zu_eq(rb, (ra >> ((ZU(1) << (3 + LG_SIZEOF_PTR)) -
|
||||
lg_range)), "Expected high order bits of full-width "
|
||||
"result, lg_range=%u", lg_range);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prng_lg_range_u32_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_lg_range_u32(false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_lg_range_u32_atomic)
|
||||
{
|
||||
|
||||
test_prng_lg_range_u32(true);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_lg_range_u64_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_lg_range_u64();
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_lg_range_zu_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_lg_range_zu(false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_lg_range_zu_atomic)
|
||||
{
|
||||
|
||||
test_prng_lg_range_zu(true);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
test_prng_range_u32(bool atomic)
|
||||
{
|
||||
uint32_t range;
|
||||
#define MAX_RANGE 10000000
|
||||
#define RANGE_STEP 97
|
||||
#define NREPS 10
|
||||
|
||||
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
|
||||
uint32_t s;
|
||||
unsigned rep;
|
||||
|
||||
s = range;
|
||||
for (rep = 0; rep < NREPS; rep++) {
|
||||
uint32_t r = prng_range_u32(&s, range, atomic);
|
||||
|
||||
assert_u32_lt(r, range, "Out of range");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_prng_range_u64(void)
|
||||
{
|
||||
uint64_t range;
|
||||
#define MAX_RANGE 10000000
|
||||
#define RANGE_STEP 97
|
||||
#define NREPS 10
|
||||
|
||||
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
|
||||
uint64_t s;
|
||||
unsigned rep;
|
||||
|
||||
s = range;
|
||||
for (rep = 0; rep < NREPS; rep++) {
|
||||
uint64_t r = prng_range_u64(&s, range);
|
||||
|
||||
assert_u64_lt(r, range, "Out of range");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_prng_range_zu(bool atomic)
|
||||
{
|
||||
size_t range;
|
||||
#define MAX_RANGE 10000000
|
||||
#define RANGE_STEP 97
|
||||
#define NREPS 10
|
||||
|
||||
for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
|
||||
size_t s;
|
||||
unsigned rep;
|
||||
|
||||
s = range;
|
||||
for (rep = 0; rep < NREPS; rep++) {
|
||||
size_t r = prng_range_zu(&s, range, atomic);
|
||||
|
||||
assert_zu_lt(r, range, "Out of range");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prng_range_u32_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_range_u32(false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_range_u32_atomic)
|
||||
{
|
||||
|
||||
test_prng_range_u32(true);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_range_u64_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_range_u64();
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_range_zu_nonatomic)
|
||||
{
|
||||
|
||||
test_prng_range_zu(false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_prng_range_zu_atomic)
|
||||
{
|
||||
|
||||
test_prng_range_zu(true);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_prng_lg_range_u32_nonatomic,
|
||||
test_prng_lg_range_u32_atomic,
|
||||
test_prng_lg_range_u64_nonatomic,
|
||||
test_prng_lg_range_zu_nonatomic,
|
||||
test_prng_lg_range_zu_atomic,
|
||||
test_prng_range_u32_nonatomic,
|
||||
test_prng_range_u32_atomic,
|
||||
test_prng_range_u64_nonatomic,
|
||||
test_prng_range_zu_nonatomic,
|
||||
test_prng_range_zu_atomic));
|
||||
}
|
||||
91
memory/jemalloc/src/test/unit/prof_accum.c
Normal file
91
memory/jemalloc/src/test/unit/prof_accum.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NALLOCS_PER_THREAD 50
|
||||
#define DUMP_INTERVAL 1
|
||||
#define BT_COUNT_CHECK_INTERVAL 5
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0";
|
||||
#endif
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static void *
|
||||
alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration)
|
||||
{
|
||||
|
||||
return (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration));
|
||||
}
|
||||
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
unsigned thd_ind = *(unsigned *)varg;
|
||||
size_t bt_count_prev, bt_count;
|
||||
unsigned i_prev, i;
|
||||
|
||||
i_prev = 0;
|
||||
bt_count_prev = 0;
|
||||
for (i = 0; i < NALLOCS_PER_THREAD; i++) {
|
||||
void *p = alloc_from_permuted_backtrace(thd_ind, i);
|
||||
dallocx(p, 0);
|
||||
if (i % DUMP_INTERVAL == 0) {
|
||||
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while dumping heap profile");
|
||||
}
|
||||
|
||||
if (i % BT_COUNT_CHECK_INTERVAL == 0 ||
|
||||
i+1 == NALLOCS_PER_THREAD) {
|
||||
bt_count = prof_bt_count();
|
||||
assert_zu_le(bt_count_prev+(i-i_prev), bt_count,
|
||||
"Expected larger backtrace count increase");
|
||||
i_prev = i;
|
||||
bt_count_prev = bt_count;
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_idump)
|
||||
{
|
||||
bool active;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned thd_args[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
thd_args[i] = i;
|
||||
thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_idump));
|
||||
}
|
||||
136
memory/jemalloc/src/test/unit/prof_active.c
Normal file
136
memory/jemalloc/src/test/unit/prof_active.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_thread_active_init:false,lg_prof_sample:0";
|
||||
#endif
|
||||
|
||||
static void
|
||||
mallctl_bool_get(const char *name, bool expected, const char *func, int line)
|
||||
{
|
||||
bool old;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(old);
|
||||
assert_d_eq(mallctl(name, &old, &sz, NULL, 0), 0,
|
||||
"%s():%d: Unexpected mallctl failure reading %s", func, line, name);
|
||||
assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line,
|
||||
name);
|
||||
}
|
||||
|
||||
static void
|
||||
mallctl_bool_set(const char *name, bool old_expected, bool val_new,
|
||||
const char *func, int line)
|
||||
{
|
||||
bool old;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(old);
|
||||
assert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0,
|
||||
"%s():%d: Unexpected mallctl failure reading/writing %s", func,
|
||||
line, name);
|
||||
assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func,
|
||||
line, name);
|
||||
}
|
||||
|
||||
static void
|
||||
mallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func,
|
||||
int line)
|
||||
{
|
||||
|
||||
mallctl_bool_get("prof.active", prof_active_old_expected, func, line);
|
||||
}
|
||||
#define mallctl_prof_active_get(a) \
|
||||
mallctl_prof_active_get_impl(a, __func__, __LINE__)
|
||||
|
||||
static void
|
||||
mallctl_prof_active_set_impl(bool prof_active_old_expected,
|
||||
bool prof_active_new, const char *func, int line)
|
||||
{
|
||||
|
||||
mallctl_bool_set("prof.active", prof_active_old_expected,
|
||||
prof_active_new, func, line);
|
||||
}
|
||||
#define mallctl_prof_active_set(a, b) \
|
||||
mallctl_prof_active_set_impl(a, b, __func__, __LINE__)
|
||||
|
||||
static void
|
||||
mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected,
|
||||
const char *func, int line)
|
||||
{
|
||||
|
||||
mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected,
|
||||
func, line);
|
||||
}
|
||||
#define mallctl_thread_prof_active_get(a) \
|
||||
mallctl_thread_prof_active_get_impl(a, __func__, __LINE__)
|
||||
|
||||
static void
|
||||
mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected,
|
||||
bool thread_prof_active_new, const char *func, int line)
|
||||
{
|
||||
|
||||
mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected,
|
||||
thread_prof_active_new, func, line);
|
||||
}
|
||||
#define mallctl_thread_prof_active_set(a, b) \
|
||||
mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__)
|
||||
|
||||
static void
|
||||
prof_sampling_probe_impl(bool expect_sample, const char *func, int line)
|
||||
{
|
||||
void *p;
|
||||
size_t expected_backtraces = expect_sample ? 1 : 0;
|
||||
|
||||
assert_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func,
|
||||
line);
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
assert_zu_eq(prof_bt_count(), expected_backtraces,
|
||||
"%s():%d: Unexpected backtrace count", func, line);
|
||||
dallocx(p, 0);
|
||||
}
|
||||
#define prof_sampling_probe(a) \
|
||||
prof_sampling_probe_impl(a, __func__, __LINE__)
|
||||
|
||||
TEST_BEGIN(test_prof_active)
|
||||
{
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
mallctl_prof_active_get(true);
|
||||
mallctl_thread_prof_active_get(false);
|
||||
|
||||
mallctl_prof_active_set(true, true);
|
||||
mallctl_thread_prof_active_set(false, false);
|
||||
/* prof.active, !thread.prof.active. */
|
||||
prof_sampling_probe(false);
|
||||
|
||||
mallctl_prof_active_set(true, false);
|
||||
mallctl_thread_prof_active_set(false, false);
|
||||
/* !prof.active, !thread.prof.active. */
|
||||
prof_sampling_probe(false);
|
||||
|
||||
mallctl_prof_active_set(false, false);
|
||||
mallctl_thread_prof_active_set(false, true);
|
||||
/* !prof.active, thread.prof.active. */
|
||||
prof_sampling_probe(false);
|
||||
|
||||
mallctl_prof_active_set(false, true);
|
||||
mallctl_thread_prof_active_set(true, true);
|
||||
/* prof.active, thread.prof.active. */
|
||||
prof_sampling_probe(true);
|
||||
|
||||
/* Restore settings. */
|
||||
mallctl_prof_active_set(true, true);
|
||||
mallctl_thread_prof_active_set(true, false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_prof_active));
|
||||
}
|
||||
81
memory/jemalloc/src/test/unit/prof_gdump.c
Normal file
81
memory/jemalloc/src/test/unit/prof_gdump.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf = "prof:true,prof_active:false,prof_gdump:true";
|
||||
#endif
|
||||
|
||||
static bool did_prof_dump_open;
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
did_prof_dump_open = true;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_gdump)
|
||||
{
|
||||
bool active, gdump, gdump_old;
|
||||
void *p, *q, *r, *s;
|
||||
size_t sz;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
did_prof_dump_open = false;
|
||||
p = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
|
||||
did_prof_dump_open = false;
|
||||
q = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(q, "Unexpected mallocx() failure");
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
|
||||
gdump = false;
|
||||
sz = sizeof(gdump_old);
|
||||
assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
|
||||
sizeof(gdump)), 0,
|
||||
"Unexpected mallctl failure while disabling prof.gdump");
|
||||
assert(gdump_old);
|
||||
did_prof_dump_open = false;
|
||||
r = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(q, "Unexpected mallocx() failure");
|
||||
assert_false(did_prof_dump_open, "Unexpected profile dump");
|
||||
|
||||
gdump = true;
|
||||
sz = sizeof(gdump_old);
|
||||
assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump,
|
||||
sizeof(gdump)), 0,
|
||||
"Unexpected mallctl failure while enabling prof.gdump");
|
||||
assert(!gdump_old);
|
||||
did_prof_dump_open = false;
|
||||
s = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(q, "Unexpected mallocx() failure");
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
|
||||
dallocx(p, 0);
|
||||
dallocx(q, 0);
|
||||
dallocx(r, 0);
|
||||
dallocx(s, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_gdump));
|
||||
}
|
||||
51
memory/jemalloc/src/test/unit/prof_idump.c
Normal file
51
memory/jemalloc/src/test/unit/prof_idump.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0,"
|
||||
"lg_prof_interval:0";
|
||||
#endif
|
||||
|
||||
static bool did_prof_dump_open;
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
did_prof_dump_open = true;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_idump)
|
||||
{
|
||||
bool active;
|
||||
void *p;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
active = true;
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure while activating profiling");
|
||||
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
did_prof_dump_open = false;
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
assert_true(did_prof_dump_open, "Expected a profile dump");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_idump));
|
||||
}
|
||||
303
memory/jemalloc/src/test/unit/prof_reset.c
Normal file
303
memory/jemalloc/src/test/unit/prof_reset.c
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf =
|
||||
"prof:true,prof_active:false,lg_prof_sample:0";
|
||||
#endif
|
||||
|
||||
static int
|
||||
prof_dump_open_intercept(bool propagate_err, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
assert_d_ne(fd, -1, "Unexpected open() failure");
|
||||
|
||||
return (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
set_prof_active(bool active)
|
||||
{
|
||||
|
||||
assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
||||
0, "Unexpected mallctl failure");
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_lg_prof_sample(void)
|
||||
{
|
||||
size_t lg_prof_sample;
|
||||
size_t sz = sizeof(size_t);
|
||||
|
||||
assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure while reading profiling sample rate");
|
||||
return (lg_prof_sample);
|
||||
}
|
||||
|
||||
static void
|
||||
do_prof_reset(size_t lg_prof_sample)
|
||||
{
|
||||
assert_d_eq(mallctl("prof.reset", NULL, NULL,
|
||||
&lg_prof_sample, sizeof(size_t)), 0,
|
||||
"Unexpected mallctl failure while resetting profile data");
|
||||
assert_zu_eq(lg_prof_sample, get_lg_prof_sample(),
|
||||
"Expected profile sample rate change");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prof_reset_basic)
|
||||
{
|
||||
size_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next;
|
||||
size_t sz;
|
||||
unsigned i;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("opt.lg_prof_sample", &lg_prof_sample_orig, &sz,
|
||||
NULL, 0), 0,
|
||||
"Unexpected mallctl failure while reading profiling sample rate");
|
||||
assert_zu_eq(lg_prof_sample_orig, 0,
|
||||
"Unexpected profiling sample rate");
|
||||
lg_prof_sample = get_lg_prof_sample();
|
||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
||||
"\"prof.lg_sample\"");
|
||||
|
||||
/* Test simple resets. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl failure while resetting profile data");
|
||||
lg_prof_sample = get_lg_prof_sample();
|
||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||
"Unexpected profile sample rate change");
|
||||
}
|
||||
|
||||
/* Test resets with prof.lg_sample changes. */
|
||||
lg_prof_sample_next = 1;
|
||||
for (i = 0; i < 2; i++) {
|
||||
do_prof_reset(lg_prof_sample_next);
|
||||
lg_prof_sample = get_lg_prof_sample();
|
||||
assert_zu_eq(lg_prof_sample, lg_prof_sample_next,
|
||||
"Expected profile sample rate change");
|
||||
lg_prof_sample_next = lg_prof_sample_orig;
|
||||
}
|
||||
|
||||
/* Make sure the test code restored prof.lg_sample. */
|
||||
lg_prof_sample = get_lg_prof_sample();
|
||||
assert_zu_eq(lg_prof_sample_orig, lg_prof_sample,
|
||||
"Unexpected disagreement between \"opt.lg_prof_sample\" and "
|
||||
"\"prof.lg_sample\"");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
bool prof_dump_header_intercepted = false;
|
||||
prof_cnt_t cnt_all_copy = {0, 0, 0, 0};
|
||||
static bool
|
||||
prof_dump_header_intercept(tsdn_t *tsdn, bool propagate_err,
|
||||
const prof_cnt_t *cnt_all)
|
||||
{
|
||||
|
||||
prof_dump_header_intercepted = true;
|
||||
memcpy(&cnt_all_copy, cnt_all, sizeof(prof_cnt_t));
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prof_reset_cleanup)
|
||||
{
|
||||
void *p;
|
||||
prof_dump_header_t *prof_dump_header_orig;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
set_prof_active(true);
|
||||
|
||||
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
|
||||
p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace");
|
||||
|
||||
prof_dump_header_orig = prof_dump_header;
|
||||
prof_dump_header = prof_dump_header_intercept;
|
||||
assert_false(prof_dump_header_intercepted, "Unexpected intercept");
|
||||
|
||||
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while dumping heap profile");
|
||||
assert_true(prof_dump_header_intercepted, "Expected intercept");
|
||||
assert_u64_eq(cnt_all_copy.curobjs, 1, "Expected 1 allocation");
|
||||
|
||||
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected error while resetting heap profile data");
|
||||
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while dumping heap profile");
|
||||
assert_u64_eq(cnt_all_copy.curobjs, 0, "Expected 0 allocations");
|
||||
assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace");
|
||||
|
||||
prof_dump_header = prof_dump_header_orig;
|
||||
|
||||
dallocx(p, 0);
|
||||
assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces");
|
||||
|
||||
set_prof_active(false);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NALLOCS_PER_THREAD (1U << 13)
|
||||
#define OBJ_RING_BUF_COUNT 1531
|
||||
#define RESET_INTERVAL (1U << 10)
|
||||
#define DUMP_INTERVAL 3677
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
unsigned thd_ind = *(unsigned *)varg;
|
||||
unsigned i;
|
||||
void *objs[OBJ_RING_BUF_COUNT];
|
||||
|
||||
memset(objs, 0, sizeof(objs));
|
||||
|
||||
for (i = 0; i < NALLOCS_PER_THREAD; i++) {
|
||||
if (i % RESET_INTERVAL == 0) {
|
||||
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while resetting heap profile "
|
||||
"data");
|
||||
}
|
||||
|
||||
if (i % DUMP_INTERVAL == 0) {
|
||||
assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0),
|
||||
0, "Unexpected error while dumping heap profile");
|
||||
}
|
||||
|
||||
{
|
||||
void **pp = &objs[i % OBJ_RING_BUF_COUNT];
|
||||
if (*pp != NULL) {
|
||||
dallocx(*pp, 0);
|
||||
*pp = NULL;
|
||||
}
|
||||
*pp = btalloc(1, thd_ind*NALLOCS_PER_THREAD + i);
|
||||
assert_ptr_not_null(*pp,
|
||||
"Unexpected btalloc() failure");
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up any remaining objects. */
|
||||
for (i = 0; i < OBJ_RING_BUF_COUNT; i++) {
|
||||
void **pp = &objs[i % OBJ_RING_BUF_COUNT];
|
||||
if (*pp != NULL) {
|
||||
dallocx(*pp, 0);
|
||||
*pp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prof_reset)
|
||||
{
|
||||
size_t lg_prof_sample_orig;
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned thd_args[NTHREADS];
|
||||
unsigned i;
|
||||
size_t bt_count, tdata_count;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
bt_count = prof_bt_count();
|
||||
assert_zu_eq(bt_count, 0,
|
||||
"Unexpected pre-existing tdata structures");
|
||||
tdata_count = prof_tdata_count();
|
||||
|
||||
lg_prof_sample_orig = get_lg_prof_sample();
|
||||
do_prof_reset(5);
|
||||
|
||||
set_prof_active(true);
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
thd_args[i] = i;
|
||||
thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
|
||||
assert_zu_eq(prof_bt_count(), bt_count,
|
||||
"Unexpected bactrace count change");
|
||||
assert_zu_eq(prof_tdata_count(), tdata_count,
|
||||
"Unexpected remaining tdata structures");
|
||||
|
||||
set_prof_active(false);
|
||||
|
||||
do_prof_reset(lg_prof_sample_orig);
|
||||
}
|
||||
TEST_END
|
||||
#undef NTHREADS
|
||||
#undef NALLOCS_PER_THREAD
|
||||
#undef OBJ_RING_BUF_COUNT
|
||||
#undef RESET_INTERVAL
|
||||
#undef DUMP_INTERVAL
|
||||
|
||||
/* Test sampling at the same allocation site across resets. */
|
||||
#define NITER 10
|
||||
TEST_BEGIN(test_xallocx)
|
||||
{
|
||||
size_t lg_prof_sample_orig;
|
||||
unsigned i;
|
||||
void *ptrs[NITER];
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
lg_prof_sample_orig = get_lg_prof_sample();
|
||||
set_prof_active(true);
|
||||
|
||||
/* Reset profiling. */
|
||||
do_prof_reset(0);
|
||||
|
||||
for (i = 0; i < NITER; i++) {
|
||||
void *p;
|
||||
size_t sz, nsz;
|
||||
|
||||
/* Reset profiling. */
|
||||
do_prof_reset(0);
|
||||
|
||||
/* Allocate small object (which will be promoted). */
|
||||
p = ptrs[i] = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
/* Reset profiling. */
|
||||
do_prof_reset(0);
|
||||
|
||||
/* Perform successful xallocx(). */
|
||||
sz = sallocx(p, 0);
|
||||
assert_zu_eq(xallocx(p, sz, 0, 0), sz,
|
||||
"Unexpected xallocx() failure");
|
||||
|
||||
/* Perform unsuccessful xallocx(). */
|
||||
nsz = nallocx(sz+1, 0);
|
||||
assert_zu_eq(xallocx(p, nsz, 0, 0), sz,
|
||||
"Unexpected xallocx() success");
|
||||
}
|
||||
|
||||
for (i = 0; i < NITER; i++) {
|
||||
/* dallocx. */
|
||||
dallocx(ptrs[i], 0);
|
||||
}
|
||||
|
||||
set_prof_active(false);
|
||||
do_prof_reset(lg_prof_sample_orig);
|
||||
}
|
||||
TEST_END
|
||||
#undef NITER
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
/* Intercept dumping prior to running any tests. */
|
||||
prof_dump_open = prof_dump_open_intercept;
|
||||
|
||||
return (test(
|
||||
test_prof_reset_basic,
|
||||
test_prof_reset_cleanup,
|
||||
test_prof_reset,
|
||||
test_xallocx));
|
||||
}
|
||||
129
memory/jemalloc/src/test/unit/prof_thread_name.c
Normal file
129
memory/jemalloc/src/test/unit/prof_thread_name.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_PROF
|
||||
const char *malloc_conf = "prof:true,prof_active:false";
|
||||
#endif
|
||||
|
||||
static void
|
||||
mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func,
|
||||
int line)
|
||||
{
|
||||
const char *thread_name_old;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(thread_name_old);
|
||||
assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, NULL, 0),
|
||||
0, "%s():%d: Unexpected mallctl failure reading thread.prof.name",
|
||||
func, line);
|
||||
assert_str_eq(thread_name_old, thread_name_expected,
|
||||
"%s():%d: Unexpected thread.prof.name value", func, line);
|
||||
}
|
||||
#define mallctl_thread_name_get(a) \
|
||||
mallctl_thread_name_get_impl(a, __func__, __LINE__)
|
||||
|
||||
static void
|
||||
mallctl_thread_name_set_impl(const char *thread_name, const char *func,
|
||||
int line)
|
||||
{
|
||||
|
||||
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
|
||||
sizeof(thread_name)), 0,
|
||||
"%s():%d: Unexpected mallctl failure reading thread.prof.name",
|
||||
func, line);
|
||||
mallctl_thread_name_get_impl(thread_name, func, line);
|
||||
}
|
||||
#define mallctl_thread_name_set(a) \
|
||||
mallctl_thread_name_set_impl(a, __func__, __LINE__)
|
||||
|
||||
TEST_BEGIN(test_prof_thread_name_validation)
|
||||
{
|
||||
const char *thread_name;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
mallctl_thread_name_get("");
|
||||
mallctl_thread_name_set("hi there");
|
||||
|
||||
/* NULL input shouldn't be allowed. */
|
||||
thread_name = NULL;
|
||||
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
|
||||
sizeof(thread_name)), EFAULT,
|
||||
"Unexpected mallctl result writing \"%s\" to thread.prof.name",
|
||||
thread_name);
|
||||
|
||||
/* '\n' shouldn't be allowed. */
|
||||
thread_name = "hi\nthere";
|
||||
assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name,
|
||||
sizeof(thread_name)), EFAULT,
|
||||
"Unexpected mallctl result writing \"%s\" to thread.prof.name",
|
||||
thread_name);
|
||||
|
||||
/* Simultaneous read/write shouldn't be allowed. */
|
||||
{
|
||||
const char *thread_name_old;
|
||||
size_t sz;
|
||||
|
||||
sz = sizeof(thread_name_old);
|
||||
assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz,
|
||||
&thread_name, sizeof(thread_name)), EPERM,
|
||||
"Unexpected mallctl result writing \"%s\" to "
|
||||
"thread.prof.name", thread_name);
|
||||
}
|
||||
|
||||
mallctl_thread_name_set("");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
#define NTHREADS 4
|
||||
#define NRESET 25
|
||||
static void *
|
||||
thd_start(void *varg)
|
||||
{
|
||||
unsigned thd_ind = *(unsigned *)varg;
|
||||
char thread_name[16] = "";
|
||||
unsigned i;
|
||||
|
||||
malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind);
|
||||
|
||||
mallctl_thread_name_get("");
|
||||
mallctl_thread_name_set(thread_name);
|
||||
|
||||
for (i = 0; i < NRESET; i++) {
|
||||
assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected error while resetting heap profile data");
|
||||
mallctl_thread_name_get(thread_name);
|
||||
}
|
||||
|
||||
mallctl_thread_name_set(thread_name);
|
||||
mallctl_thread_name_set("");
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_prof_thread_name_threaded)
|
||||
{
|
||||
thd_t thds[NTHREADS];
|
||||
unsigned thd_args[NTHREADS];
|
||||
unsigned i;
|
||||
|
||||
test_skip_if(!config_prof);
|
||||
|
||||
for (i = 0; i < NTHREADS; i++) {
|
||||
thd_args[i] = i;
|
||||
thd_create(&thds[i], thd_start, (void *)&thd_args[i]);
|
||||
}
|
||||
for (i = 0; i < NTHREADS; i++)
|
||||
thd_join(thds[i], NULL);
|
||||
}
|
||||
TEST_END
|
||||
#undef NTHREADS
|
||||
#undef NRESET
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_prof_thread_name_validation,
|
||||
test_prof_thread_name_threaded));
|
||||
}
|
||||
209
memory/jemalloc/src/test/unit/ql.c
Normal file
209
memory/jemalloc/src/test/unit/ql.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
/* Number of ring entries, in [2..26]. */
|
||||
#define NENTRIES 9
|
||||
|
||||
typedef struct list_s list_t;
|
||||
typedef ql_head(list_t) list_head_t;
|
||||
|
||||
struct list_s {
|
||||
ql_elm(list_t) link;
|
||||
char id;
|
||||
};
|
||||
|
||||
static void
|
||||
test_empty_list(list_head_t *head)
|
||||
{
|
||||
list_t *t;
|
||||
unsigned i;
|
||||
|
||||
assert_ptr_null(ql_first(head), "Unexpected element for empty list");
|
||||
assert_ptr_null(ql_last(head, link),
|
||||
"Unexpected element for empty list");
|
||||
|
||||
i = 0;
|
||||
ql_foreach(t, head, link) {
|
||||
i++;
|
||||
}
|
||||
assert_u_eq(i, 0, "Unexpected element for empty list");
|
||||
|
||||
i = 0;
|
||||
ql_reverse_foreach(t, head, link) {
|
||||
i++;
|
||||
}
|
||||
assert_u_eq(i, 0, "Unexpected element for empty list");
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ql_empty)
|
||||
{
|
||||
list_head_t head;
|
||||
|
||||
ql_new(&head);
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
init_entries(list_t *entries, unsigned nentries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nentries; i++) {
|
||||
entries[i].id = 'a' + i;
|
||||
ql_elm_new(&entries[i], link);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_entries_list(list_head_t *head, list_t *entries, unsigned nentries)
|
||||
{
|
||||
list_t *t;
|
||||
unsigned i;
|
||||
|
||||
assert_c_eq(ql_first(head)->id, entries[0].id, "Element id mismatch");
|
||||
assert_c_eq(ql_last(head, link)->id, entries[nentries-1].id,
|
||||
"Element id mismatch");
|
||||
|
||||
i = 0;
|
||||
ql_foreach(t, head, link) {
|
||||
assert_c_eq(t->id, entries[i].id, "Element id mismatch");
|
||||
i++;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
ql_reverse_foreach(t, head, link) {
|
||||
assert_c_eq(t->id, entries[nentries-i-1].id,
|
||||
"Element id mismatch");
|
||||
i++;
|
||||
}
|
||||
|
||||
for (i = 0; i < nentries-1; i++) {
|
||||
t = ql_next(head, &entries[i], link);
|
||||
assert_c_eq(t->id, entries[i+1].id, "Element id mismatch");
|
||||
}
|
||||
assert_ptr_null(ql_next(head, &entries[nentries-1], link),
|
||||
"Unexpected element");
|
||||
|
||||
assert_ptr_null(ql_prev(head, &entries[0], link), "Unexpected element");
|
||||
for (i = 1; i < nentries; i++) {
|
||||
t = ql_prev(head, &entries[i], link);
|
||||
assert_c_eq(t->id, entries[i-1].id, "Element id mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_ql_tail_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_tail_insert(&head, &entries[i], link);
|
||||
|
||||
test_entries_list(&head, entries, NENTRIES);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_tail_remove)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_tail_insert(&head, &entries[i], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
test_entries_list(&head, entries, NENTRIES-i);
|
||||
ql_tail_remove(&head, list_t, link);
|
||||
}
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_head_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
|
||||
|
||||
test_entries_list(&head, entries, NENTRIES);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_head_remove)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
for (i = 0; i < NENTRIES; i++)
|
||||
ql_head_insert(&head, &entries[NENTRIES-i-1], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
test_entries_list(&head, &entries[i], NENTRIES-i);
|
||||
ql_head_remove(&head, list_t, link);
|
||||
}
|
||||
test_empty_list(&head);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ql_insert)
|
||||
{
|
||||
list_head_t head;
|
||||
list_t entries[8];
|
||||
list_t *a, *b, *c, *d, *e, *f, *g, *h;
|
||||
|
||||
ql_new(&head);
|
||||
init_entries(entries, sizeof(entries)/sizeof(list_t));
|
||||
a = &entries[0];
|
||||
b = &entries[1];
|
||||
c = &entries[2];
|
||||
d = &entries[3];
|
||||
e = &entries[4];
|
||||
f = &entries[5];
|
||||
g = &entries[6];
|
||||
h = &entries[7];
|
||||
|
||||
/*
|
||||
* ql_remove(), ql_before_insert(), and ql_after_insert() are used
|
||||
* internally by other macros that are already tested, so there's no
|
||||
* need to test them completely. However, insertion/deletion from the
|
||||
* middle of lists is not otherwise tested; do so here.
|
||||
*/
|
||||
ql_tail_insert(&head, f, link);
|
||||
ql_before_insert(&head, f, b, link);
|
||||
ql_before_insert(&head, f, c, link);
|
||||
ql_after_insert(f, h, link);
|
||||
ql_after_insert(f, g, link);
|
||||
ql_before_insert(&head, b, a, link);
|
||||
ql_after_insert(c, d, link);
|
||||
ql_before_insert(&head, f, e, link);
|
||||
|
||||
test_entries_list(&head, entries, sizeof(entries)/sizeof(list_t));
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ql_empty,
|
||||
test_ql_tail_insert,
|
||||
test_ql_tail_remove,
|
||||
test_ql_head_insert,
|
||||
test_ql_head_remove,
|
||||
test_ql_insert));
|
||||
}
|
||||
248
memory/jemalloc/src/test/unit/qr.c
Normal file
248
memory/jemalloc/src/test/unit/qr.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
/* Number of ring entries, in [2..26]. */
|
||||
#define NENTRIES 9
|
||||
/* Split index, in [1..NENTRIES). */
|
||||
#define SPLIT_INDEX 5
|
||||
|
||||
typedef struct ring_s ring_t;
|
||||
|
||||
struct ring_s {
|
||||
qr(ring_t) link;
|
||||
char id;
|
||||
};
|
||||
|
||||
static void
|
||||
init_entries(ring_t *entries)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
qr_new(&entries[i], link);
|
||||
entries[i].id = 'a' + i;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_independent_entries(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
j++;
|
||||
}
|
||||
assert_u_eq(j, 1,
|
||||
"Iteration over single-element ring should visit precisely "
|
||||
"one element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
j++;
|
||||
}
|
||||
assert_u_eq(j, 1,
|
||||
"Iteration over single-element ring should visit precisely "
|
||||
"one element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_ptr_eq(t, &entries[i],
|
||||
"Next element in single-element ring should be same as "
|
||||
"current element");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_ptr_eq(t, &entries[i],
|
||||
"Previous element in single-element ring should be same as "
|
||||
"current element");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_one)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
|
||||
init_entries(entries);
|
||||
test_independent_entries(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
test_entries_ring(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(i+j) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-j-1) %
|
||||
NENTRIES].id, "Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(i+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_after_insert)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
test_entries_ring(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_qr_remove)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[i+j].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[NENTRIES - 1 - j].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
qr_remove(&entries[i], link);
|
||||
}
|
||||
test_independent_entries(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_qr_before_insert)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_before_insert(&entries[i - 1], &entries[i], link);
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-j) %
|
||||
NENTRIES].id, "Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_reverse_foreach(t, &entries[i], link) {
|
||||
assert_c_eq(t->id, entries[(i+j+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
j++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_next(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
t = qr_prev(&entries[i], link);
|
||||
assert_c_eq(t->id, entries[(i+1) % NENTRIES].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static void
|
||||
test_split_entries(ring_t *entries)
|
||||
{
|
||||
ring_t *t;
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < NENTRIES; i++) {
|
||||
j = 0;
|
||||
qr_foreach(t, &entries[i], link) {
|
||||
if (i < SPLIT_INDEX) {
|
||||
assert_c_eq(t->id,
|
||||
entries[(i+j) % SPLIT_INDEX].id,
|
||||
"Element id mismatch");
|
||||
} else {
|
||||
assert_c_eq(t->id, entries[(i+j-SPLIT_INDEX) %
|
||||
(NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id,
|
||||
"Element id mismatch");
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_qr_meld_split)
|
||||
{
|
||||
ring_t entries[NENTRIES];
|
||||
unsigned i;
|
||||
|
||||
init_entries(entries);
|
||||
for (i = 1; i < NENTRIES; i++)
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_qr_one,
|
||||
test_qr_after_insert,
|
||||
test_qr_remove,
|
||||
test_qr_before_insert,
|
||||
test_qr_meld_split));
|
||||
}
|
||||
108
memory/jemalloc/src/test/unit/quarantine.c
Normal file
108
memory/jemalloc/src/test/unit/quarantine.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define QUARANTINE_SIZE 8192
|
||||
#define STRINGIFY_HELPER(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_HELPER(x)
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:"
|
||||
STRINGIFY(QUARANTINE_SIZE);
|
||||
#endif
|
||||
|
||||
void
|
||||
quarantine_clear(void)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = mallocx(QUARANTINE_SIZE*2, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_quarantine)
|
||||
{
|
||||
#define SZ ZU(256)
|
||||
#define NQUARANTINED (QUARANTINE_SIZE/SZ)
|
||||
void *quarantined[NQUARANTINED+1];
|
||||
size_t i, j;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
|
||||
assert_zu_eq(nallocx(SZ, 0), SZ,
|
||||
"SZ=%zu does not precisely equal a size class", SZ);
|
||||
|
||||
quarantine_clear();
|
||||
|
||||
/*
|
||||
* Allocate enough regions to completely fill the quarantine, plus one
|
||||
* more. The last iteration occurs with a completely full quarantine,
|
||||
* but no regions should be drained from the quarantine until the last
|
||||
* deallocation occurs. Therefore no region recycling should occur
|
||||
* until after this loop completes.
|
||||
*/
|
||||
for (i = 0; i < NQUARANTINED+1; i++) {
|
||||
void *p = mallocx(SZ, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
quarantined[i] = p;
|
||||
dallocx(p, 0);
|
||||
for (j = 0; j < i; j++) {
|
||||
assert_ptr_ne(p, quarantined[j],
|
||||
"Quarantined region recycled too early; "
|
||||
"i=%zu, j=%zu", i, j);
|
||||
}
|
||||
}
|
||||
#undef NQUARANTINED
|
||||
#undef SZ
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static bool detected_redzone_corruption;
|
||||
|
||||
static void
|
||||
arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after,
|
||||
size_t offset, uint8_t byte)
|
||||
{
|
||||
|
||||
detected_redzone_corruption = true;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_quarantine_redzone)
|
||||
{
|
||||
char *s;
|
||||
arena_redzone_corruption_t *arena_redzone_corruption_orig;
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
|
||||
arena_redzone_corruption_orig = arena_redzone_corruption;
|
||||
arena_redzone_corruption = arena_redzone_corruption_replacement;
|
||||
|
||||
/* Test underflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[-1] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
/* Test overflow. */
|
||||
detected_redzone_corruption = false;
|
||||
s = (char *)mallocx(1, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
s[sallocx(s, 0)] = 0xbb;
|
||||
dallocx(s, 0);
|
||||
assert_true(detected_redzone_corruption,
|
||||
"Did not detect redzone corruption");
|
||||
|
||||
arena_redzone_corruption = arena_redzone_corruption_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_quarantine,
|
||||
test_quarantine_redzone));
|
||||
}
|
||||
354
memory/jemalloc/src/test/unit/rb.c
Normal file
354
memory/jemalloc/src/test/unit/rb.c
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define rbtn_black_height(a_type, a_field, a_rbt, r_height) do { \
|
||||
a_type *rbp_bh_t; \
|
||||
for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; \
|
||||
rbp_bh_t != NULL; \
|
||||
rbp_bh_t = rbtn_left_get(a_type, a_field, rbp_bh_t)) { \
|
||||
if (!rbtn_red_get(a_type, a_field, rbp_bh_t)) { \
|
||||
(r_height)++; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct node_s node_t;
|
||||
|
||||
struct node_s {
|
||||
#define NODE_MAGIC 0x9823af7e
|
||||
uint32_t magic;
|
||||
rb_node(node_t) link;
|
||||
uint64_t key;
|
||||
};
|
||||
|
||||
static int
|
||||
node_cmp(const node_t *a, const node_t *b) {
|
||||
int ret;
|
||||
|
||||
assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic");
|
||||
assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
ret = (a->key > b->key) - (a->key < b->key);
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Duplicates are not allowed in the tree, so force an
|
||||
* arbitrary ordering for non-identical items with equal keys.
|
||||
*/
|
||||
ret = (((uintptr_t)a) > ((uintptr_t)b))
|
||||
- (((uintptr_t)a) < ((uintptr_t)b));
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
typedef rb_tree(node_t) tree_t;
|
||||
rb_gen(static, tree_, tree_t, node_t, link, node_cmp);
|
||||
|
||||
TEST_BEGIN(test_rb_empty)
|
||||
{
|
||||
tree_t tree;
|
||||
node_t key;
|
||||
|
||||
tree_new(&tree);
|
||||
|
||||
assert_true(tree_empty(&tree), "Tree should be empty");
|
||||
assert_ptr_null(tree_first(&tree), "Unexpected node");
|
||||
assert_ptr_null(tree_last(&tree), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_search(&tree, &key), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_nsearch(&tree, &key), "Unexpected node");
|
||||
|
||||
key.key = 0;
|
||||
key.magic = NODE_MAGIC;
|
||||
assert_ptr_null(tree_psearch(&tree, &key), "Unexpected node");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
static unsigned
|
||||
tree_recurse(node_t *node, unsigned black_height, unsigned black_depth)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
node_t *left_node;
|
||||
node_t *right_node;
|
||||
|
||||
if (node == NULL)
|
||||
return (ret);
|
||||
|
||||
left_node = rbtn_left_get(node_t, link, node);
|
||||
right_node = rbtn_right_get(node_t, link, node);
|
||||
|
||||
if (!rbtn_red_get(node_t, link, node))
|
||||
black_depth++;
|
||||
|
||||
/* Red nodes must be interleaved with black nodes. */
|
||||
if (rbtn_red_get(node_t, link, node)) {
|
||||
if (left_node != NULL)
|
||||
assert_false(rbtn_red_get(node_t, link, left_node),
|
||||
"Node should be black");
|
||||
if (right_node != NULL)
|
||||
assert_false(rbtn_red_get(node_t, link, right_node),
|
||||
"Node should be black");
|
||||
}
|
||||
|
||||
/* Self. */
|
||||
assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
/* Left subtree. */
|
||||
if (left_node != NULL)
|
||||
ret += tree_recurse(left_node, black_height, black_depth);
|
||||
else
|
||||
ret += (black_depth != black_height);
|
||||
|
||||
/* Right subtree. */
|
||||
if (right_node != NULL)
|
||||
ret += tree_recurse(right_node, black_height, black_depth);
|
||||
else
|
||||
ret += (black_depth != black_height);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static node_t *
|
||||
tree_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *i = (unsigned *)data;
|
||||
node_t *search_node;
|
||||
|
||||
assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic");
|
||||
|
||||
/* Test rb_search(). */
|
||||
search_node = tree_search(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_search() returned unexpected node");
|
||||
|
||||
/* Test rb_nsearch(). */
|
||||
search_node = tree_nsearch(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_nsearch() returned unexpected node");
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
search_node = tree_psearch(tree, node);
|
||||
assert_ptr_eq(search_node, node,
|
||||
"tree_psearch() returned unexpected node");
|
||||
|
||||
(*i)++;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_iterate(tree_t *tree)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
tree_iter(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
tree_iterate_reverse(tree_t *tree)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
tree_reverse_iter(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
|
||||
return (i);
|
||||
}
|
||||
|
||||
static void
|
||||
node_remove(tree_t *tree, node_t *node, unsigned nnodes)
|
||||
{
|
||||
node_t *search_node;
|
||||
unsigned black_height, imbalances;
|
||||
|
||||
tree_remove(tree, node);
|
||||
|
||||
/* Test rb_nsearch(). */
|
||||
search_node = tree_nsearch(tree, node);
|
||||
if (search_node != NULL) {
|
||||
assert_u64_ge(search_node->key, node->key,
|
||||
"Key ordering error");
|
||||
}
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
search_node = tree_psearch(tree, node);
|
||||
if (search_node != NULL) {
|
||||
assert_u64_le(search_node->key, node->key,
|
||||
"Key ordering error");
|
||||
}
|
||||
|
||||
node->magic = 0;
|
||||
|
||||
rbtn_black_height(node_t, link, tree, black_height);
|
||||
imbalances = tree_recurse(tree->rbt_root, black_height, 0);
|
||||
assert_u_eq(imbalances, 0, "Tree is unbalanced");
|
||||
assert_u_eq(tree_iterate(tree), nnodes-1,
|
||||
"Unexpected node iteration count");
|
||||
assert_u_eq(tree_iterate_reverse(tree), nnodes-1,
|
||||
"Unexpected node iteration count");
|
||||
}
|
||||
|
||||
static node_t *
|
||||
remove_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
node_t *ret = tree_next(tree, node);
|
||||
|
||||
node_remove(tree, node, *nnodes);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static node_t *
|
||||
remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
node_t *ret = tree_prev(tree, node);
|
||||
|
||||
node_remove(tree, node, *nnodes);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_cb(node_t *node, void *data)
|
||||
{
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
|
||||
assert_u_gt(*nnodes, 0, "Destruction removed too many nodes");
|
||||
(*nnodes)--;
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_rb_random)
|
||||
{
|
||||
#define NNODES 25
|
||||
#define NBAGS 250
|
||||
#define SEED 42
|
||||
sfmt_t *sfmt;
|
||||
uint64_t bag[NNODES];
|
||||
tree_t tree;
|
||||
node_t nodes[NNODES];
|
||||
unsigned i, j, k, black_height, imbalances;
|
||||
|
||||
sfmt = init_gen_rand(SEED);
|
||||
for (i = 0; i < NBAGS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
/* Insert in order. */
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = j;
|
||||
break;
|
||||
case 1:
|
||||
/* Insert in reverse order. */
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = NNODES - j - 1;
|
||||
break;
|
||||
default:
|
||||
for (j = 0; j < NNODES; j++)
|
||||
bag[j] = gen_rand64_range(sfmt, NNODES);
|
||||
}
|
||||
|
||||
for (j = 1; j <= NNODES; j++) {
|
||||
/* Initialize tree and nodes. */
|
||||
tree_new(&tree);
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
for (k = 0; k < j; k++) {
|
||||
tree_insert(&tree, &nodes[k]);
|
||||
|
||||
rbtn_black_height(node_t, link, &tree,
|
||||
black_height);
|
||||
imbalances = tree_recurse(tree.rbt_root,
|
||||
black_height, 0);
|
||||
assert_u_eq(imbalances, 0,
|
||||
"Tree is unbalanced");
|
||||
|
||||
assert_u_eq(tree_iterate(&tree), k+1,
|
||||
"Unexpected node iteration count");
|
||||
assert_u_eq(tree_iterate_reverse(&tree), k+1,
|
||||
"Unexpected node iteration count");
|
||||
|
||||
assert_false(tree_empty(&tree),
|
||||
"Tree should not be empty");
|
||||
assert_ptr_not_null(tree_first(&tree),
|
||||
"Tree should not be empty");
|
||||
assert_ptr_not_null(tree_last(&tree),
|
||||
"Tree should not be empty");
|
||||
|
||||
tree_next(&tree, &nodes[k]);
|
||||
tree_prev(&tree, &nodes[k]);
|
||||
}
|
||||
|
||||
/* Remove nodes. */
|
||||
switch (i % 5) {
|
||||
case 0:
|
||||
for (k = 0; k < j; k++)
|
||||
node_remove(&tree, &nodes[k], j - k);
|
||||
break;
|
||||
case 1:
|
||||
for (k = j; k > 0; k--)
|
||||
node_remove(&tree, &nodes[k-1], k);
|
||||
break;
|
||||
case 2: {
|
||||
node_t *start;
|
||||
unsigned nnodes = j;
|
||||
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree_iter(&tree, start,
|
||||
remove_iterate_cb, (void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert_u_eq(nnodes, 0,
|
||||
"Removal terminated early");
|
||||
break;
|
||||
} case 3: {
|
||||
node_t *start;
|
||||
unsigned nnodes = j;
|
||||
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree_reverse_iter(&tree, start,
|
||||
remove_reverse_iterate_cb,
|
||||
(void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert_u_eq(nnodes, 0,
|
||||
"Removal terminated early");
|
||||
break;
|
||||
} case 4: {
|
||||
unsigned nnodes = j;
|
||||
tree_destroy(&tree, destroy_cb, &nnodes);
|
||||
assert_u_eq(nnodes, 0,
|
||||
"Destruction terminated early");
|
||||
break;
|
||||
} default:
|
||||
not_reached();
|
||||
}
|
||||
}
|
||||
}
|
||||
fini_gen_rand(sfmt);
|
||||
#undef NNODES
|
||||
#undef NBAGS
|
||||
#undef SEED
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_rb_empty,
|
||||
test_rb_random));
|
||||
}
|
||||
151
memory/jemalloc/src/test/unit/rtree.c
Normal file
151
memory/jemalloc/src/test/unit/rtree.c
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static rtree_node_elm_t *
|
||||
node_alloc(size_t nelms)
|
||||
{
|
||||
|
||||
return ((rtree_node_elm_t *)calloc(nelms, sizeof(rtree_node_elm_t)));
|
||||
}
|
||||
|
||||
static void
|
||||
node_dalloc(rtree_node_elm_t *node)
|
||||
{
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_rtree_get_empty)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
|
||||
rtree_t rtree;
|
||||
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
|
||||
"Unexpected rtree_new() failure");
|
||||
assert_ptr_null(rtree_get(&rtree, 0, false),
|
||||
"rtree_get() should return NULL for empty tree");
|
||||
rtree_delete(&rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_extrema)
|
||||
{
|
||||
unsigned i;
|
||||
extent_node_t node_a, node_b;
|
||||
|
||||
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
|
||||
rtree_t rtree;
|
||||
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
|
||||
"Unexpected rtree_new() failure");
|
||||
|
||||
assert_false(rtree_set(&rtree, 0, &node_a),
|
||||
"Unexpected rtree_set() failure");
|
||||
assert_ptr_eq(rtree_get(&rtree, 0, true), &node_a,
|
||||
"rtree_get() should return previously set value");
|
||||
|
||||
assert_false(rtree_set(&rtree, ~((uintptr_t)0), &node_b),
|
||||
"Unexpected rtree_set() failure");
|
||||
assert_ptr_eq(rtree_get(&rtree, ~((uintptr_t)0), true), &node_b,
|
||||
"rtree_get() should return previously set value");
|
||||
|
||||
rtree_delete(&rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_bits)
|
||||
{
|
||||
unsigned i, j, k;
|
||||
|
||||
for (i = 1; i < (sizeof(uintptr_t) << 3); i++) {
|
||||
uintptr_t keys[] = {0, 1,
|
||||
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i)) - 1};
|
||||
extent_node_t node;
|
||||
rtree_t rtree;
|
||||
|
||||
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
|
||||
"Unexpected rtree_new() failure");
|
||||
|
||||
for (j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) {
|
||||
assert_false(rtree_set(&rtree, keys[j], &node),
|
||||
"Unexpected rtree_set() failure");
|
||||
for (k = 0; k < sizeof(keys)/sizeof(uintptr_t); k++) {
|
||||
assert_ptr_eq(rtree_get(&rtree, keys[k], true),
|
||||
&node, "rtree_get() should return "
|
||||
"previously set value and ignore "
|
||||
"insignificant key bits; i=%u, j=%u, k=%u, "
|
||||
"set key=%#"FMTxPTR", get key=%#"FMTxPTR, i,
|
||||
j, k, keys[j], keys[k]);
|
||||
}
|
||||
assert_ptr_null(rtree_get(&rtree,
|
||||
(((uintptr_t)1) << (sizeof(uintptr_t)*8-i)), false),
|
||||
"Only leftmost rtree leaf should be set; "
|
||||
"i=%u, j=%u", i, j);
|
||||
assert_false(rtree_set(&rtree, keys[j], NULL),
|
||||
"Unexpected rtree_set() failure");
|
||||
}
|
||||
|
||||
rtree_delete(&rtree);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_rtree_random)
|
||||
{
|
||||
unsigned i;
|
||||
sfmt_t *sfmt;
|
||||
#define NSET 16
|
||||
#define SEED 42
|
||||
|
||||
sfmt = init_gen_rand(SEED);
|
||||
for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) {
|
||||
uintptr_t keys[NSET];
|
||||
extent_node_t node;
|
||||
unsigned j;
|
||||
rtree_t rtree;
|
||||
|
||||
assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc),
|
||||
"Unexpected rtree_new() failure");
|
||||
|
||||
for (j = 0; j < NSET; j++) {
|
||||
keys[j] = (uintptr_t)gen_rand64(sfmt);
|
||||
assert_false(rtree_set(&rtree, keys[j], &node),
|
||||
"Unexpected rtree_set() failure");
|
||||
assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
for (j = 0; j < NSET; j++) {
|
||||
assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node,
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
|
||||
for (j = 0; j < NSET; j++) {
|
||||
assert_false(rtree_set(&rtree, keys[j], NULL),
|
||||
"Unexpected rtree_set() failure");
|
||||
assert_ptr_null(rtree_get(&rtree, keys[j], true),
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
for (j = 0; j < NSET; j++) {
|
||||
assert_ptr_null(rtree_get(&rtree, keys[j], true),
|
||||
"rtree_get() should return previously set value");
|
||||
}
|
||||
|
||||
rtree_delete(&rtree);
|
||||
}
|
||||
fini_gen_rand(sfmt);
|
||||
#undef NSET
|
||||
#undef SEED
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_rtree_get_empty,
|
||||
test_rtree_extrema,
|
||||
test_rtree_bits,
|
||||
test_rtree_random));
|
||||
}
|
||||
149
memory/jemalloc/src/test/unit/run_quantize.c
Normal file
149
memory/jemalloc/src/test/unit/run_quantize.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_small_run_size)
|
||||
{
|
||||
unsigned nbins, i;
|
||||
size_t sz, run_size;
|
||||
size_t mib[4];
|
||||
size_t miblen = sizeof(mib) / sizeof(size_t);
|
||||
|
||||
/*
|
||||
* Iterate over all small size classes, get their run sizes, and verify
|
||||
* that the quantized size is the same as the run size.
|
||||
*/
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nbins", &nbins, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib failure");
|
||||
for (i = 0; i < nbins; i++) {
|
||||
mib[2] = i;
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &run_size, &sz, NULL, 0),
|
||||
0, "Unexpected mallctlbymib failure");
|
||||
assert_zu_eq(run_size, run_quantize_floor(run_size),
|
||||
"Small run quantization should be a no-op (run_size=%zu)",
|
||||
run_size);
|
||||
assert_zu_eq(run_size, run_quantize_ceil(run_size),
|
||||
"Small run quantization should be a no-op (run_size=%zu)",
|
||||
run_size);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_large_run_size)
|
||||
{
|
||||
bool cache_oblivious;
|
||||
unsigned nlruns, i;
|
||||
size_t sz, run_size_prev, ceil_prev;
|
||||
size_t mib[4];
|
||||
size_t miblen = sizeof(mib) / sizeof(size_t);
|
||||
|
||||
/*
|
||||
* Iterate over all large size classes, get their run sizes, and verify
|
||||
* that the quantized size is the same as the run size.
|
||||
*/
|
||||
|
||||
sz = sizeof(bool);
|
||||
assert_d_eq(mallctl("config.cache_oblivious", &cache_oblivious, &sz,
|
||||
NULL, 0), 0, "Unexpected mallctl failure");
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nlruns", &nlruns, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
assert_d_eq(mallctlnametomib("arenas.lrun.0.size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib failure");
|
||||
for (i = 0; i < nlruns; i++) {
|
||||
size_t lrun_size, run_size, floor, ceil;
|
||||
|
||||
mib[2] = i;
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &lrun_size, &sz, NULL, 0),
|
||||
0, "Unexpected mallctlbymib failure");
|
||||
run_size = cache_oblivious ? lrun_size + PAGE : lrun_size;
|
||||
floor = run_quantize_floor(run_size);
|
||||
ceil = run_quantize_ceil(run_size);
|
||||
|
||||
assert_zu_eq(run_size, floor,
|
||||
"Large run quantization should be a no-op for precise "
|
||||
"size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
|
||||
assert_zu_eq(run_size, ceil,
|
||||
"Large run quantization should be a no-op for precise "
|
||||
"size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
|
||||
|
||||
if (i > 0) {
|
||||
assert_zu_eq(run_size_prev, run_quantize_floor(run_size
|
||||
- PAGE), "Floor should be a precise size");
|
||||
if (run_size_prev < ceil_prev) {
|
||||
assert_zu_eq(ceil_prev, run_size,
|
||||
"Ceiling should be a precise size "
|
||||
"(run_size_prev=%zu, ceil_prev=%zu, "
|
||||
"run_size=%zu)", run_size_prev, ceil_prev,
|
||||
run_size);
|
||||
}
|
||||
}
|
||||
run_size_prev = floor;
|
||||
ceil_prev = run_quantize_ceil(run_size + PAGE);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_monotonic)
|
||||
{
|
||||
unsigned nbins, nlruns, i;
|
||||
size_t sz, floor_prev, ceil_prev;
|
||||
|
||||
/*
|
||||
* Iterate over all run sizes and verify that
|
||||
* run_quantize_{floor,ceil}() are monotonic.
|
||||
*/
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nbins", &nbins, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nlruns", &nlruns, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl failure");
|
||||
|
||||
floor_prev = 0;
|
||||
ceil_prev = 0;
|
||||
for (i = 1; i <= chunksize >> LG_PAGE; i++) {
|
||||
size_t run_size, floor, ceil;
|
||||
|
||||
run_size = i << LG_PAGE;
|
||||
floor = run_quantize_floor(run_size);
|
||||
ceil = run_quantize_ceil(run_size);
|
||||
|
||||
assert_zu_le(floor, run_size,
|
||||
"Floor should be <= (floor=%zu, run_size=%zu, ceil=%zu)",
|
||||
floor, run_size, ceil);
|
||||
assert_zu_ge(ceil, run_size,
|
||||
"Ceiling should be >= (floor=%zu, run_size=%zu, ceil=%zu)",
|
||||
floor, run_size, ceil);
|
||||
|
||||
assert_zu_le(floor_prev, floor, "Floor should be monotonic "
|
||||
"(floor_prev=%zu, floor=%zu, run_size=%zu, ceil=%zu)",
|
||||
floor_prev, floor, run_size, ceil);
|
||||
assert_zu_le(ceil_prev, ceil, "Ceiling should be monotonic "
|
||||
"(floor=%zu, run_size=%zu, ceil_prev=%zu, ceil=%zu)",
|
||||
floor, run_size, ceil_prev, ceil);
|
||||
|
||||
floor_prev = floor;
|
||||
ceil_prev = ceil;
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_small_run_size,
|
||||
test_large_run_size,
|
||||
test_monotonic));
|
||||
}
|
||||
184
memory/jemalloc/src/test/unit/size_classes.c
Normal file
184
memory/jemalloc/src/test/unit/size_classes.c
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static size_t
|
||||
get_max_size_class(void)
|
||||
{
|
||||
unsigned nhchunks;
|
||||
size_t mib[4];
|
||||
size_t sz, miblen, max_size_class;
|
||||
|
||||
sz = sizeof(unsigned);
|
||||
assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctl() error");
|
||||
|
||||
miblen = sizeof(mib) / sizeof(size_t);
|
||||
assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0,
|
||||
"Unexpected mallctlnametomib() error");
|
||||
mib[2] = nhchunks - 1;
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0,
|
||||
"Unexpected mallctlbymib() error");
|
||||
|
||||
return (max_size_class);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_size_classes)
|
||||
{
|
||||
size_t size_class, max_size_class;
|
||||
szind_t index, max_index;
|
||||
|
||||
max_size_class = get_max_size_class();
|
||||
max_index = size2index(max_size_class);
|
||||
|
||||
for (index = 0, size_class = index2size(index); index < max_index ||
|
||||
size_class < max_size_class; index++, size_class =
|
||||
index2size(index)) {
|
||||
assert_true(index < max_index,
|
||||
"Loop conditionals should be equivalent; index=%u, "
|
||||
"size_class=%zu (%#zx)", index, size_class, size_class);
|
||||
assert_true(size_class < max_size_class,
|
||||
"Loop conditionals should be equivalent; index=%u, "
|
||||
"size_class=%zu (%#zx)", index, size_class, size_class);
|
||||
|
||||
assert_u_eq(index, size2index(size_class),
|
||||
"size2index() does not reverse index2size(): index=%u -->"
|
||||
" size_class=%zu --> index=%u --> size_class=%zu", index,
|
||||
size_class, size2index(size_class),
|
||||
index2size(size2index(size_class)));
|
||||
assert_zu_eq(size_class, index2size(size2index(size_class)),
|
||||
"index2size() does not reverse size2index(): index=%u -->"
|
||||
" size_class=%zu --> index=%u --> size_class=%zu", index,
|
||||
size_class, size2index(size_class),
|
||||
index2size(size2index(size_class)));
|
||||
|
||||
assert_u_eq(index+1, size2index(size_class+1),
|
||||
"Next size_class does not round up properly");
|
||||
|
||||
assert_zu_eq(size_class, (index > 0) ?
|
||||
s2u(index2size(index-1)+1) : s2u(1),
|
||||
"s2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, s2u(size_class-1),
|
||||
"s2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, s2u(size_class),
|
||||
"s2u() does not compute same size class");
|
||||
assert_zu_eq(s2u(size_class+1), index2size(index+1),
|
||||
"s2u() does not round up to next size class");
|
||||
}
|
||||
|
||||
assert_u_eq(index, size2index(index2size(index)),
|
||||
"size2index() does not reverse index2size()");
|
||||
assert_zu_eq(max_size_class, index2size(size2index(max_size_class)),
|
||||
"index2size() does not reverse size2index()");
|
||||
|
||||
assert_zu_eq(size_class, s2u(index2size(index-1)+1),
|
||||
"s2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, s2u(size_class-1),
|
||||
"s2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, s2u(size_class),
|
||||
"s2u() does not compute same size class");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_psize_classes)
|
||||
{
|
||||
size_t size_class, max_size_class;
|
||||
pszind_t pind, max_pind;
|
||||
|
||||
max_size_class = get_max_size_class();
|
||||
max_pind = psz2ind(max_size_class);
|
||||
|
||||
for (pind = 0, size_class = pind2sz(pind); pind < max_pind ||
|
||||
size_class < max_size_class; pind++, size_class =
|
||||
pind2sz(pind)) {
|
||||
assert_true(pind < max_pind,
|
||||
"Loop conditionals should be equivalent; pind=%u, "
|
||||
"size_class=%zu (%#zx)", pind, size_class, size_class);
|
||||
assert_true(size_class < max_size_class,
|
||||
"Loop conditionals should be equivalent; pind=%u, "
|
||||
"size_class=%zu (%#zx)", pind, size_class, size_class);
|
||||
|
||||
assert_u_eq(pind, psz2ind(size_class),
|
||||
"psz2ind() does not reverse pind2sz(): pind=%u -->"
|
||||
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
|
||||
size_class, psz2ind(size_class),
|
||||
pind2sz(psz2ind(size_class)));
|
||||
assert_zu_eq(size_class, pind2sz(psz2ind(size_class)),
|
||||
"pind2sz() does not reverse psz2ind(): pind=%u -->"
|
||||
" size_class=%zu --> pind=%u --> size_class=%zu", pind,
|
||||
size_class, psz2ind(size_class),
|
||||
pind2sz(psz2ind(size_class)));
|
||||
|
||||
assert_u_eq(pind+1, psz2ind(size_class+1),
|
||||
"Next size_class does not round up properly");
|
||||
|
||||
assert_zu_eq(size_class, (pind > 0) ?
|
||||
psz2u(pind2sz(pind-1)+1) : psz2u(1),
|
||||
"psz2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, psz2u(size_class-1),
|
||||
"psz2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, psz2u(size_class),
|
||||
"psz2u() does not compute same size class");
|
||||
assert_zu_eq(psz2u(size_class+1), pind2sz(pind+1),
|
||||
"psz2u() does not round up to next size class");
|
||||
}
|
||||
|
||||
assert_u_eq(pind, psz2ind(pind2sz(pind)),
|
||||
"psz2ind() does not reverse pind2sz()");
|
||||
assert_zu_eq(max_size_class, pind2sz(psz2ind(max_size_class)),
|
||||
"pind2sz() does not reverse psz2ind()");
|
||||
|
||||
assert_zu_eq(size_class, psz2u(pind2sz(pind-1)+1),
|
||||
"psz2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, psz2u(size_class-1),
|
||||
"psz2u() does not round up to size class");
|
||||
assert_zu_eq(size_class, psz2u(size_class),
|
||||
"psz2u() does not compute same size class");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_overflow)
|
||||
{
|
||||
size_t max_size_class;
|
||||
|
||||
max_size_class = get_max_size_class();
|
||||
|
||||
assert_u_eq(size2index(max_size_class+1), NSIZES,
|
||||
"size2index() should return NSIZES on overflow");
|
||||
assert_u_eq(size2index(ZU(PTRDIFF_MAX)+1), NSIZES,
|
||||
"size2index() should return NSIZES on overflow");
|
||||
assert_u_eq(size2index(SIZE_T_MAX), NSIZES,
|
||||
"size2index() should return NSIZES on overflow");
|
||||
|
||||
assert_zu_eq(s2u(max_size_class+1), 0,
|
||||
"s2u() should return 0 for unsupported size");
|
||||
assert_zu_eq(s2u(ZU(PTRDIFF_MAX)+1), 0,
|
||||
"s2u() should return 0 for unsupported size");
|
||||
assert_zu_eq(s2u(SIZE_T_MAX), 0,
|
||||
"s2u() should return 0 on overflow");
|
||||
|
||||
assert_u_eq(psz2ind(max_size_class+1), NPSIZES,
|
||||
"psz2ind() should return NPSIZES on overflow");
|
||||
assert_u_eq(psz2ind(ZU(PTRDIFF_MAX)+1), NPSIZES,
|
||||
"psz2ind() should return NPSIZES on overflow");
|
||||
assert_u_eq(psz2ind(SIZE_T_MAX), NPSIZES,
|
||||
"psz2ind() should return NPSIZES on overflow");
|
||||
|
||||
assert_zu_eq(psz2u(max_size_class+1), 0,
|
||||
"psz2u() should return 0 for unsupported size");
|
||||
assert_zu_eq(psz2u(ZU(PTRDIFF_MAX)+1), 0,
|
||||
"psz2u() should return 0 for unsupported size");
|
||||
assert_zu_eq(psz2u(SIZE_T_MAX), 0,
|
||||
"psz2u() should return 0 on overflow");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_size_classes,
|
||||
test_psize_classes,
|
||||
test_overflow));
|
||||
}
|
||||
106
memory/jemalloc/src/test/unit/smoothstep.c
Normal file
106
memory/jemalloc/src/test/unit/smoothstep.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static const uint64_t smoothstep_tab[] = {
|
||||
#define STEP(step, h, x, y) \
|
||||
h,
|
||||
SMOOTHSTEP
|
||||
#undef STEP
|
||||
};
|
||||
|
||||
TEST_BEGIN(test_smoothstep_integral)
|
||||
{
|
||||
uint64_t sum, min, max;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* The integral of smoothstep in the [0..1] range equals 1/2. Verify
|
||||
* that the fixed point representation's integral is no more than
|
||||
* rounding error distant from 1/2. Regarding rounding, each table
|
||||
* element is rounded down to the nearest fixed point value, so the
|
||||
* integral may be off by as much as SMOOTHSTEP_NSTEPS ulps.
|
||||
*/
|
||||
sum = 0;
|
||||
for (i = 0; i < SMOOTHSTEP_NSTEPS; i++)
|
||||
sum += smoothstep_tab[i];
|
||||
|
||||
max = (KQU(1) << (SMOOTHSTEP_BFP-1)) * (SMOOTHSTEP_NSTEPS+1);
|
||||
min = max - SMOOTHSTEP_NSTEPS;
|
||||
|
||||
assert_u64_ge(sum, min,
|
||||
"Integral too small, even accounting for truncation");
|
||||
assert_u64_le(sum, max, "Integral exceeds 1/2");
|
||||
if (false) {
|
||||
malloc_printf("%"FMTu64" ulps under 1/2 (limit %d)\n",
|
||||
max - sum, SMOOTHSTEP_NSTEPS);
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_smoothstep_monotonic)
|
||||
{
|
||||
uint64_t prev_h;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* The smoothstep function is monotonic in [0..1], i.e. its slope is
|
||||
* non-negative. In practice we want to parametrize table generation
|
||||
* such that piecewise slope is greater than zero, but do not require
|
||||
* that here.
|
||||
*/
|
||||
prev_h = 0;
|
||||
for (i = 0; i < SMOOTHSTEP_NSTEPS; i++) {
|
||||
uint64_t h = smoothstep_tab[i];
|
||||
assert_u64_ge(h, prev_h, "Piecewise non-monotonic, i=%u", i);
|
||||
prev_h = h;
|
||||
}
|
||||
assert_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS-1],
|
||||
(KQU(1) << SMOOTHSTEP_BFP), "Last step must equal 1");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_smoothstep_slope)
|
||||
{
|
||||
uint64_t prev_h, prev_delta;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* The smoothstep slope strictly increases until x=0.5, and then
|
||||
* strictly decreases until x=1.0. Verify the slightly weaker
|
||||
* requirement of monotonicity, so that inadequate table precision does
|
||||
* not cause false test failures.
|
||||
*/
|
||||
prev_h = 0;
|
||||
prev_delta = 0;
|
||||
for (i = 0; i < SMOOTHSTEP_NSTEPS / 2 + SMOOTHSTEP_NSTEPS % 2; i++) {
|
||||
uint64_t h = smoothstep_tab[i];
|
||||
uint64_t delta = h - prev_h;
|
||||
assert_u64_ge(delta, prev_delta,
|
||||
"Slope must monotonically increase in 0.0 <= x <= 0.5, "
|
||||
"i=%u", i);
|
||||
prev_h = h;
|
||||
prev_delta = delta;
|
||||
}
|
||||
|
||||
prev_h = KQU(1) << SMOOTHSTEP_BFP;
|
||||
prev_delta = 0;
|
||||
for (i = SMOOTHSTEP_NSTEPS-1; i >= SMOOTHSTEP_NSTEPS / 2; i--) {
|
||||
uint64_t h = smoothstep_tab[i];
|
||||
uint64_t delta = prev_h - h;
|
||||
assert_u64_ge(delta, prev_delta,
|
||||
"Slope must monotonically decrease in 0.5 <= x <= 1.0, "
|
||||
"i=%u", i);
|
||||
prev_h = h;
|
||||
prev_delta = delta;
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_smoothstep_integral,
|
||||
test_smoothstep_monotonic,
|
||||
test_smoothstep_slope));
|
||||
}
|
||||
447
memory/jemalloc/src/test/unit/stats.c
Normal file
447
memory/jemalloc/src/test/unit/stats.c
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_stats_summary)
|
||||
{
|
||||
size_t *cactive;
|
||||
size_t sz, allocated, active, resident, mapped;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
sz = sizeof(cactive);
|
||||
assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
|
||||
expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.resident", &resident, &sz, NULL, 0),
|
||||
expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_le(active, *cactive,
|
||||
"active should be no larger than cactive");
|
||||
assert_zu_le(allocated, active,
|
||||
"allocated should be no larger than active");
|
||||
assert_zu_lt(active, resident,
|
||||
"active should be less than resident");
|
||||
assert_zu_lt(active, mapped,
|
||||
"active should be less than mapped");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_huge)
|
||||
{
|
||||
void *p;
|
||||
uint64_t epoch;
|
||||
size_t allocated;
|
||||
uint64_t nmalloc, ndalloc, nrequests;
|
||||
size_t sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
p = mallocx(large_maxclass+1, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, NULL,
|
||||
0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, NULL,
|
||||
0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_le(nmalloc, nrequests,
|
||||
"nmalloc should no larger than nrequests");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_summary)
|
||||
{
|
||||
unsigned arena;
|
||||
void *little, *large, *huge;
|
||||
uint64_t epoch;
|
||||
size_t sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
size_t mapped;
|
||||
uint64_t npurge, nmadvise, purged;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
little = mallocx(SMALL_MAXCLASS, 0);
|
||||
assert_ptr_not_null(little, "Unexpected mallocx() failure");
|
||||
large = mallocx(large_maxclass, 0);
|
||||
assert_ptr_not_null(large, "Unexpected mallocx() failure");
|
||||
huge = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(huge, "Unexpected mallocx() failure");
|
||||
|
||||
dallocx(little, 0);
|
||||
dallocx(large, 0);
|
||||
dallocx(huge, 0);
|
||||
|
||||
assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.mapped", &mapped, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.nmadvise", &nmadvise, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.purged", &purged, &sz, NULL, 0),
|
||||
expected, "Unexepected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_u64_gt(npurge, 0,
|
||||
"At least one purge should have occurred");
|
||||
assert_u64_le(nmadvise, purged,
|
||||
"nmadvise should be no greater than purged");
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
no_lazy_lock(void)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
thd_create(&thd, thd_start, NULL);
|
||||
thd_join(thd, NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_small)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
no_lazy_lock(); /* Lazy locking would dodge tcache testing. */
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(SMALL_MAXCLASS, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
|
||||
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.small.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be no greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_gt(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_large)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(large_maxclass, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.large.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_gt(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_huge)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, allocated;
|
||||
uint64_t epoch, nmalloc, ndalloc;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_zu_gt(allocated, 0,
|
||||
"allocated should be greater than zero");
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_bins)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
size_t sz, curruns, curregs;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
|
||||
uint64_t nruns, nreruns;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(arena_bin_info[0].reg_size, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
|
||||
config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", &curregs, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
|
||||
NULL, 0), config_tcache ? expected : ENOENT,
|
||||
"Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz,
|
||||
NULL, 0), config_tcache ? expected : ENOENT,
|
||||
"Unexpected mallctl() result");
|
||||
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", &nruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", &nreruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", &curruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_gt(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
assert_zu_gt(curregs, 0,
|
||||
"allocated should be greater than zero");
|
||||
if (config_tcache) {
|
||||
assert_u64_gt(nfills, 0,
|
||||
"At least one fill should have occurred");
|
||||
assert_u64_gt(nflushes, 0,
|
||||
"At least one flush should have occurred");
|
||||
}
|
||||
assert_u64_gt(nruns, 0,
|
||||
"At least one run should have been allocated");
|
||||
assert_zu_gt(curruns, 0,
|
||||
"At least one run should be currently allocated");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_lruns)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
uint64_t epoch, nmalloc, ndalloc, nrequests;
|
||||
size_t curruns, sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(LARGE_MINCLASS, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests", &nrequests, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", &curruns, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_gt(nrequests, 0,
|
||||
"nrequests should be greater than zero");
|
||||
assert_u64_gt(curruns, 0,
|
||||
"At least one run should be currently allocated");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_stats_arenas_hchunks)
|
||||
{
|
||||
unsigned arena;
|
||||
void *p;
|
||||
uint64_t epoch, nmalloc, ndalloc;
|
||||
size_t curhchunks, sz;
|
||||
int expected = config_stats ? 0 : ENOENT;
|
||||
|
||||
arena = 0;
|
||||
assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
|
||||
0, "Unexpected mallctl() failure");
|
||||
|
||||
p = mallocx(chunksize, 0);
|
||||
assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
||||
|
||||
assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
|
||||
"Unexpected mallctl() failure");
|
||||
|
||||
sz = sizeof(uint64_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc", &nmalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc", &ndalloc, &sz,
|
||||
NULL, 0), expected, "Unexpected mallctl() result");
|
||||
sz = sizeof(size_t);
|
||||
assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks", &curhchunks,
|
||||
&sz, NULL, 0), expected, "Unexpected mallctl() result");
|
||||
|
||||
if (config_stats) {
|
||||
assert_u64_gt(nmalloc, 0,
|
||||
"nmalloc should be greater than zero");
|
||||
assert_u64_ge(nmalloc, ndalloc,
|
||||
"nmalloc should be at least as large as ndalloc");
|
||||
assert_u64_gt(curhchunks, 0,
|
||||
"At least one chunk should be currently allocated");
|
||||
}
|
||||
|
||||
dallocx(p, 0);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_stats_summary,
|
||||
test_stats_huge,
|
||||
test_stats_arenas_summary,
|
||||
test_stats_arenas_small,
|
||||
test_stats_arenas_large,
|
||||
test_stats_arenas_huge,
|
||||
test_stats_arenas_bins,
|
||||
test_stats_arenas_lruns,
|
||||
test_stats_arenas_hchunks));
|
||||
}
|
||||
76
memory/jemalloc/src/test/unit/ticker.c
Normal file
76
memory/jemalloc/src/test/unit/ticker.c
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
TEST_BEGIN(test_ticker_tick)
|
||||
{
|
||||
#define NREPS 2
|
||||
#define NTICKS 3
|
||||
ticker_t ticker;
|
||||
int32_t i, j;
|
||||
|
||||
ticker_init(&ticker, NTICKS);
|
||||
for (i = 0; i < NREPS; i++) {
|
||||
for (j = 0; j < NTICKS; j++) {
|
||||
assert_u_eq(ticker_read(&ticker), NTICKS - j,
|
||||
"Unexpected ticker value (i=%d, j=%d)", i, j);
|
||||
assert_false(ticker_tick(&ticker),
|
||||
"Unexpected ticker fire (i=%d, j=%d)", i, j);
|
||||
}
|
||||
assert_u32_eq(ticker_read(&ticker), 0,
|
||||
"Expected ticker depletion");
|
||||
assert_true(ticker_tick(&ticker),
|
||||
"Expected ticker fire (i=%d)", i);
|
||||
assert_u32_eq(ticker_read(&ticker), NTICKS,
|
||||
"Expected ticker reset");
|
||||
}
|
||||
#undef NTICKS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ticker_ticks)
|
||||
{
|
||||
#define NTICKS 3
|
||||
ticker_t ticker;
|
||||
|
||||
ticker_init(&ticker, NTICKS);
|
||||
|
||||
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
|
||||
assert_false(ticker_ticks(&ticker, NTICKS), "Unexpected ticker fire");
|
||||
assert_u_eq(ticker_read(&ticker), 0, "Unexpected ticker value");
|
||||
assert_true(ticker_ticks(&ticker, NTICKS), "Expected ticker fire");
|
||||
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
|
||||
|
||||
assert_true(ticker_ticks(&ticker, NTICKS + 1), "Expected ticker fire");
|
||||
assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value");
|
||||
#undef NTICKS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_ticker_copy)
|
||||
{
|
||||
#define NTICKS 3
|
||||
ticker_t ta, tb;
|
||||
|
||||
ticker_init(&ta, NTICKS);
|
||||
ticker_copy(&tb, &ta);
|
||||
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
|
||||
assert_true(ticker_ticks(&tb, NTICKS + 1), "Expected ticker fire");
|
||||
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
|
||||
|
||||
ticker_tick(&ta);
|
||||
ticker_copy(&tb, &ta);
|
||||
assert_u_eq(ticker_read(&tb), NTICKS - 1, "Unexpected ticker value");
|
||||
assert_true(ticker_ticks(&tb, NTICKS), "Expected ticker fire");
|
||||
assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value");
|
||||
#undef NTICKS
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_ticker_tick,
|
||||
test_ticker_ticks,
|
||||
test_ticker_copy));
|
||||
}
|
||||
112
memory/jemalloc/src/test/unit/tsd.c
Normal file
112
memory/jemalloc/src/test/unit/tsd.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define THREAD_DATA 0x72b65c10
|
||||
|
||||
typedef unsigned int data_t;
|
||||
|
||||
static bool data_cleanup_executed;
|
||||
|
||||
malloc_tsd_types(data_, data_t)
|
||||
malloc_tsd_protos(, data_, data_t)
|
||||
|
||||
void
|
||||
data_cleanup(void *arg)
|
||||
{
|
||||
data_t *data = (data_t *)arg;
|
||||
|
||||
if (!data_cleanup_executed) {
|
||||
assert_x_eq(*data, THREAD_DATA,
|
||||
"Argument passed into cleanup function should match tsd "
|
||||
"value");
|
||||
}
|
||||
data_cleanup_executed = true;
|
||||
|
||||
/*
|
||||
* Allocate during cleanup for two rounds, in order to assure that
|
||||
* jemalloc's internal tsd reinitialization happens.
|
||||
*/
|
||||
switch (*data) {
|
||||
case THREAD_DATA:
|
||||
*data = 1;
|
||||
data_tsd_set(data);
|
||||
break;
|
||||
case 1:
|
||||
*data = 2;
|
||||
data_tsd_set(data);
|
||||
break;
|
||||
case 2:
|
||||
return;
|
||||
default:
|
||||
not_reached();
|
||||
}
|
||||
|
||||
{
|
||||
void *p = mallocx(1, 0);
|
||||
assert_ptr_not_null(p, "Unexpeced mallocx() failure");
|
||||
dallocx(p, 0);
|
||||
}
|
||||
}
|
||||
|
||||
malloc_tsd_externs(data_, data_t)
|
||||
#define DATA_INIT 0x12345678
|
||||
malloc_tsd_data(, data_, data_t, DATA_INIT)
|
||||
malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup)
|
||||
|
||||
static void *
|
||||
thd_start(void *arg)
|
||||
{
|
||||
data_t d = (data_t)(uintptr_t)arg;
|
||||
void *p;
|
||||
|
||||
assert_x_eq(*data_tsd_get(true), DATA_INIT,
|
||||
"Initial tsd get should return initialization value");
|
||||
|
||||
p = malloc(1);
|
||||
assert_ptr_not_null(p, "Unexpected malloc() failure");
|
||||
|
||||
data_tsd_set(&d);
|
||||
assert_x_eq(*data_tsd_get(true), d,
|
||||
"After tsd set, tsd get should return value that was set");
|
||||
|
||||
d = 0;
|
||||
assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg,
|
||||
"Resetting local data should have no effect on tsd");
|
||||
|
||||
free(p);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_tsd_main_thread)
|
||||
{
|
||||
|
||||
thd_start((void *) 0xa5f3e329);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_tsd_sub_thread)
|
||||
{
|
||||
thd_t thd;
|
||||
|
||||
data_cleanup_executed = false;
|
||||
thd_create(&thd, thd_start, (void *)THREAD_DATA);
|
||||
thd_join(thd, NULL);
|
||||
assert_true(data_cleanup_executed,
|
||||
"Cleanup function should have executed");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
/* Core tsd bootstrapping must happen prior to data_tsd_boot(). */
|
||||
if (nallocx(1, 0) == 0) {
|
||||
malloc_printf("Initialization error");
|
||||
return (test_status_fail);
|
||||
}
|
||||
data_tsd_boot();
|
||||
|
||||
return (test(
|
||||
test_tsd_main_thread,
|
||||
test_tsd_sub_thread));
|
||||
}
|
||||
317
memory/jemalloc/src/test/unit/util.c
Normal file
317
memory/jemalloc/src/test/unit/util.c
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#define TEST_POW2_CEIL(t, suf, pri) do { \
|
||||
unsigned i, pow2; \
|
||||
t x; \
|
||||
\
|
||||
assert_##suf##_eq(pow2_ceil_##suf(0), 0, "Unexpected result"); \
|
||||
\
|
||||
for (i = 0; i < sizeof(t) * 8; i++) { \
|
||||
assert_##suf##_eq(pow2_ceil_##suf(((t)1) << i), ((t)1) \
|
||||
<< i, "Unexpected result"); \
|
||||
} \
|
||||
\
|
||||
for (i = 2; i < sizeof(t) * 8; i++) { \
|
||||
assert_##suf##_eq(pow2_ceil_##suf((((t)1) << i) - 1), \
|
||||
((t)1) << i, "Unexpected result"); \
|
||||
} \
|
||||
\
|
||||
for (i = 0; i < sizeof(t) * 8 - 1; i++) { \
|
||||
assert_##suf##_eq(pow2_ceil_##suf((((t)1) << i) + 1), \
|
||||
((t)1) << (i+1), "Unexpected result"); \
|
||||
} \
|
||||
\
|
||||
for (pow2 = 1; pow2 < 25; pow2++) { \
|
||||
for (x = (((t)1) << (pow2-1)) + 1; x <= ((t)1) << pow2; \
|
||||
x++) { \
|
||||
assert_##suf##_eq(pow2_ceil_##suf(x), \
|
||||
((t)1) << pow2, \
|
||||
"Unexpected result, x=%"pri, x); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
TEST_BEGIN(test_pow2_ceil_u64)
|
||||
{
|
||||
|
||||
TEST_POW2_CEIL(uint64_t, u64, FMTu64);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_pow2_ceil_u32)
|
||||
{
|
||||
|
||||
TEST_POW2_CEIL(uint32_t, u32, FMTu32);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_pow2_ceil_zu)
|
||||
{
|
||||
|
||||
TEST_POW2_CEIL(size_t, zu, "zu");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_strtoumax_no_endptr)
|
||||
{
|
||||
int err;
|
||||
|
||||
set_errno(0);
|
||||
assert_ju_eq(malloc_strtoumax("0", NULL, 0), 0, "Unexpected result");
|
||||
err = get_errno();
|
||||
assert_d_eq(err, 0, "Unexpected failure");
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_strtoumax)
|
||||
{
|
||||
struct test_s {
|
||||
const char *input;
|
||||
const char *expected_remainder;
|
||||
int base;
|
||||
int expected_errno;
|
||||
const char *expected_errno_name;
|
||||
uintmax_t expected_x;
|
||||
};
|
||||
#define ERR(e) e, #e
|
||||
#define KUMAX(x) ((uintmax_t)x##ULL)
|
||||
struct test_s tests[] = {
|
||||
{"0", "0", -1, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"0", "0", 1, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"0", "0", 37, ERR(EINVAL), UINTMAX_MAX},
|
||||
|
||||
{"", "", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"+", "+", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"++3", "++3", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
{"-", "-", 0, ERR(EINVAL), UINTMAX_MAX},
|
||||
|
||||
{"42", "", 0, ERR(0), KUMAX(42)},
|
||||
{"+42", "", 0, ERR(0), KUMAX(42)},
|
||||
{"-42", "", 0, ERR(0), KUMAX(-42)},
|
||||
{"042", "", 0, ERR(0), KUMAX(042)},
|
||||
{"+042", "", 0, ERR(0), KUMAX(042)},
|
||||
{"-042", "", 0, ERR(0), KUMAX(-042)},
|
||||
{"0x42", "", 0, ERR(0), KUMAX(0x42)},
|
||||
{"+0x42", "", 0, ERR(0), KUMAX(0x42)},
|
||||
{"-0x42", "", 0, ERR(0), KUMAX(-0x42)},
|
||||
|
||||
{"0", "", 0, ERR(0), KUMAX(0)},
|
||||
{"1", "", 0, ERR(0), KUMAX(1)},
|
||||
|
||||
{"42", "", 0, ERR(0), KUMAX(42)},
|
||||
{" 42", "", 0, ERR(0), KUMAX(42)},
|
||||
{"42 ", " ", 0, ERR(0), KUMAX(42)},
|
||||
{"0x", "x", 0, ERR(0), KUMAX(0)},
|
||||
{"42x", "x", 0, ERR(0), KUMAX(42)},
|
||||
|
||||
{"07", "", 0, ERR(0), KUMAX(7)},
|
||||
{"010", "", 0, ERR(0), KUMAX(8)},
|
||||
{"08", "8", 0, ERR(0), KUMAX(0)},
|
||||
{"0_", "_", 0, ERR(0), KUMAX(0)},
|
||||
|
||||
{"0x", "x", 0, ERR(0), KUMAX(0)},
|
||||
{"0X", "X", 0, ERR(0), KUMAX(0)},
|
||||
{"0xg", "xg", 0, ERR(0), KUMAX(0)},
|
||||
{"0XA", "", 0, ERR(0), KUMAX(10)},
|
||||
|
||||
{"010", "", 10, ERR(0), KUMAX(10)},
|
||||
{"0x3", "x3", 10, ERR(0), KUMAX(0)},
|
||||
|
||||
{"12", "2", 2, ERR(0), KUMAX(1)},
|
||||
{"78", "8", 8, ERR(0), KUMAX(7)},
|
||||
{"9a", "a", 10, ERR(0), KUMAX(9)},
|
||||
{"9A", "A", 10, ERR(0), KUMAX(9)},
|
||||
{"fg", "g", 16, ERR(0), KUMAX(15)},
|
||||
{"FG", "G", 16, ERR(0), KUMAX(15)},
|
||||
{"0xfg", "g", 16, ERR(0), KUMAX(15)},
|
||||
{"0XFG", "G", 16, ERR(0), KUMAX(15)},
|
||||
{"z_", "_", 36, ERR(0), KUMAX(35)},
|
||||
{"Z_", "_", 36, ERR(0), KUMAX(35)}
|
||||
};
|
||||
#undef ERR
|
||||
#undef KUMAX
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) {
|
||||
struct test_s *test = &tests[i];
|
||||
int err;
|
||||
uintmax_t result;
|
||||
char *remainder;
|
||||
|
||||
set_errno(0);
|
||||
result = malloc_strtoumax(test->input, &remainder, test->base);
|
||||
err = get_errno();
|
||||
assert_d_eq(err, test->expected_errno,
|
||||
"Expected errno %s for \"%s\", base %d",
|
||||
test->expected_errno_name, test->input, test->base);
|
||||
assert_str_eq(remainder, test->expected_remainder,
|
||||
"Unexpected remainder for \"%s\", base %d",
|
||||
test->input, test->base);
|
||||
if (err == 0) {
|
||||
assert_ju_eq(result, test->expected_x,
|
||||
"Unexpected result for \"%s\", base %d",
|
||||
test->input, test->base);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_snprintf_truncated)
|
||||
{
|
||||
#define BUFLEN 15
|
||||
char buf[BUFLEN];
|
||||
size_t result;
|
||||
size_t len;
|
||||
#define TEST(expected_str_untruncated, ...) do { \
|
||||
result = malloc_snprintf(buf, len, __VA_ARGS__); \
|
||||
assert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \
|
||||
"Unexpected string inequality (\"%s\" vs \"%s\")", \
|
||||
buf, expected_str_untruncated); \
|
||||
assert_zu_eq(result, strlen(expected_str_untruncated), \
|
||||
"Unexpected result"); \
|
||||
} while (0)
|
||||
|
||||
for (len = 1; len < BUFLEN; len++) {
|
||||
TEST("012346789", "012346789");
|
||||
TEST("a0123b", "a%sb", "0123");
|
||||
TEST("a01234567", "a%s%s", "0123", "4567");
|
||||
TEST("a0123 ", "a%-6s", "0123");
|
||||
TEST("a 0123", "a%6s", "0123");
|
||||
TEST("a 012", "a%6.3s", "0123");
|
||||
TEST("a 012", "a%*.*s", 6, 3, "0123");
|
||||
TEST("a 123b", "a% db", 123);
|
||||
TEST("a123b", "a%-db", 123);
|
||||
TEST("a-123b", "a%-db", -123);
|
||||
TEST("a+123b", "a%+db", 123);
|
||||
}
|
||||
#undef BUFLEN
|
||||
#undef TEST
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_malloc_snprintf)
|
||||
{
|
||||
#define BUFLEN 128
|
||||
char buf[BUFLEN];
|
||||
size_t result;
|
||||
#define TEST(expected_str, ...) do { \
|
||||
result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \
|
||||
assert_str_eq(buf, expected_str, "Unexpected output"); \
|
||||
assert_zu_eq(result, strlen(expected_str), "Unexpected result");\
|
||||
} while (0)
|
||||
|
||||
TEST("hello", "hello");
|
||||
|
||||
TEST("50%, 100%", "50%%, %d%%", 100);
|
||||
|
||||
TEST("a0123b", "a%sb", "0123");
|
||||
|
||||
TEST("a 0123b", "a%5sb", "0123");
|
||||
TEST("a 0123b", "a%*sb", 5, "0123");
|
||||
|
||||
TEST("a0123 b", "a%-5sb", "0123");
|
||||
TEST("a0123b", "a%*sb", -1, "0123");
|
||||
TEST("a0123 b", "a%*sb", -5, "0123");
|
||||
TEST("a0123 b", "a%-*sb", -5, "0123");
|
||||
|
||||
TEST("a012b", "a%.3sb", "0123");
|
||||
TEST("a012b", "a%.*sb", 3, "0123");
|
||||
TEST("a0123b", "a%.*sb", -3, "0123");
|
||||
|
||||
TEST("a 012b", "a%5.3sb", "0123");
|
||||
TEST("a 012b", "a%5.*sb", 3, "0123");
|
||||
TEST("a 012b", "a%*.3sb", 5, "0123");
|
||||
TEST("a 012b", "a%*.*sb", 5, 3, "0123");
|
||||
TEST("a 0123b", "a%*.*sb", 5, -3, "0123");
|
||||
|
||||
TEST("_abcd_", "_%x_", 0xabcd);
|
||||
TEST("_0xabcd_", "_%#x_", 0xabcd);
|
||||
TEST("_1234_", "_%o_", 01234);
|
||||
TEST("_01234_", "_%#o_", 01234);
|
||||
TEST("_1234_", "_%u_", 1234);
|
||||
|
||||
TEST("_1234_", "_%d_", 1234);
|
||||
TEST("_ 1234_", "_% d_", 1234);
|
||||
TEST("_+1234_", "_%+d_", 1234);
|
||||
TEST("_-1234_", "_%d_", -1234);
|
||||
TEST("_-1234_", "_% d_", -1234);
|
||||
TEST("_-1234_", "_%+d_", -1234);
|
||||
|
||||
TEST("_-1234_", "_%d_", -1234);
|
||||
TEST("_1234_", "_%d_", 1234);
|
||||
TEST("_-1234_", "_%i_", -1234);
|
||||
TEST("_1234_", "_%i_", 1234);
|
||||
TEST("_01234_", "_%#o_", 01234);
|
||||
TEST("_1234_", "_%u_", 1234);
|
||||
TEST("_0x1234abc_", "_%#x_", 0x1234abc);
|
||||
TEST("_0X1234ABC_", "_%#X_", 0x1234abc);
|
||||
TEST("_c_", "_%c_", 'c');
|
||||
TEST("_string_", "_%s_", "string");
|
||||
TEST("_0x42_", "_%p_", ((void *)0x42));
|
||||
|
||||
TEST("_-1234_", "_%ld_", ((long)-1234));
|
||||
TEST("_1234_", "_%ld_", ((long)1234));
|
||||
TEST("_-1234_", "_%li_", ((long)-1234));
|
||||
TEST("_1234_", "_%li_", ((long)1234));
|
||||
TEST("_01234_", "_%#lo_", ((long)01234));
|
||||
TEST("_1234_", "_%lu_", ((long)1234));
|
||||
TEST("_0x1234abc_", "_%#lx_", ((long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#lX_", ((long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%lld_", ((long long)-1234));
|
||||
TEST("_1234_", "_%lld_", ((long long)1234));
|
||||
TEST("_-1234_", "_%lli_", ((long long)-1234));
|
||||
TEST("_1234_", "_%lli_", ((long long)1234));
|
||||
TEST("_01234_", "_%#llo_", ((long long)01234));
|
||||
TEST("_1234_", "_%llu_", ((long long)1234));
|
||||
TEST("_0x1234abc_", "_%#llx_", ((long long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#llX_", ((long long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%qd_", ((long long)-1234));
|
||||
TEST("_1234_", "_%qd_", ((long long)1234));
|
||||
TEST("_-1234_", "_%qi_", ((long long)-1234));
|
||||
TEST("_1234_", "_%qi_", ((long long)1234));
|
||||
TEST("_01234_", "_%#qo_", ((long long)01234));
|
||||
TEST("_1234_", "_%qu_", ((long long)1234));
|
||||
TEST("_0x1234abc_", "_%#qx_", ((long long)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#qX_", ((long long)0x1234ABC));
|
||||
|
||||
TEST("_-1234_", "_%jd_", ((intmax_t)-1234));
|
||||
TEST("_1234_", "_%jd_", ((intmax_t)1234));
|
||||
TEST("_-1234_", "_%ji_", ((intmax_t)-1234));
|
||||
TEST("_1234_", "_%ji_", ((intmax_t)1234));
|
||||
TEST("_01234_", "_%#jo_", ((intmax_t)01234));
|
||||
TEST("_1234_", "_%ju_", ((intmax_t)1234));
|
||||
TEST("_0x1234abc_", "_%#jx_", ((intmax_t)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#jX_", ((intmax_t)0x1234ABC));
|
||||
|
||||
TEST("_1234_", "_%td_", ((ptrdiff_t)1234));
|
||||
TEST("_-1234_", "_%td_", ((ptrdiff_t)-1234));
|
||||
TEST("_1234_", "_%ti_", ((ptrdiff_t)1234));
|
||||
TEST("_-1234_", "_%ti_", ((ptrdiff_t)-1234));
|
||||
|
||||
TEST("_-1234_", "_%zd_", ((ssize_t)-1234));
|
||||
TEST("_1234_", "_%zd_", ((ssize_t)1234));
|
||||
TEST("_-1234_", "_%zi_", ((ssize_t)-1234));
|
||||
TEST("_1234_", "_%zi_", ((ssize_t)1234));
|
||||
TEST("_01234_", "_%#zo_", ((ssize_t)01234));
|
||||
TEST("_1234_", "_%zu_", ((ssize_t)1234));
|
||||
TEST("_0x1234abc_", "_%#zx_", ((ssize_t)0x1234abc));
|
||||
TEST("_0X1234ABC_", "_%#zX_", ((ssize_t)0x1234ABC));
|
||||
#undef BUFLEN
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_pow2_ceil_u64,
|
||||
test_pow2_ceil_u32,
|
||||
test_pow2_ceil_zu,
|
||||
test_malloc_strtoumax_no_endptr,
|
||||
test_malloc_strtoumax,
|
||||
test_malloc_snprintf_truncated,
|
||||
test_malloc_snprintf));
|
||||
}
|
||||
278
memory/jemalloc/src/test/unit/witness.c
Normal file
278
memory/jemalloc/src/test/unit/witness.c
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
static witness_lock_error_t *witness_lock_error_orig;
|
||||
static witness_owner_error_t *witness_owner_error_orig;
|
||||
static witness_not_owner_error_t *witness_not_owner_error_orig;
|
||||
static witness_lockless_error_t *witness_lockless_error_orig;
|
||||
|
||||
static bool saw_lock_error;
|
||||
static bool saw_owner_error;
|
||||
static bool saw_not_owner_error;
|
||||
static bool saw_lockless_error;
|
||||
|
||||
static void
|
||||
witness_lock_error_intercept(const witness_list_t *witnesses,
|
||||
const witness_t *witness)
|
||||
{
|
||||
|
||||
saw_lock_error = true;
|
||||
}
|
||||
|
||||
static void
|
||||
witness_owner_error_intercept(const witness_t *witness)
|
||||
{
|
||||
|
||||
saw_owner_error = true;
|
||||
}
|
||||
|
||||
static void
|
||||
witness_not_owner_error_intercept(const witness_t *witness)
|
||||
{
|
||||
|
||||
saw_not_owner_error = true;
|
||||
}
|
||||
|
||||
static void
|
||||
witness_lockless_error_intercept(const witness_list_t *witnesses)
|
||||
{
|
||||
|
||||
saw_lockless_error = true;
|
||||
}
|
||||
|
||||
static int
|
||||
witness_comp(const witness_t *a, const witness_t *b)
|
||||
{
|
||||
|
||||
assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
|
||||
|
||||
return (strcmp(a->name, b->name));
|
||||
}
|
||||
|
||||
static int
|
||||
witness_comp_reverse(const witness_t *a, const witness_t *b)
|
||||
{
|
||||
|
||||
assert_u_eq(a->rank, b->rank, "Witnesses should have equal rank");
|
||||
|
||||
return (-strcmp(a->name, b->name));
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_witness)
|
||||
{
|
||||
witness_t a, b;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, NULL);
|
||||
witness_assert_not_owner(tsdn, &a);
|
||||
witness_lock(tsdn, &a);
|
||||
witness_assert_owner(tsdn, &a);
|
||||
|
||||
witness_init(&b, "b", 2, NULL);
|
||||
witness_assert_not_owner(tsdn, &b);
|
||||
witness_lock(tsdn, &b);
|
||||
witness_assert_owner(tsdn, &b);
|
||||
|
||||
witness_unlock(tsdn, &a);
|
||||
witness_unlock(tsdn, &b);
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_witness_comp)
|
||||
{
|
||||
witness_t a, b, c, d;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, witness_comp);
|
||||
witness_assert_not_owner(tsdn, &a);
|
||||
witness_lock(tsdn, &a);
|
||||
witness_assert_owner(tsdn, &a);
|
||||
|
||||
witness_init(&b, "b", 1, witness_comp);
|
||||
witness_assert_not_owner(tsdn, &b);
|
||||
witness_lock(tsdn, &b);
|
||||
witness_assert_owner(tsdn, &b);
|
||||
witness_unlock(tsdn, &b);
|
||||
|
||||
witness_lock_error_orig = witness_lock_error;
|
||||
witness_lock_error = witness_lock_error_intercept;
|
||||
saw_lock_error = false;
|
||||
|
||||
witness_init(&c, "c", 1, witness_comp_reverse);
|
||||
witness_assert_not_owner(tsdn, &c);
|
||||
assert_false(saw_lock_error, "Unexpected witness lock error");
|
||||
witness_lock(tsdn, &c);
|
||||
assert_true(saw_lock_error, "Expected witness lock error");
|
||||
witness_unlock(tsdn, &c);
|
||||
|
||||
saw_lock_error = false;
|
||||
|
||||
witness_init(&d, "d", 1, NULL);
|
||||
witness_assert_not_owner(tsdn, &d);
|
||||
assert_false(saw_lock_error, "Unexpected witness lock error");
|
||||
witness_lock(tsdn, &d);
|
||||
assert_true(saw_lock_error, "Expected witness lock error");
|
||||
witness_unlock(tsdn, &d);
|
||||
|
||||
witness_unlock(tsdn, &a);
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_lock_error = witness_lock_error_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_witness_reversal)
|
||||
{
|
||||
witness_t a, b;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
witness_lock_error_orig = witness_lock_error;
|
||||
witness_lock_error = witness_lock_error_intercept;
|
||||
saw_lock_error = false;
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, NULL);
|
||||
witness_init(&b, "b", 2, NULL);
|
||||
|
||||
witness_lock(tsdn, &b);
|
||||
assert_false(saw_lock_error, "Unexpected witness lock error");
|
||||
witness_lock(tsdn, &a);
|
||||
assert_true(saw_lock_error, "Expected witness lock error");
|
||||
|
||||
witness_unlock(tsdn, &a);
|
||||
witness_unlock(tsdn, &b);
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_lock_error = witness_lock_error_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_witness_recursive)
|
||||
{
|
||||
witness_t a;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
witness_not_owner_error_orig = witness_not_owner_error;
|
||||
witness_not_owner_error = witness_not_owner_error_intercept;
|
||||
saw_not_owner_error = false;
|
||||
|
||||
witness_lock_error_orig = witness_lock_error;
|
||||
witness_lock_error = witness_lock_error_intercept;
|
||||
saw_lock_error = false;
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, NULL);
|
||||
|
||||
witness_lock(tsdn, &a);
|
||||
assert_false(saw_lock_error, "Unexpected witness lock error");
|
||||
assert_false(saw_not_owner_error, "Unexpected witness not owner error");
|
||||
witness_lock(tsdn, &a);
|
||||
assert_true(saw_lock_error, "Expected witness lock error");
|
||||
assert_true(saw_not_owner_error, "Expected witness not owner error");
|
||||
|
||||
witness_unlock(tsdn, &a);
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_owner_error = witness_owner_error_orig;
|
||||
witness_lock_error = witness_lock_error_orig;
|
||||
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_witness_unlock_not_owned)
|
||||
{
|
||||
witness_t a;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
witness_owner_error_orig = witness_owner_error;
|
||||
witness_owner_error = witness_owner_error_intercept;
|
||||
saw_owner_error = false;
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, NULL);
|
||||
|
||||
assert_false(saw_owner_error, "Unexpected owner error");
|
||||
witness_unlock(tsdn, &a);
|
||||
assert_true(saw_owner_error, "Expected owner error");
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_owner_error = witness_owner_error_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_witness_lockful)
|
||||
{
|
||||
witness_t a;
|
||||
tsdn_t *tsdn;
|
||||
|
||||
test_skip_if(!config_debug);
|
||||
|
||||
witness_lockless_error_orig = witness_lockless_error;
|
||||
witness_lockless_error = witness_lockless_error_intercept;
|
||||
saw_lockless_error = false;
|
||||
|
||||
tsdn = tsdn_fetch();
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_init(&a, "a", 1, NULL);
|
||||
|
||||
assert_false(saw_lockless_error, "Unexpected lockless error");
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_lock(tsdn, &a);
|
||||
witness_assert_lockless(tsdn);
|
||||
assert_true(saw_lockless_error, "Expected lockless error");
|
||||
|
||||
witness_unlock(tsdn, &a);
|
||||
|
||||
witness_assert_lockless(tsdn);
|
||||
|
||||
witness_lockless_error = witness_lockless_error_orig;
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_witness,
|
||||
test_witness_comp,
|
||||
test_witness_reversal,
|
||||
test_witness_recursive,
|
||||
test_witness_unlock_not_owned,
|
||||
test_witness_lockful));
|
||||
}
|
||||
80
memory/jemalloc/src/test/unit/zero.c
Normal file
80
memory/jemalloc/src/test/unit/zero.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "test/jemalloc_test.h"
|
||||
|
||||
#ifdef JEMALLOC_FILL
|
||||
const char *malloc_conf =
|
||||
"abort:false,junk:false,zero:true,redzone:false,quarantine:0";
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_zero(size_t sz_min, size_t sz_max)
|
||||
{
|
||||
uint8_t *s;
|
||||
size_t sz_prev, sz, i;
|
||||
#define MAGIC ((uint8_t)0x61)
|
||||
|
||||
sz_prev = 0;
|
||||
s = (uint8_t *)mallocx(sz_min, 0);
|
||||
assert_ptr_not_null((void *)s, "Unexpected mallocx() failure");
|
||||
|
||||
for (sz = sallocx(s, 0); sz <= sz_max;
|
||||
sz_prev = sz, sz = sallocx(s, 0)) {
|
||||
if (sz_prev > 0) {
|
||||
assert_u_eq(s[0], MAGIC,
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
ZU(0), sz_prev);
|
||||
assert_u_eq(s[sz_prev-1], MAGIC,
|
||||
"Previously allocated byte %zu/%zu is corrupted",
|
||||
sz_prev-1, sz_prev);
|
||||
}
|
||||
|
||||
for (i = sz_prev; i < sz; i++) {
|
||||
assert_u_eq(s[i], 0x0,
|
||||
"Newly allocated byte %zu/%zu isn't zero-filled",
|
||||
i, sz);
|
||||
s[i] = MAGIC;
|
||||
}
|
||||
|
||||
if (xallocx(s, sz+1, 0, 0) == sz) {
|
||||
s = (uint8_t *)rallocx(s, sz+1, 0);
|
||||
assert_ptr_not_null((void *)s,
|
||||
"Unexpected rallocx() failure");
|
||||
}
|
||||
}
|
||||
|
||||
dallocx(s, 0);
|
||||
#undef MAGIC
|
||||
}
|
||||
|
||||
TEST_BEGIN(test_zero_small)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(1, SMALL_MAXCLASS-1);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_zero_large)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(SMALL_MAXCLASS+1, large_maxclass);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
TEST_BEGIN(test_zero_huge)
|
||||
{
|
||||
|
||||
test_skip_if(!config_fill);
|
||||
test_zero(large_maxclass+1, chunksize*2);
|
||||
}
|
||||
TEST_END
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
return (test(
|
||||
test_zero_small,
|
||||
test_zero_large,
|
||||
test_zero_huge));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue