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