mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-08 00:09:31 +03:00
merge with dev-exp
This commit is contained in:
commit
e0b8ec7f54
3 changed files with 16 additions and 39 deletions
|
@ -432,7 +432,6 @@ typedef struct mi_segments_tld_s {
|
||||||
// OS thread local data
|
// OS thread local data
|
||||||
typedef struct mi_os_tld_s {
|
typedef struct mi_os_tld_s {
|
||||||
size_t region_idx; // start point for next allocation
|
size_t region_idx; // start point for next allocation
|
||||||
int numa_node; // numa node associated with this thread
|
|
||||||
mi_stats_t* stats; // points to tld stats
|
mi_stats_t* stats; // points to tld stats
|
||||||
} mi_os_tld_t;
|
} mi_os_tld_t;
|
||||||
|
|
||||||
|
|
|
@ -109,8 +109,8 @@ static const mi_tld_t tld_empty = {
|
||||||
false,
|
false,
|
||||||
NULL,
|
NULL,
|
||||||
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, 0, NULL, tld_empty_stats }, // segments
|
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, 0, NULL, tld_empty_stats }, // segments
|
||||||
{ 0, -1, tld_empty_stats }, // os
|
{ 0, tld_empty_stats }, // os
|
||||||
{ MI_STATS_NULL } // stats
|
{ MI_STATS_NULL } // stats
|
||||||
};
|
};
|
||||||
|
|
||||||
mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
|
mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
|
||||||
|
@ -123,8 +123,8 @@ static mi_tld_t tld_main = {
|
||||||
0, false,
|
0, false,
|
||||||
&_mi_heap_main,
|
&_mi_heap_main,
|
||||||
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, 0, NULL, tld_main_stats }, // segments
|
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, 0, NULL, tld_main_stats }, // segments
|
||||||
{ 0, -1, tld_main_stats }, // os
|
{ 0, tld_main_stats }, // os
|
||||||
{ MI_STATS_NULL } // stats
|
{ MI_STATS_NULL } // stats
|
||||||
};
|
};
|
||||||
|
|
||||||
mi_heap_t _mi_heap_main = {
|
mi_heap_t _mi_heap_main = {
|
||||||
|
@ -242,7 +242,6 @@ static bool _mi_heap_init(void) {
|
||||||
heap->tld = tld;
|
heap->tld = tld;
|
||||||
tld->heap_backing = heap;
|
tld->heap_backing = heap;
|
||||||
tld->segments.stats = &tld->stats;
|
tld->segments.stats = &tld->stats;
|
||||||
tld->os.numa_node = -1;
|
|
||||||
tld->os.stats = &tld->stats;
|
tld->os.stats = &tld->stats;
|
||||||
_mi_heap_default = heap;
|
_mi_heap_default = heap;
|
||||||
}
|
}
|
||||||
|
|
45
src/os.c
45
src/os.c
|
@ -902,29 +902,21 @@ static int mi_os_numa_node_countx(void) {
|
||||||
GetNumaHighestNodeNumber(&numa_max);
|
GetNumaHighestNodeNumber(&numa_max);
|
||||||
return (int)(numa_max + 1);
|
return (int)(numa_max + 1);
|
||||||
}
|
}
|
||||||
#elif MI_HAS_NUMA
|
#elif defined(__linux__)
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <numaif.h>
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
static int mi_os_numa_nodex(void) {
|
static int mi_os_numa_nodex(void) {
|
||||||
#define MI_NUMA_NODE_SLOW // too slow, so cache it
|
#ifdef SYS_getcpu
|
||||||
// TODO: perhaps use RDTSCP instruction on x64?
|
unsigned node = 0;
|
||||||
// see <https://stackoverflow.com/questions/16862620/numa-get-current-node-core>
|
unsigned ncpu = 0;
|
||||||
#define MI_MAX_MASK (4) // support at most 256 nodes
|
int err = syscall(SYS_getcpu, &ncpu, &node, NULL);
|
||||||
unsigned long mask[MI_MAX_MASK];
|
|
||||||
memset(mask,0,MI_MAX_MASK*sizeof(long));
|
|
||||||
int mode = 0;
|
|
||||||
long err = get_mempolicy(&mode, mask, MI_MAX_MASK*sizeof(long)*8, NULL, 0 /* thread policy */);
|
|
||||||
if (err != 0) return 0;
|
if (err != 0) return 0;
|
||||||
// find the lowest bit that is set
|
return (int)node;
|
||||||
for(int i = 0; i < MI_MAX_MASK; i++) {
|
#else
|
||||||
for(int j = 0; j < (int)(sizeof(long)*8); j++) {
|
return 0;
|
||||||
if ((mask[i] & (1UL << j)) != 0) {
|
#endif
|
||||||
return (i*sizeof(long)*8 + j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mi_os_numa_node_countx(void) {
|
static int mi_os_numa_node_countx(void) {
|
||||||
|
@ -967,21 +959,8 @@ int _mi_os_numa_node_count(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int _mi_os_numa_node(mi_os_tld_t* tld) {
|
int _mi_os_numa_node(mi_os_tld_t* tld) {
|
||||||
int numa_node;
|
|
||||||
#ifndef MI_NUMA_NODE_SLOW
|
|
||||||
UNUSED(tld);
|
UNUSED(tld);
|
||||||
numa_node = mi_os_numa_nodex();
|
int numa_node = mi_os_numa_nodex();
|
||||||
#else
|
|
||||||
if (mi_unlikely(tld->numa_node < 0)) {
|
|
||||||
// Cache the NUMA node of the thread if the call is slow.
|
|
||||||
// This may not be correct as threads can migrate to another cpu on
|
|
||||||
// another node -- however, for memory allocation this just means we keep
|
|
||||||
// using the same 'node id' for its allocations; new OS allocations
|
|
||||||
// naturally come from the actual node so in practice this may be fine.
|
|
||||||
tld->numa_node = mi_os_numa_nodex();
|
|
||||||
}
|
|
||||||
numa_node = tld->numa_node;
|
|
||||||
#endif
|
|
||||||
// never more than the node count and >= 0
|
// never more than the node count and >= 0
|
||||||
int numa_count = _mi_os_numa_node_count();
|
int numa_count = _mi_os_numa_node_count();
|
||||||
if (numa_node >= numa_count) { numa_node = numa_node % numa_count; }
|
if (numa_node >= numa_count) { numa_node = numa_node % numa_count; }
|
||||||
|
|
Loading…
Add table
Reference in a new issue