1 1.1 christos #ifndef JEMALLOC_INTERNAL_DIV_H 2 1.1 christos #define JEMALLOC_INTERNAL_DIV_H 3 1.1 christos 4 1.1 christos #include "jemalloc/internal/assert.h" 5 1.1 christos 6 1.1 christos /* 7 1.1 christos * This module does the division that computes the index of a region in a slab, 8 1.1 christos * given its offset relative to the base. 9 1.1 christos * That is, given a divisor d, an n = i * d (all integers), we'll return i. 10 1.1 christos * We do some pre-computation to do this more quickly than a CPU division 11 1.1 christos * instruction. 12 1.1 christos * We bound n < 2^32, and don't support dividing by one. 13 1.1 christos */ 14 1.1 christos 15 1.1 christos typedef struct div_info_s div_info_t; 16 1.1 christos struct div_info_s { 17 1.1 christos uint32_t magic; 18 1.1 christos #ifdef JEMALLOC_DEBUG 19 1.1 christos size_t d; 20 1.1 christos #endif 21 1.1 christos }; 22 1.1 christos 23 1.1 christos void div_init(div_info_t *div_info, size_t divisor); 24 1.1 christos 25 1.1 christos static inline size_t 26 1.1 christos div_compute(div_info_t *div_info, size_t n) { 27 1.1 christos assert(n <= (uint32_t)-1); 28 1.1 christos /* 29 1.1 christos * This generates, e.g. mov; imul; shr on x86-64. On a 32-bit machine, 30 1.1 christos * the compilers I tried were all smart enough to turn this into the 31 1.1 christos * appropriate "get the high 32 bits of the result of a multiply" (e.g. 32 1.1 christos * mul; mov edx eax; on x86, umull on arm, etc.). 33 1.1 christos */ 34 1.1 christos size_t i = ((uint64_t)n * (uint64_t)div_info->magic) >> 32; 35 1.1 christos #ifdef JEMALLOC_DEBUG 36 1.1 christos assert(i * div_info->d == n); 37 1.1 christos #endif 38 1.1 christos return i; 39 1.1 christos } 40 1.1 christos 41 1.1 christos #endif /* JEMALLOC_INTERNAL_DIV_H */ 42