8
8
#include <assert.h>
9
9
#include <errno.h>
10
10
#include <limits.h>
11
-
12
11
#include <stddef.h>
13
12
#include <stdio.h>
14
13
#include <stdlib.h>
15
14
#include <string.h>
15
+
16
+ #if !defined(_WIN32 ) && !defined(__APPLE__ )
17
+ #include <numaif.h>
18
+ #include <sys/syscall.h>
19
+ #endif
20
+
16
21
#include <umf.h>
17
22
#include <umf/base.h>
18
23
#include <umf/memory_provider.h>
24
29
#include "ctl/ctl_internal.h"
25
30
#include "libumf.h"
26
31
#include "provider_os_memory_internal.h"
32
+ #include "topology.h"
27
33
#include "utils_assert.h"
28
34
#include "utils_common.h"
29
35
#include "utils_concurrency.h"
32
38
#define CTL_PROVIDER_TYPE os_memory_provider_t
33
39
#include "provider_ctl_stats_impl.h"
34
40
41
+ #define MAX_NUMNODES 1024
35
42
#define NODESET_STR_BUF_LEN 1024
36
-
37
43
#define TLS_MSG_BUF_LEN 1024
38
44
39
45
static const char * DEFAULT_NAME = "OS" ;
@@ -152,8 +158,14 @@ static umf_result_t initialize_nodeset(os_memory_provider_t *os_provider,
152
158
// Hwloc_set_area_membind fails if empty nodeset is passed so
153
159
// if no node is specified, just pass all available nodes.
154
160
// For modes where no node is needed, they will be ignored anyway.
161
+
162
+ #if defined(_WIN32 ) || defined(__APPLE__ )
155
163
out_nodeset [0 ] = hwloc_bitmap_dup (
156
164
hwloc_topology_get_complete_nodeset (os_provider -> topo ));
165
+ #else
166
+ out_nodeset [0 ] = hwloc_bitmap_dup (umfGetTopology2 ());
167
+ #endif
168
+
157
169
if (!out_nodeset [0 ]) {
158
170
goto err_free_list ;
159
171
}
@@ -518,6 +530,11 @@ translate_params(const umf_os_memory_provider_params_t *in_params,
518
530
519
531
provider -> numa_flags =
520
532
getHwlocMembindFlags (in_params -> numa_mode , is_dedicated_node_bind );
533
+
534
+ #if !defined(_WIN32 ) && !defined(__APPLE__ )
535
+ provider -> dedicated = is_dedicated_node_bind ;
536
+ #endif
537
+
521
538
provider -> mode = in_params -> numa_mode ;
522
539
provider -> part_size = in_params -> part_size ;
523
540
@@ -561,6 +578,11 @@ static umf_result_t os_initialize(const void *params, void **provider) {
561
578
snprintf (os_provider -> name , sizeof (os_provider -> name ), "%s" ,
562
579
in_params -> name );
563
580
581
+ #if defined(_WIN32 ) || defined(__APPLE__ )
582
+
583
+ //struct timespec ts_init_start, ts_init_end;
584
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_start);
585
+
564
586
int r = hwloc_topology_init (& os_provider -> topo );
565
587
if (r ) {
566
588
LOG_ERR ("HWLOC topology init failed" );
@@ -577,6 +599,13 @@ static umf_result_t os_initialize(const void *params, void **provider) {
577
599
goto err_destroy_hwloc_topology ;
578
600
}
579
601
602
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_end);
603
+ //LOG_FATAL("HWLOC topology initialized in %ld.%09ld seconds",
604
+ // ts_init_end.tv_sec - ts_init_start.tv_sec,
605
+ // ts_init_end.tv_nsec - ts_init_start.tv_nsec);
606
+
607
+ #endif // _WIN32
608
+
580
609
os_provider -> fd_offset_map = critnib_new (NULL , NULL );
581
610
if (!os_provider -> fd_offset_map ) {
582
611
LOG_ERR ("creating file descriptor offset map failed" );
@@ -625,8 +654,11 @@ static umf_result_t os_initialize(const void *params, void **provider) {
625
654
err_destroy_critnib :
626
655
critnib_delete (os_provider -> fd_offset_map );
627
656
err_destroy_hwloc_topology :
657
+
658
+ #if defined(_WIN32 ) || defined(__APPLE__ )
628
659
hwloc_topology_destroy (os_provider -> topo );
629
660
err_free_os_provider :
661
+ #endif
630
662
umf_ba_global_free (os_provider );
631
663
return ret ;
632
664
}
@@ -649,7 +681,10 @@ static umf_result_t os_finalize(void *provider) {
649
681
if (os_provider -> nodeset_str_buf ) {
650
682
umf_ba_global_free (os_provider -> nodeset_str_buf );
651
683
}
684
+
685
+ #if defined(_WIN32 ) || defined(__APPLE__ )
652
686
hwloc_topology_destroy (os_provider -> topo );
687
+ #endif
653
688
umf_ba_global_free (os_provider );
654
689
return UMF_RESULT_SUCCESS ;
655
690
}
@@ -1012,10 +1047,52 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
1012
1047
1013
1048
do {
1014
1049
errno = 0 ;
1050
+ ret = 0 ;
1051
+
1052
+ #if defined(_WIN32 ) || defined(__APPLE__ )
1015
1053
ret = hwloc_set_area_membind (os_provider -> topo , membind .addr ,
1016
1054
membind .bind_size , membind .bitmap ,
1017
1055
os_provider -> numa_policy ,
1018
1056
os_provider -> numa_flags );
1057
+ #else // !_WIN32 && !_APPLE__
1058
+
1059
+ // NOTE: could we done this
1060
+
1061
+ // on Linux, use mbind syscall directly instead of hwloc
1062
+ unsigned long nodemask = 0 ;
1063
+ int maxnode = 8 * sizeof (nodemask ); // up to 64 nodes
1064
+ if (membind .bitmap ) {
1065
+ for (int i = 0 ; i < maxnode ; ++ i ) {
1066
+ if (hwloc_bitmap_isset (membind .bitmap , i )) {
1067
+ nodemask |= (1UL << i );
1068
+ }
1069
+ }
1070
+ }
1071
+
1072
+ int mbind_mode = MPOL_DEFAULT ;
1073
+ if (os_provider -> mode == UMF_NUMA_MODE_INTERLEAVE &&
1074
+ os_provider -> dedicated == 0 ) {
1075
+ mbind_mode = MPOL_INTERLEAVE ;
1076
+ } else if (os_provider -> mode == UMF_NUMA_MODE_SPLIT ) {
1077
+ mbind_mode = MPOL_BIND ;
1078
+ } else if (os_provider -> mode == UMF_NUMA_MODE_LOCAL ) {
1079
+ mbind_mode = MPOL_LOCAL ;
1080
+ nodemask = 0 ;
1081
+ } else if (os_provider -> mode == UMF_NUMA_MODE_PREFERRED ) {
1082
+ mbind_mode = MPOL_BIND ;
1083
+ } else if (os_provider -> mode == UMF_NUMA_MODE_BIND ||
1084
+ os_provider -> dedicated ) {
1085
+ mbind_mode = MPOL_BIND ;
1086
+ }
1087
+
1088
+ unsigned long mbind_flags = 0 ;
1089
+ if (os_provider -> dedicated ) {
1090
+ mbind_flags |= MPOL_MF_STRICT ;
1091
+ }
1092
+
1093
+ ret = syscall (__NR_mbind , membind .addr , membind .bind_size ,
1094
+ mbind_mode , & nodemask , maxnode , mbind_flags );
1095
+ #endif // !_WIN32 && !_APPLE__
1019
1096
1020
1097
if (ret ) {
1021
1098
os_store_last_native_error (UMF_OS_RESULT_ERROR_BIND_FAILED ,
0 commit comments