mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Make malloc scalable on all platforms
It turns out sched_getcpu() didn't work on many platforms. So the system call now has tests and is well documented. We now employ new workarounds on platforms where it isn't supported in our malloc() implementation. It was previously the case that malloc() was only scalable on Linux/Windows for x86-64. Now the other platforms are scalable too.
This commit is contained in:
parent
3fd275f59f
commit
0a79c6961f
9 changed files with 459 additions and 99 deletions
|
@ -30,39 +30,63 @@
|
|||
|
||||
int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache);
|
||||
|
||||
/**
|
||||
* Determines ID of CPU on which thread is currently scheduled.
|
||||
*
|
||||
* This is the same as sched_getcpu(), except it also supports returning
|
||||
* the ID of the current NUMA node. On some platforms this functionality
|
||||
* isn't available, in which case `out_opt_node` is always be set to 0.
|
||||
*/
|
||||
int getcpu(unsigned *out_opt_cpu, unsigned *out_opt_node) {
|
||||
unsigned cpu;
|
||||
unsigned node;
|
||||
if (X86_HAVE(RDTSCP)) {
|
||||
|
||||
if (IsWindows()) {
|
||||
struct NtProcessorNumber pn;
|
||||
if (out_opt_cpu) {
|
||||
GetCurrentProcessorNumberEx(&pn);
|
||||
*out_opt_cpu = 64 * pn.Group + pn.Number;
|
||||
}
|
||||
if (out_opt_node) {
|
||||
unsigned short node16;
|
||||
if (GetNumaProcessorNodeEx(&pn, &node16)) {
|
||||
*out_opt_node = node16;
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
if (X86_HAVE(RDTSCP) && (IsLinux() || IsFreebsd())) {
|
||||
unsigned tsc_aux;
|
||||
rdtscp(&tsc_aux);
|
||||
cpu = TSC_AUX_CORE(tsc_aux);
|
||||
node = TSC_AUX_NODE(tsc_aux);
|
||||
} else if (IsWindows()) {
|
||||
struct NtProcessorNumber pn;
|
||||
GetCurrentProcessorNumberEx(&pn);
|
||||
cpu = 64 * pn.Group + pn.Number;
|
||||
unsigned short node16;
|
||||
if (GetNumaProcessorNodeEx(&pn, &node16)) {
|
||||
node = node16;
|
||||
} else {
|
||||
return __winerr();
|
||||
if (out_opt_cpu)
|
||||
*out_opt_cpu = TSC_AUX_CORE(tsc_aux);
|
||||
if (out_opt_node)
|
||||
*out_opt_node = TSC_AUX_NODE(tsc_aux);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IsXnu() || IsOpenbsd() || IsNetbsd() || IsFreebsd()) {
|
||||
if (out_opt_cpu) {
|
||||
int rc = sched_getcpu();
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
*out_opt_cpu = rc;
|
||||
}
|
||||
} else if (IsAarch64()) {
|
||||
long tpidr_el0;
|
||||
asm("mrs\t%0,tpidr_el0" : "=r"(tpidr_el0));
|
||||
cpu = tpidr_el0 & 255;
|
||||
node = 0;
|
||||
} else {
|
||||
int rc = sys_getcpu(&cpu, &node, 0);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
if (out_opt_node)
|
||||
*out_opt_node = 0;
|
||||
return 0;
|
||||
}
|
||||
if (out_opt_cpu) {
|
||||
|
||||
unsigned cpu, node;
|
||||
int rc = sys_getcpu(&cpu, &node, 0);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
if (out_opt_cpu)
|
||||
*out_opt_cpu = cpu;
|
||||
}
|
||||
if (out_opt_node) {
|
||||
if (out_opt_node)
|
||||
*out_opt_node = node;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue