88#include <assert.h>
99#include <errno.h>
1010#include <limits.h>
11-
1211#include <stddef.h>
1312#include <stdio.h>
1413#include <stdlib.h>
1514#include <string.h>
15+
16+ #ifndef _WIN32
17+ #include <numaif.h>
18+ #include <sys/syscall.h>
19+ #endif
20+
1621#include <umf.h>
1722#include <umf/base.h>
1823#include <umf/memory_provider.h>
3237#define CTL_PROVIDER_TYPE os_memory_provider_t
3338#include "provider_ctl_stats_impl.h"
3439
40+ #define MAX_NUMNODES 1024
3541#define NODESET_STR_BUF_LEN 1024
36-
3742#define TLS_MSG_BUF_LEN 1024
3843
3944static const char * DEFAULT_NAME = "OS" ;
@@ -152,8 +157,42 @@ static umf_result_t initialize_nodeset(os_memory_provider_t *os_provider,
152157 // Hwloc_set_area_membind fails if empty nodeset is passed so
153158 // if no node is specified, just pass all available nodes.
154159 // For modes where no node is needed, they will be ignored anyway.
160+
161+ #ifdef _WIN32
155162 out_nodeset [0 ] = hwloc_bitmap_dup (
156163 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+
157196 if (!out_nodeset [0 ]) {
158197 goto err_free_list ;
159198 }
@@ -518,6 +557,12 @@ translate_params(const umf_os_memory_provider_params_t *in_params,
518557
519558 provider -> numa_flags =
520559 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+
521566 provider -> mode = in_params -> numa_mode ;
522567 provider -> part_size = in_params -> part_size ;
523568
@@ -561,21 +606,34 @@ static umf_result_t os_initialize(const void *params, void **provider) {
561606 snprintf (os_provider -> name , sizeof (os_provider -> name ), "%s" ,
562607 in_params -> name );
563608
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);
579637
580638 os_provider -> fd_offset_map = critnib_new (NULL , NULL );
581639 if (!os_provider -> fd_offset_map ) {
@@ -625,8 +683,10 @@ static umf_result_t os_initialize(const void *params, void **provider) {
625683err_destroy_critnib :
626684 critnib_delete (os_provider -> fd_offset_map );
627685err_destroy_hwloc_topology :
686+ #ifdef _WIN32
628687 hwloc_topology_destroy (os_provider -> topo );
629688err_free_os_provider :
689+ #endif
630690 umf_ba_global_free (os_provider );
631691 return ret ;
632692}
@@ -649,7 +709,9 @@ static umf_result_t os_finalize(void *provider) {
649709 if (os_provider -> nodeset_str_buf ) {
650710 umf_ba_global_free (os_provider -> nodeset_str_buf );
651711 }
712+ #ifdef _WIN32
652713 hwloc_topology_destroy (os_provider -> topo );
714+ #endif
653715 umf_ba_global_free (os_provider );
654716 return UMF_RESULT_SUCCESS ;
655717}
@@ -1012,10 +1074,52 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
10121074
10131075 do {
10141076 errno = 0 ;
1077+ ret = 0 ;
1078+
1079+ #ifdef _WIN32
10151080 ret = hwloc_set_area_membind (os_provider -> topo , membind .addr ,
10161081 membind .bind_size , membind .bitmap ,
10171082 os_provider -> numa_policy ,
10181083 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
10191123
10201124 if (ret ) {
10211125 os_store_last_native_error (UMF_OS_RESULT_ERROR_BIND_FAILED ,
0 commit comments