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
+ #ifndef _WIN32
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>
32
37
#define CTL_PROVIDER_TYPE os_memory_provider_t
33
38
#include "provider_ctl_stats_impl.h"
34
39
40
+ #define MAX_NUMNODES 1024
35
41
#define NODESET_STR_BUF_LEN 1024
36
-
37
42
#define TLS_MSG_BUF_LEN 1024
38
43
39
44
static const char * DEFAULT_NAME = "OS" ;
@@ -152,8 +157,42 @@ static umf_result_t initialize_nodeset(os_memory_provider_t *os_provider,
152
157
// Hwloc_set_area_membind fails if empty nodeset is passed so
153
158
// if no node is specified, just pass all available nodes.
154
159
// For modes where no node is needed, they will be ignored anyway.
160
+
161
+ #ifdef _WIN32
155
162
out_nodeset [0 ] = hwloc_bitmap_dup (
156
163
hwloc_topology_get_complete_nodeset (os_provider -> topo ));
164
+ #else
165
+ size_t * nodes = umf_ba_global_alloc (sizeof (size_t ) * MAX_NUMNODES );
166
+ if (!nodes ) {
167
+ umf_ba_global_free (out_nodeset );
168
+ os_provider -> nodeset_len = 0 ;
169
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
170
+ }
171
+
172
+ out_nodeset [0 ] = hwloc_bitmap_alloc ();
173
+ if (!out_nodeset [0 ]) {
174
+ umf_ba_global_free (out_nodeset );
175
+ umf_ba_global_free (nodes );
176
+ os_provider -> nodeset_len = 0 ;
177
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
178
+ }
179
+
180
+ size_t num = 0 ;
181
+ int ret = utils_get_complete_nodeset (nodes , MAX_NUMNODES , & num );
182
+ if (ret < 0 ) {
183
+ hwloc_bitmap_free (out_nodeset [0 ]);
184
+ umf_ba_global_free (out_nodeset );
185
+ umf_ba_global_free (nodes );
186
+ os_provider -> nodeset_len = 0 ;
187
+ return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
188
+ }
189
+
190
+ for (size_t i = 0 ; i < num ; i ++ ) {
191
+ hwloc_bitmap_set (out_nodeset [0 ], (int )nodes [i ]);
192
+ }
193
+ umf_ba_global_free (nodes );
194
+ #endif
195
+
157
196
if (!out_nodeset [0 ]) {
158
197
goto err_free_list ;
159
198
}
@@ -518,6 +557,12 @@ translate_params(const umf_os_memory_provider_params_t *in_params,
518
557
519
558
provider -> numa_flags =
520
559
getHwlocMembindFlags (in_params -> numa_mode , is_dedicated_node_bind );
560
+
561
+ #ifndef _WIN32
562
+ provider -> umf_numa_mode = in_params -> numa_mode ;
563
+ provider -> dedicated = is_dedicated_node_bind ;
564
+ #endif
565
+
521
566
provider -> mode = in_params -> numa_mode ;
522
567
provider -> part_size = in_params -> part_size ;
523
568
@@ -561,21 +606,34 @@ static umf_result_t os_initialize(const void *params, void **provider) {
561
606
snprintf (os_provider -> name , sizeof (os_provider -> name ), "%s" ,
562
607
in_params -> name );
563
608
564
- int r = hwloc_topology_init (& os_provider -> topo );
565
- if (r ) {
566
- LOG_ERR ("HWLOC topology init failed" );
567
- ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
568
- goto err_free_os_provider ;
569
- }
570
-
571
- r = hwloc_topology_load (os_provider -> topo );
572
- if (r ) {
573
- os_store_last_native_error (UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED ,
574
- 0 );
575
- LOG_ERR ("HWLOC topology discovery failed" );
576
- ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
577
- goto err_destroy_hwloc_topology ;
578
- }
609
+ //struct timespec ts_init_start, ts_init_end;
610
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_start);
611
+
612
+ //int r = hwloc_topology_init(&os_provider->topo);
613
+ //if (r) {
614
+ // LOG_ERR("HWLOC topology init failed");
615
+ // ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
616
+ // goto err_free_os_provider;
617
+ //}
618
+
619
+ //hwloc_topology_set_all_types_filter(os_provider->topo,
620
+ // HWLOC_TYPE_FILTER_KEEP_NONE);
621
+ //hwloc_topology_set_type_filter(os_provider->topo, HWLOC_OBJ_CORE,
622
+ // HWLOC_TYPE_FILTER_KEEP_ALL);
623
+
624
+ //r = hwloc_topology_load(os_provider->topo);
625
+ //if (r) {
626
+ // os_store_last_native_error(UMF_OS_RESULT_ERROR_TOPO_DISCOVERY_FAILED,
627
+ // 0);
628
+ // LOG_ERR("HWLOC topology discovery failed");
629
+ // ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC;
630
+ // goto err_destroy_hwloc_topology;
631
+ //}
632
+
633
+ //clock_gettime(CLOCK_MONOTONIC, &ts_init_end);
634
+ //LOG_FATAL("HWLOC topology initialized in %ld.%09ld seconds",
635
+ // ts_init_end.tv_sec - ts_init_start.tv_sec,
636
+ // ts_init_end.tv_nsec - ts_init_start.tv_nsec);
579
637
580
638
os_provider -> fd_offset_map = critnib_new (NULL , NULL );
581
639
if (!os_provider -> fd_offset_map ) {
@@ -625,8 +683,10 @@ static umf_result_t os_initialize(const void *params, void **provider) {
625
683
err_destroy_critnib :
626
684
critnib_delete (os_provider -> fd_offset_map );
627
685
err_destroy_hwloc_topology :
686
+ #ifdef _WIN32
628
687
hwloc_topology_destroy (os_provider -> topo );
629
688
err_free_os_provider :
689
+ #endif
630
690
umf_ba_global_free (os_provider );
631
691
return ret ;
632
692
}
@@ -649,7 +709,9 @@ static umf_result_t os_finalize(void *provider) {
649
709
if (os_provider -> nodeset_str_buf ) {
650
710
umf_ba_global_free (os_provider -> nodeset_str_buf );
651
711
}
712
+ #ifdef _WIN32
652
713
hwloc_topology_destroy (os_provider -> topo );
714
+ #endif
653
715
umf_ba_global_free (os_provider );
654
716
return UMF_RESULT_SUCCESS ;
655
717
}
@@ -1012,10 +1074,52 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
1012
1074
1013
1075
do {
1014
1076
errno = 0 ;
1077
+ ret = 0 ;
1078
+
1079
+ #ifdef _WIN32
1015
1080
ret = hwloc_set_area_membind (os_provider -> topo , membind .addr ,
1016
1081
membind .bind_size , membind .bitmap ,
1017
1082
os_provider -> numa_policy ,
1018
1083
os_provider -> numa_flags );
1084
+ #else // !_WIN32
1085
+
1086
+ // NOTE: could we done this
1087
+
1088
+ // on Linux, use mbind syscall directly instead of hwloc
1089
+ unsigned long nodemask = 0 ;
1090
+ int maxnode = 8 * sizeof (nodemask ); // up to 64 nodes
1091
+ if (membind .bitmap ) {
1092
+ for (int i = 0 ; i < maxnode ; ++ i ) {
1093
+ if (hwloc_bitmap_isset (membind .bitmap , i )) {
1094
+ nodemask |= (1UL << i );
1095
+ }
1096
+ }
1097
+ }
1098
+
1099
+ int mbind_mode = MPOL_DEFAULT ;
1100
+ if (os_provider -> umf_numa_mode == UMF_NUMA_MODE_INTERLEAVE &&
1101
+ os_provider -> dedicated == 0 ) {
1102
+ mbind_mode = MPOL_INTERLEAVE ;
1103
+ } else if (os_provider -> umf_numa_mode == UMF_NUMA_MODE_SPLIT ) {
1104
+ mbind_mode = MPOL_BIND ;
1105
+ } else if (os_provider -> umf_numa_mode == UMF_NUMA_MODE_LOCAL ) {
1106
+ mbind_mode = MPOL_LOCAL ;
1107
+ nodemask = 0 ;
1108
+ } else if (os_provider -> umf_numa_mode == UMF_NUMA_MODE_PREFERRED ) {
1109
+ mbind_mode = MPOL_BIND ;
1110
+ } else if (os_provider -> umf_numa_mode == UMF_NUMA_MODE_BIND ||
1111
+ os_provider -> dedicated ) {
1112
+ mbind_mode = MPOL_BIND ;
1113
+ }
1114
+
1115
+ unsigned long mbind_flags = 0 ;
1116
+ if (os_provider -> dedicated ) {
1117
+ mbind_flags |= MPOL_MF_STRICT ;
1118
+ }
1119
+
1120
+ ret = syscall (__NR_mbind , membind .addr , membind .bind_size ,
1121
+ mbind_mode , & nodemask , maxnode , mbind_flags );
1122
+ #endif // !_WIN32
1019
1123
1020
1124
if (ret ) {
1021
1125
os_store_last_native_error (UMF_OS_RESULT_ERROR_BIND_FAILED ,
0 commit comments