mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-13 04:07:23 +03:00
Fix malloc_getcpu on macOS to read the current CPU number correctly
The Apple branch read the CPU number from the low 3 bits of `tpidrro_el0`. That layout no longer holds on Apple Silicon: those bits read back as 0, so `malloc_getcpu` returned 0 for every thread. `percpu_arena` then funneled all allocations into arena 0, or was disabled outright at init. Read the CPU number the same way as libplatform's `_os_cpu_number`: the low 12 bits of `tpidr_el0` on arm64, or of the IDT base (via `sidt`) on x86. Also move the Apple branch ahead of the `rdtscp` one so Apple x86 uses `sidt` rather than `rdtscp`, whose `ecx` is not the CPU id under XNU. https://github.com/apple-oss-distributions/xnu/blob/main/libsyscall/os/tsd.h Verified on a 12-CPU M2 Pro: with `percpu_arena:percpu`, `opt.percpu_arena` now stays `percpu` and `thread.arena` spreads across all 12 arenas {0..11}; the old code collapsed every thread onto arena 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b859093d28
commit
5aabbc87bf
1 changed files with 16 additions and 5 deletions
|
|
@ -18,15 +18,26 @@ malloc_getcpu(void) {
|
|||
return GetCurrentProcessorNumber();
|
||||
#elif defined(JEMALLOC_HAVE_SCHED_GETCPU)
|
||||
return (malloc_cpuid_t)sched_getcpu();
|
||||
#elif defined(__APPLE__)
|
||||
/* No sched_getcpu() on macOS; read the CPU number like _os_cpu_number(), see
|
||||
* https://github.com/apple-oss-distributions/xnu/blob/main/libsyscall/os/tsd.h
|
||||
* (it is no longer in tpidrro_el0's low bits on Apple Silicon). */
|
||||
# if defined(__aarch64__)
|
||||
uint64_t cpu;
|
||||
__asm__ __volatile__("mrs %0, tpidr_el0" : "=r"(cpu));
|
||||
return (malloc_cpuid_t)(cpu & 0xfff);
|
||||
# elif defined(__x86_64__) || defined(__i386__)
|
||||
struct { uintptr_t p1, p2; } idtr;
|
||||
__asm__ __volatile__("sidt %0" : "=m"(idtr));
|
||||
return (malloc_cpuid_t)(idtr.p1 & 0xfff);
|
||||
# else
|
||||
not_reached();
|
||||
return -1;
|
||||
# endif
|
||||
#elif defined(JEMALLOC_HAVE_RDTSCP)
|
||||
unsigned int ecx;
|
||||
asm volatile("rdtscp" : "=c"(ecx)::"eax", "edx");
|
||||
return (malloc_cpuid_t)(ecx & 0xfff);
|
||||
#elif defined(__aarch64__) && defined(__APPLE__)
|
||||
/* Other oses most likely use tpidr_el0 instead */
|
||||
uintptr_t c;
|
||||
asm volatile("mrs %x0, tpidrro_el0" : "=r"(c)::"memory");
|
||||
return (malloc_cpuid_t)(c & (1 << 3) - 1);
|
||||
#else
|
||||
not_reached();
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue