From: Damjan Jovanovic damjan.jov@gmail.com
Add hwloc as a dependency, and use it to retrieve CPU and cache topology info on FreeBSD. --- configure.ac | 15 ++++ dlls/ntdll/Makefile.in | 4 +- dlls/ntdll/unix/system.c | 143 +++++++++++++++++++++++++++++++++++++++ include/config.h.in | 3 + 4 files changed, 163 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac index 51572bdae66..fda3147252d 100644 --- a/configure.ac +++ b/configure.ac @@ -40,6 +40,7 @@ AC_ARG_WITH(gphoto, AS_HELP_STRING([--without-gphoto],[do not use gphoto (Dig AC_ARG_WITH(gnutls, AS_HELP_STRING([--without-gnutls],[do not use GnuTLS (schannel support)])) AC_ARG_WITH(gssapi, AS_HELP_STRING([--without-gssapi],[do not use GSSAPI (Kerberos SSP support)])) AC_ARG_WITH(gstreamer, AS_HELP_STRING([--without-gstreamer],[do not use GStreamer (codecs support)])) +AC_ARG_WITH(hwloc, AS_HELP_STRING([--without-hwloc],[do not use hwloc (CPU/cache topology detection)])) AC_ARG_WITH(inotify, AS_HELP_STRING([--without-inotify],[do not use inotify (filesystem change notifications)])) AC_ARG_WITH(krb5, AS_HELP_STRING([--without-krb5],[do not use krb5 (Kerberos)])) AC_ARG_WITH(mingw, AS_HELP_STRING([--without-mingw],[do not use the MinGW cross-compiler])) @@ -1519,6 +1520,20 @@ fi WINE_WARNING_WITH(gnutls,[test "x$ac_cv_lib_soname_gnutls" = "x"], [libgnutls ${notice_platform}development files not found, no schannel support.])
+dnl **** Check for hwloc *** +if test "x$with_hwloc" != "xno" -a `expr "$host_os" : '(freebsd).*'` = "freebsd" +then + WINE_PACKAGE_FLAGS(HWLOC,[hwloc],,,, + [AC_CHECK_HEADER([hwloc.h], + [AC_CHECK_LIB(hwloc,hwloc_topology_init, + [AC_DEFINE(HAVE_LIBHWLOC, 1, [Define to 1 if you have the 'hwloc' library (-lhwloc).])], + [HWLOC_LIBS=""], + [$HWLOC_LIBS])], + [HWLOC_LIBS=""])]) + WINE_NOTICE_WITH(hwloc,[test "$ac_cv_lib_hwloc_hwloc_topology_init" != "yes"], + [hwloc ${notice_platform}development files not found, detailed CPU info on FreeBSD won't be supported.]) +fi + dnl **** Check for SANE **** if test "x$with_sane" != "xno" then diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in index f7558bb5d86..3c0dfa7a895 100644 --- a/dlls/ntdll/Makefile.in +++ b/dlls/ntdll/Makefile.in @@ -4,8 +4,8 @@ UNIXLIB = ntdll.so IMPORTLIB = ntdll IMPORTS = $(TOMCRYPT_PE_LIBS) $(MUSL_PE_LIBS) EXTRAINCL = $(TOMCRYPT_PE_CFLAGS) -UNIX_CFLAGS = $(UNWIND_CFLAGS) -UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS) +UNIX_CFLAGS = $(UNWIND_CFLAGS) $(HWLOC_CFLAGS) +UNIX_LIBS = $(IOKIT_LIBS) $(COREFOUNDATION_LIBS) $(CORESERVICES_LIBS) $(RT_LIBS) $(PTHREAD_LIBS) $(UNWIND_LIBS) $(I386_LIBS) $(PROCSTAT_LIBS) $(HWLOC_LIBS)
EXTRADLLFLAGS = -nodefaultlibs i386_EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000 diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 342e443f5e7..2bfb9b414b5 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -69,6 +69,10 @@ # include <mach/vm_map.h> #endif
+#if defined(HAVE_LIBHWLOC) +# include <hwloc.h> +#endif + #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -1339,6 +1343,145 @@ static NTSTATUS create_logical_proc_info(void) return STATUS_SUCCESS; }
+#elif defined(__FreeBSD__) || defined(__FreeBSD__kernel__) + +#if defined(HAVE_LIBHWLOC) +static NTSTATUS add_hwloc_cache(hwloc_obj_t obj, int level) +{ + CACHE_DESCRIPTOR cache; + + memset(&cache, 0, sizeof(cache)); + cache.Level = level; + if (obj->attr) + { + cache.Associativity = obj->attr->cache.associativity; + cache.LineSize = obj->attr->cache.linesize; + cache.Size = obj->attr->cache.size; + switch (obj->attr->cache.type) + { + case HWLOC_OBJ_CACHE_UNIFIED: + cache.Type = CacheUnified; + break; + case HWLOC_OBJ_CACHE_DATA: + cache.Type = CacheData; + break; + case HWLOC_OBJ_CACHE_INSTRUCTION: + cache.Type = CacheInstruction; + break; + default: + break; + } + } + if (!logical_proc_info_add_cache(hwloc_bitmap_to_ulong(obj->cpuset), &cache)) + return STATUS_NO_MEMORY; + return STATUS_SUCCESS; +} + +static NTSTATUS add_hwloc_numa_nodes(hwloc_topology_t topology) +{ + hwloc_obj_t obj; + + for (obj = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 0); obj != NULL; obj = obj->next_cousin) + { + if (!logical_proc_info_add_numa_node(obj->logical_index, hwloc_bitmap_to_ulong(obj->cpuset))) + return STATUS_NO_MEMORY; + } + return STATUS_SUCCESS; +} + +static NTSTATUS traverse_hwloc_topology(hwloc_obj_t obj) +{ + int i; + NTSTATUS nt_status = STATUS_SUCCESS; + + switch (obj->type) + { + case HWLOC_OBJ_PACKAGE: + if (!logical_proc_info_add_by_id(RelationProcessorPackage, obj->logical_index, hwloc_bitmap_to_ulong(obj->cpuset))) + return STATUS_NO_MEMORY; + break; + case HWLOC_OBJ_CORE: + if (!logical_proc_info_add_by_id(RelationProcessorCore, obj->logical_index, hwloc_bitmap_to_ulong(obj->cpuset))) + return STATUS_NO_MEMORY; + break; + case HWLOC_OBJ_L1CACHE: + case HWLOC_OBJ_L1ICACHE: + nt_status = add_hwloc_cache(obj, 1); + break; + case HWLOC_OBJ_L2CACHE: + case HWLOC_OBJ_L2ICACHE: + nt_status = add_hwloc_cache(obj, 2); + break; + case HWLOC_OBJ_L3CACHE: + case HWLOC_OBJ_L3ICACHE: + nt_status = add_hwloc_cache(obj, 3); + break; + case HWLOC_OBJ_L4CACHE: + nt_status = add_hwloc_cache(obj, 4); + break; + case HWLOC_OBJ_L5CACHE: + nt_status = add_hwloc_cache(obj, 5); + break; + default: + break; + } + + for (i = 0; i < obj->arity && nt_status == STATUS_SUCCESS; i++) + nt_status = traverse_hwloc_topology(obj->children[i]); + return nt_status; +} +#endif + +static NTSTATUS create_logical_proc_info(void) +{ +#if defined(HAVE_LIBHWLOC) + NTSTATUS nt_status = STATUS_SUCCESS; + int ret; + hwloc_topology_t topology; + hwloc_obj_t root_obj; + + ret = hwloc_topology_init(&topology); + if (ret != 0) + return STATUS_NO_MEMORY; + + hwloc_topology_set_icache_types_filter(topology, HWLOC_TYPE_FILTER_KEEP_ALL); + ret = hwloc_topology_load(topology); + if (ret != 0) + { + nt_status = STATUS_NO_MEMORY; + goto end; + } + + root_obj = hwloc_get_root_obj(topology); + if (root_obj == NULL) + { + nt_status = STATUS_NO_MEMORY; + goto end; + } + + nt_status = traverse_hwloc_topology(root_obj); + if (nt_status != STATUS_SUCCESS) + goto end; + + nt_status = add_hwloc_numa_nodes(topology); + if (nt_status != STATUS_SUCCESS) + goto end; + + if (!logical_proc_info_add_group(hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PU), hwloc_bitmap_to_ulong(root_obj->cpuset))) + { + nt_status = STATUS_NO_MEMORY; + goto end; + } + +end: + hwloc_topology_destroy(topology); + return nt_status; +#else + FIXME("hwloc unavailable, cannot detect CPU/cache topology info\n"); + return STATUS_NOT_IMPLEMENTED; +#endif +} + #else
static NTSTATUS create_logical_proc_info(void) diff --git a/include/config.h.in b/include/config.h.in index b5b57d8fd7b..f344446bae1 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -138,6 +138,9 @@ /* Define to 1 if you have the 'gettextpo' library (-lgettextpo). */ #undef HAVE_LIBGETTEXTPO
+/* Define to 1 if you have the 'hwloc' library (-lhwloc). */ +#undef HAVE_LIBHWLOC + /* Define to 1 if you have the 'procstat' library (-lprocstat). */ #undef HAVE_LIBPROCSTAT