diff -Nru hardinfo-0.5.1+git20171103/benchmark.conf hardinfo-0.5.1+git20180227/benchmark.conf --- hardinfo-0.5.1+git20171103/benchmark.conf 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/benchmark.conf 2018-02-27 15:43:20.000000000 +0000 @@ -51,8 +51,6 @@ Intel(R) Pentium(R) 4 CPU 3.06GHz=7.454|2x 3065 MHz|Unknown AMD Processor model unknown=5.242|2x 3006 MHz|Unknown AMD Turion(tm) 64 X2 Mobile Technology TL-62=7.519|2x 800 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=11.97|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=114.42|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 [CPU CryptoHash] Intel(R) Atom(TM) CPU330 @ 1.60GHz=105.569|4x 1596 MHz|Unknown Intel(R) Core(TM)2 Duo CPU T5250@ 1.50GHz=102.949|2x 1000 MHz|Unknown @@ -104,8 +102,6 @@ Intel(R) Xeon(R) CPU3040@ 1.86GHz=127.825|2x 1862 MHz|Unknown AMD Athlon(tm) XP 2500+=39.659|1792 MHz|Unknown Intel(R) Core(TM)2 Duo CPU T9500@ 2.60GHz=172.640|2x 2593 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=98.27|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=11.70|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 [CPU N-Queens] AMD Athlon(tm) 64 X2 Dual Core Processor 5400+=15.057|2x 1000 MHz|Unknown Genuine Intel(R) CPU T2080@ 1.73GHz=33.309|2x 800 MHz|Unknown @@ -157,8 +153,6 @@ Intel(R) Core(TM)2 Duo CPU T5750@ 2.00GHz=11.140|2x 1994 MHz|Unknown Intel(R) Core(TM)2 Duo CPU T7250@ 2.00GHz=11.387|2x 2001 MHz|Unknown Intel(R) Pentium(R) 4 CPU 1500MHz=28.460|1495 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=22.83|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=65.80|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 [FPU Raytracing] Intel(R) Core(TM) Duo CPUT2450@ 2.00GHz=28.359|2x 800 MHz|Unknown AMD Athlon(tm) XP 2200+=29.739|1782 MHz|Unknown @@ -210,8 +204,6 @@ Intel(R) Celeron(R) CPU 2.80GHz=81.047|2793 MHz|Unknown Genuine Intel(R) CPU T1350@ 1.86GHz=222.178|1867 MHz|Unknown Intel(R) Pentium(R) 4 CPU 2.80GHz=28.658|2791 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=16.21|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=112.48|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 PowerPC 740/750=161.312647|280.00 MHz|Unknown [CPU Blowfish] Intel(R) Pentium(R) D CPU 3.00GHz=10.838|2x 3000 MHz|Unknown @@ -264,8 +256,6 @@ AMD Athlon(tm) 64 X2 Dual Core Processor 4800+=8.735|2x 2512 MHz|Unknown Intel(R) Celeron(R) M CPU520@ 1.60GHz=22.072|1600 MHz|Unknown Intel(R) Core(TM)2 Quad CPUQ8300@ 2.50GHz=3.346|4x 2497 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=10.41|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=77.47|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 PowerPC 740/750=172.816713|280.00 MHz|Unknown [CPU SHA1] [CPU MD5] @@ -320,12 +310,7 @@ AMD Athlon(tm)=4.475|2305 MHz|Unknown AMD Athlon(tm) X2 Dual Core Processor BE-2300=4.373|2x 1899 MHz|Unknown Intel(R) Core(TM)2 Duo CPU E6750@ 2.66GHz=4.096|2x 2671 MHz|Unknown -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=12.29|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=20.15|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 PowerPC 740/750=58.07682|280.00 MHz|Unknown [CPU Zlib] -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=0.18|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) -Raspberry_Pi_Model_B_Rev_1;Broadcom_BCM2835;900_00=7169.12|1|Raspberry Pi Model B Rev 1|Broadcom BCM2835|1x ARM ARM1176 r0p7 (AArch32)|1x 900.00 MHz|233620|1|1|1 PowerPC 740/750=2150.597408|280.00 MHz|Unknown [GPU Drawing] -Raspberry_Pi_3_Model_B_Rev_1_2;Broadcom_BCM2837;4800_00=3984.56|4|Raspberry Pi 3 Model B Rev 1.2|Broadcom BCM2837|4x ARM Cortex-A53 r0p4 (AArch32)|4x 1200.00 MHz|945512|4|4|4|Gallium 0.4 on llvmpipe (LLVM 3.9, 128 bits) diff -Nru hardinfo-0.5.1+git20171103/CMakeLists.txt hardinfo-0.5.1+git20180227/CMakeLists.txt --- hardinfo-0.5.1+git20171103/CMakeLists.txt 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/CMakeLists.txt 2018-02-27 15:43:20.000000000 +0000 @@ -12,7 +12,8 @@ include(GNUInstallDirs) if(${CMAKE_BUILD_TYPE} MATCHES [Dd]ebug) - set(HARDINFO_DEBUG 1) + set(HARDINFO_DEBUG 1) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") endif() if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Linux") diff -Nru hardinfo-0.5.1+git20171103/debian/changelog hardinfo-0.5.1+git20180227/debian/changelog --- hardinfo-0.5.1+git20171103/debian/changelog 2017-11-25 19:36:24.000000000 +0000 +++ hardinfo-0.5.1+git20180227/debian/changelog 2018-02-28 04:47:46.000000000 +0000 @@ -1,3 +1,14 @@ +hardinfo (0.5.1+git20180227-1) unstable; urgency=medium + + * Update to latest upstream Git commit (3d78bd2). + * Bump Standards-version to 4.1.3, no changes needed. + * Bump debhelper compat to 11, no changes needed. + * Add zlib1g-dev as a build dependency to make sure that the CPU ZLib + benchmark works as intended (Closes: #536244). + * Update Vcs-* to reflect the move to Salsa. + + -- Simon Quigley Tue, 27 Feb 2018 22:47:46 -0600 + hardinfo (0.5.1+git20171103-1) unstable; urgency=medium * Update to latest upstream Git commit (9ea63eb). diff -Nru hardinfo-0.5.1+git20171103/debian/compat hardinfo-0.5.1+git20180227/debian/compat --- hardinfo-0.5.1+git20171103/debian/compat 2017-06-19 20:34:43.000000000 +0000 +++ hardinfo-0.5.1+git20180227/debian/compat 2018-02-28 04:47:46.000000000 +0000 @@ -1 +1 @@ -10 +11 diff -Nru hardinfo-0.5.1+git20171103/debian/control hardinfo-0.5.1+git20180227/debian/control --- hardinfo-0.5.1+git20171103/debian/control 2017-11-25 19:36:24.000000000 +0000 +++ hardinfo-0.5.1+git20180227/debian/control 2018-02-28 04:47:46.000000000 +0000 @@ -3,21 +3,24 @@ Priority: optional Maintainer: Simon Quigley Build-Depends: cmake, - debhelper (>= 10), + debhelper (>= 11), libffi-dev, libgtk2.0-dev, liblzma-dev, libselinux1-dev [!kfreebsd-i386 !kfreebsd-amd64 !hurd-i386], libsoup2.4-dev, pciutils (>= 1:2.1.11-10) -Standards-Version: 4.1.1 +Standards-Version: 4.1.3 Homepage: http://hardinfo.org -Vcs-Browser: https://anonscm.debian.org/git/collab-maint/hardinfo.git -Vcs-Git: https://anonscm.debian.org/git/collab-maint/hardinfo.git +Vcs-Browser: https://salsa.debian.org/tsimonq2-guest/hardinfo +Vcs-Git: https://salsa.debian.org/tsimonq2-guest/hardinfo.git Package: hardinfo Architecture: any -Depends: pciutils (>= 1:2.1.11-10), ${misc:Depends}, ${shlibs:Depends} +Depends: pciutils (>= 1:2.1.11-10), + zlib1g-dev, + ${misc:Depends}, + ${shlibs:Depends} Recommends: lm-sensors Suggests: mesa-utils Description: Displays system information diff -Nru hardinfo-0.5.1+git20171103/debian/copyright hardinfo-0.5.1+git20180227/debian/copyright --- hardinfo-0.5.1+git20171103/debian/copyright 2017-11-25 19:36:24.000000000 +0000 +++ hardinfo-0.5.1+git20180227/debian/copyright 2018-02-28 04:47:46.000000000 +0000 @@ -11,7 +11,7 @@ Files: debian/* Copyright: 2006 Agney Lopes Roth Ferraz - 2017 Simon Quigley + 2017-2018 Simon Quigley License: GPL-2 Files: hardinfo/binreloc.c diff -Nru hardinfo-0.5.1+git20171103/debian/rules hardinfo-0.5.1+git20180227/debian/rules --- hardinfo-0.5.1+git20171103/debian/rules 2017-06-19 20:34:43.000000000 +0000 +++ hardinfo-0.5.1+git20180227/debian/rules 2018-02-28 04:47:46.000000000 +0000 @@ -2,4 +2,4 @@ #export DH_VERBOSE=1 %: - dh ${@} --buildsystem cmake + dh ${@} diff -Nru hardinfo-0.5.1+git20171103/hardinfo/cpubits.c hardinfo-0.5.1+git20180227/hardinfo/cpubits.c --- hardinfo-0.5.1+git20171103/hardinfo/cpubits.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/hardinfo/cpubits.c 2018-02-27 15:43:20.000000000 +0000 @@ -41,7 +41,7 @@ } int cpubits_max(cpubits *b) { - int i = CPUBITS_SIZE * 8; + int i = CPUBITS_SIZE * 8 - 1; while (i >= 0) { if (CPUBIT_GET(b, i)) break; diff -Nru hardinfo-0.5.1+git20171103/hardinfo/cpu_util.c hardinfo-0.5.1+git20180227/hardinfo/cpu_util.c --- hardinfo-0.5.1+git20171103/hardinfo/cpu_util.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/hardinfo/cpu_util.c 2018-02-27 15:43:20.000000000 +0000 @@ -85,7 +85,8 @@ for (i = 0; i <= m; i++) { pack_id = get_cpu_int("topology/physical_package_id", i, CPU_TOPO_NULL); core_id = get_cpu_int("topology/core_id", i, CPU_TOPO_NULL); - if (pack_id >= 0) { CPUBIT_SET(packs, pack_id); } + if (pack_id < 0) pack_id = 0; + CPUBIT_SET(packs, pack_id); if (core_id >= 0) { CPUBIT_SET(cores, (pack_id * MAX_CORES_PER_PACK) + core_id ); } } *t = cpubits_count(threads); @@ -128,6 +129,11 @@ cpufd->cpukhz_max = get_cpu_int("cpufreq/scaling_max_freq", cpufd->id, 0); if (cpufd->scaling_driver == NULL) cpufd->scaling_driver = g_strdup("(Unknown)"); if (cpufd->scaling_governor == NULL) cpufd->scaling_governor = g_strdup("(Unknown)"); + + /* x86 uses freqdomain_cpus, all others use affected_cpus */ + cpufd->shared_list = get_cpu_str("cpufreq/freqdomain_cpus", cpufd->id); + if (cpufd->shared_list == NULL) cpufd->shared_list = get_cpu_str("cpufreq/affected_cpus", cpufd->id); + if (cpufd->shared_list == NULL) cpufd->shared_list = g_strdup_printf("%d", cpufd->id); } } diff -Nru hardinfo-0.5.1+git20171103/hardinfo/hardinfo.c hardinfo-0.5.1+git20180227/hardinfo/hardinfo.c --- hardinfo-0.5.1+git20171103/hardinfo/hardinfo.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/hardinfo/hardinfo.c 2018-02-27 15:43:20.000000000 +0000 @@ -121,8 +121,9 @@ result = module_call_method_param("benchmark::runBenchmark", params.run_benchmark); if (!result) { - g_error(_("Unknown benchmark ``%s'' or libbenchmark.so not loaded"), params.run_benchmark); + g_error(_("Unknown benchmark ``%s'' or benchmark.so not loaded"), params.run_benchmark); } else { + fprintf(stderr, "\n"); g_print("%s\n", result); g_free(result); } diff -Nru hardinfo-0.5.1+git20171103/hardinfo/util.c hardinfo-0.5.1+git20180227/hardinfo/util.c --- hardinfo-0.5.1+git20171103/hardinfo/util.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/hardinfo/util.c 2018-02-27 15:43:20.000000000 +0000 @@ -390,6 +390,7 @@ static gboolean run_xmlrpc_server = FALSE; static gchar *report_format = NULL; static gchar *run_benchmark = NULL; + static gchar *result_format = NULL; static gchar **use_modules = NULL; static GOptionEntry options[] = { @@ -412,6 +413,12 @@ .arg_data = &run_benchmark, .description = N_("run benchmark; requires benchmark.so to be loaded")}, { + .long_name = "result-format", + .short_name = 'g', + .arg = G_OPTION_ARG_STRING, + .arg_data = &result_format, + .description = N_("benchmark result format ([short], conf, shell)")}, + { .long_name = "list-modules", .short_name = 'l', .arg = G_OPTION_ARG_NONE, @@ -468,6 +475,7 @@ param->list_modules = list_modules; param->use_modules = use_modules; param->run_benchmark = run_benchmark; + param->result_format = result_format; param->autoload_deps = autoload_deps; param->run_xmlrpc_server = run_xmlrpc_server; param->argv0 = *(argv)[0]; diff -Nru hardinfo-0.5.1+git20171103/includes/benchmark.h hardinfo-0.5.1+git20180227/includes/benchmark.h --- hardinfo-0.5.1+git20171103/includes/benchmark.h 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/includes/benchmark.h 2018-02-27 15:43:20.000000000 +0000 @@ -27,9 +27,29 @@ void benchmark_raytrace(void); void benchmark_zlib(void); -gdouble benchmark_parallel_for(guint start, guint end, +typedef struct { + double result; + double elapsed_time; + int threads_used; +} bench_value; + +#define EMPTY_BENCH_VALUE {-1.0f,0,0} + +char *bench_value_to_str(bench_value r); +bench_value bench_value_from_str(const char* str); + +/* Note: + * benchmark_parallel_for(): element [start] included, but [end] is excluded. + * callback(): expected to processes elements [start] through [end] inclusive. + */ +bench_value benchmark_parallel_for(gint n_threads, guint start, guint end, + gpointer callback, gpointer callback_data); + +bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data); + +bench_value benchmark_crunch_for(float seconds, gint n_threads, gpointer callback, gpointer callback_data); -extern gdouble bench_results[BENCHMARK_N_ENTRIES]; +extern bench_value bench_results[BENCHMARK_N_ENTRIES]; -#endif /* __BENCHMARK_H__ */ \ No newline at end of file +#endif /* __BENCHMARK_H__ */ diff -Nru hardinfo-0.5.1+git20171103/includes/cpu_util.h hardinfo-0.5.1+git20180227/includes/cpu_util.h --- hardinfo-0.5.1+git20171103/includes/cpu_util.h 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/includes/cpu_util.h 2018-02-27 15:43:20.000000000 +0000 @@ -25,6 +25,7 @@ gint cpukhz_max, cpukhz_min, cpukhz_cur; gchar *scaling_driver, *scaling_governor; gint transition_latency; + gchar *shared_list; } cpufreq_data; typedef struct { diff -Nru hardinfo-0.5.1+git20171103/includes/hardinfo.h hardinfo-0.5.1+git20180227/includes/hardinfo.h --- hardinfo-0.5.1+git20171103/includes/hardinfo.h 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/includes/hardinfo.h 2018-02-27 15:43:20.000000000 +0000 @@ -55,6 +55,7 @@ gchar **use_modules; gchar *run_benchmark; + gchar *result_format; gchar *path_lib; gchar *path_data; gchar *argv0; diff -Nru hardinfo-0.5.1+git20171103/includes/x86/processor-platform.h hardinfo-0.5.1+git20180227/includes/x86/processor-platform.h --- hardinfo-0.5.1+git20171103/includes/x86/processor-platform.h 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/includes/x86/processor-platform.h 2018-02-27 15:43:20.000000000 +0000 @@ -30,6 +30,9 @@ gint size; gchar *type; gint ways_of_associativity; + gint uid; /* uid is unique among caches with the same (type, level) */ + gchar *shared_cpu_list; /* some kernel's don't give a uid, so try shared_cpu_list */ + gint phy_sock; }; struct _Processor { diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/benches.c hardinfo-0.5.1+git20180227/modules/benchmark/benches.c --- hardinfo-0.5.1+git20171103/modules/benchmark/benches.c 1970-01-01 00:00:00.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/benches.c 2018-02-27 15:43:20.000000000 +0000 @@ -0,0 +1,106 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2017 Leandro A. F. Pereira + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* These are parts of modules/benchmark.c where specific benchmarks are defined. */ + +#define BENCH_CALLBACK(CN, BN, BID, R) \ +gchar *CN() { \ + if (R) \ + return benchmark_include_results_reverse(bench_results[BID], BN); \ + else \ + return benchmark_include_results(bench_results[BID], BN); \ +} + +BENCH_CALLBACK(callback_gui, "GPU Drawing", BENCHMARK_GUI, 1); +BENCH_CALLBACK(callback_fft, "FPU FFT", BENCHMARK_FFT, 0); +BENCH_CALLBACK(callback_nqueens, "CPU N-Queens", BENCHMARK_NQUEENS, 0); +BENCH_CALLBACK(callback_raytr, "FPU Raytracing", BENCHMARK_RAYTRACE, 0); +BENCH_CALLBACK(callback_bfsh, "CPU Blowfish", BENCHMARK_BLOWFISH, 0); +BENCH_CALLBACK(callback_cryptohash, "CPU CryptoHash", BENCHMARK_CRYPTOHASH, 1); +BENCH_CALLBACK(callback_fib, "CPU Fibonacci", BENCHMARK_FIB, 0); +BENCH_CALLBACK(callback_zlib, "CPU Zlib", BENCHMARK_ZLIB, 0); + +#define BENCH_SCAN_SIMPLE(SN, BF, BID) \ +void SN(gboolean reload) { \ + SCAN_START(); \ + do_benchmark(BF, BID); \ + SCAN_END(); \ +} + +BENCH_SCAN_SIMPLE(scan_fft, benchmark_fft, BENCHMARK_FFT); +BENCH_SCAN_SIMPLE(scan_nqueens, benchmark_nqueens, BENCHMARK_NQUEENS); +BENCH_SCAN_SIMPLE(scan_raytr, benchmark_raytrace, BENCHMARK_RAYTRACE); +BENCH_SCAN_SIMPLE(scan_bfsh, benchmark_fish, BENCHMARK_BLOWFISH); +BENCH_SCAN_SIMPLE(scan_cryptohash, benchmark_cryptohash, BENCHMARK_CRYPTOHASH); +BENCH_SCAN_SIMPLE(scan_fib, benchmark_fib, BENCHMARK_FIB); +BENCH_SCAN_SIMPLE(scan_zlib, benchmark_zlib, BENCHMARK_ZLIB); + +void scan_gui(gboolean reload) +{ + SCAN_START(); + + bench_value er = EMPTY_BENCH_VALUE; + + if (params.run_benchmark) { + int argc = 0; + + ui_init(&argc, NULL); + } + + if (params.gui_running || params.run_benchmark) { + do_benchmark(benchmark_gui, BENCHMARK_GUI); + } else { + bench_results[BENCHMARK_GUI] = er; + } + SCAN_END(); +} + +static ModuleEntry entries[] = { + {N_("CPU Blowfish"), "blowfish.png", callback_bfsh, scan_bfsh, MODULE_FLAG_NONE}, + {N_("CPU CryptoHash"), "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE}, + {N_("CPU Fibonacci"), "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE}, + {N_("CPU N-Queens"), "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE}, + {N_("CPU Zlib"), "file-roller.png", callback_zlib, scan_zlib, MODULE_FLAG_NONE}, + {N_("FPU FFT"), "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE}, + {N_("FPU Raytracing"), "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE}, +#if !GTK_CHECK_VERSION(3,0,0) + {N_("GPU Drawing"), "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE}, +#endif + {NULL} +}; + +const gchar *hi_note_func(gint entry) +{ + switch (entry) { + case BENCHMARK_CRYPTOHASH: + return _("Results in MiB/second. Higher is better."); + + case BENCHMARK_ZLIB: + case BENCHMARK_GUI: + return _("Results in HIMarks. Higher is better."); + + case BENCHMARK_FFT: + case BENCHMARK_RAYTRACE: + case BENCHMARK_BLOWFISH: + case BENCHMARK_FIB: + case BENCHMARK_NQUEENS: + return _("Results in seconds. Lower is better."); + } + + return NULL; +} diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/bench_results.c hardinfo-0.5.1+git20180227/modules/benchmark/bench_results.c --- hardinfo-0.5.1+git20171103/modules/benchmark/bench_results.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/bench_results.c 2018-02-27 15:43:20.000000000 +0000 @@ -32,13 +32,12 @@ int cores; int threads; char *mid; -} simple_machine; +} bench_machine; typedef struct { char *name; - float result; - int threads; - simple_machine *machine; + bench_value bvalue; + bench_machine *machine; int legacy; /* an old benchmark.conf result */ } bench_result; @@ -112,7 +111,7 @@ return 0; } -static gen_machine_id(simple_machine *m) { +static gen_machine_id(bench_machine *m) { char *s; if (m) { if (m->mid != NULL) @@ -135,19 +134,19 @@ } } -simple_machine *simple_machine_new() { - simple_machine *m = NULL; - m = malloc(sizeof(simple_machine)); +bench_machine *bench_machine_new() { + bench_machine *m = NULL; + m = malloc(sizeof(bench_machine)); if (m) - memset(m, 0, sizeof(simple_machine)); + memset(m, 0, sizeof(bench_machine)); return m; } -simple_machine *simple_machine_this() { - simple_machine *m = NULL; +bench_machine *bench_machine_this() { + bench_machine *m = NULL; char *tmp; - m = simple_machine_new(); + m = bench_machine_new(); if (m) { m->board = module_call_method("devices::getMotherboard"); m->cpu_name = module_call_method("devices::getProcessorName"); @@ -159,18 +158,12 @@ free(tmp); cpu_procs_cores_threads(&m->processors, &m->cores, &m->threads); - /* - tmp = module_call_method("devices::getProcessorCount"); - m->threads = atoi(tmp); - free(tmp); - */ - gen_machine_id(m); } return m; } -void simple_machine_free(simple_machine *s) { +void bench_machine_free(bench_machine *s) { if (s) { free(s->board); free(s->cpu_name); @@ -183,20 +176,19 @@ void bench_result_free(bench_result *s) { if (s) { free(s->name); - simple_machine_free(s->machine); + bench_machine_free(s->machine); } } -bench_result *bench_result_this_machine(const char *bench_name, float result, int threads) { +bench_result *bench_result_this_machine(const char *bench_name, bench_value r) { bench_result *b = NULL; b = malloc(sizeof(bench_result)); if (b) { memset(b, 0, sizeof(bench_result)); - b->machine = simple_machine_this(); + b->machine = bench_machine_this(); b->name = strdup(bench_name); - b->result = result; - b->threads = threads; + b->bvalue = r; b->legacy = 0; } return b; @@ -221,6 +213,32 @@ return -1; } +/* old results didn't store the actual number of threads used */ +static int guess_threads_old_result(const char *bench_name, int threads_available) { +#define CHKBNAME(BN) (strcmp(bench_name, BN) == 0) + if (CHKBNAME("CPU Fibonacci") ) + return 1; + if (CHKBNAME("FPU FFT") ) { + if (threads_available >= 4) + return 4; + else if (threads_available >= 2) + return 2; + else + return 1; + } + if (CHKBNAME("CPU N-Queens") ) { + if (threads_available >= 10) + return 10; + else if (threads_available >= 5) + return 5; + else if (threads_available >= 2) + return 2; + else + return 1; + } + return threads_available; +} + bench_result *bench_result_benchmarkconf(const char *section, const char *key, char **values) { bench_result *b = NULL; char *s0, *s1, *s2; @@ -232,13 +250,16 @@ b = malloc(sizeof(bench_result)); if (b) { memset(b, 0, sizeof(bench_result)); - b->machine = simple_machine_new(); + b->machine = bench_machine_new(); b->name = strdup(section); if (vl >= 10) { /* the 11th could be empty */ b->machine->mid = strdup(key); - b->result = atof(values[0]); - b->threads = atoi(values[1]); + /* first try as bench_value, then try as double 'result' only */ + b->bvalue = bench_value_from_str(values[0]); + if (b->bvalue.result == -1) + b->bvalue.result = atoi(values[0]); + b->bvalue.threads_used = atoi(values[1]); b->machine->board = strdup(values[2]); b->machine->cpu_name = strdup(values[3]); b->machine->cpu_desc = strdup(values[4]); @@ -251,7 +272,7 @@ b->machine->ogl_renderer = strdup(values[10]); b->legacy = 0; } else if (vl >= 2) { - b->result = atof(values[0]); + b->bvalue.result = atof(values[0]); b->legacy = 1; /* old old format has prefix before cpu name (ex: 4x Pentium...) */ @@ -259,11 +280,9 @@ if (nx > 0) { b->machine->cpu_name = strdup(strchr(key, 'x') + 1); b->machine->threads = nx; - b->threads = nx; } else { b->machine->cpu_name = strdup(key); b->machine->threads = 1; - b->threads = 1; } b->machine->cpu_config = strdup(values[1]); @@ -271,9 +290,10 @@ nx = nx_prefix(values[1]); if (nx > 0) { b->machine->threads = nx; - b->threads = nx; } + b->bvalue.threads_used = guess_threads_old_result(section, b->machine->threads); + /* If the clock rate in the id string is more than the * config string, use that. Older hardinfo used current cpu freq * instead of max freq. @@ -295,7 +315,7 @@ n = atof(s1+1); n *= m; - s1 = g_strdup_printf("%dx %.2f %s", b->threads, n, _("MHz")); + s1 = g_strdup_printf("%dx %.2f %s", b->bvalue.threads_used, n, _("MHz")); if ( cpu_config_cmp(b->machine->cpu_config, s1) == -1 && !cpu_config_is_close(b->machine->cpu_config, s1) ) { free(b->machine->cpu_config); @@ -327,8 +347,9 @@ char *bench_result_benchmarkconf_line(bench_result *b) { char *cpu_config = cpu_config_retranslate(b->machine->cpu_config, 1, 0); - char *ret = g_strdup_printf("%s=%.2f|%d|%s|%s|%s|%s|%d|%d|%d|%d|%s\n", - b->machine->mid, b->result, b->threads, + char *bv = bench_value_to_str(b->bvalue); + char *ret = g_strdup_printf("%s=%s|%d|%s|%s|%s|%s|%d|%d|%d|%d|%s\n", + b->machine->mid, bv, b->bvalue.threads_used, (b->machine->board != NULL) ? b->machine->board : "", b->machine->cpu_name, (b->machine->cpu_desc != NULL) ? b->machine->cpu_desc : "", @@ -338,10 +359,11 @@ (b->machine->ogl_renderer != NULL) ? b->machine->ogl_renderer : "" ); free(cpu_config); + free(bv); return ret; } -char *bench_result_more_info(bench_result *b) { +static char *bench_result_more_info_less(bench_result *b) { char *memory = (b->machine->memory_kiB > 0) ? g_strdup_printf("%d %s", b->machine->memory_kiB, _("kiB") ) @@ -359,7 +381,7 @@ /* ogl rend */ "%s=%s\n" /* mem */ "%s=%s\n", _("Benchmark Result"), - _("Threads"), b->threads, + _("Threads"), b->bvalue.threads_used, b->legacy ? _("Note") : "#Note", b->legacy ? _("This result is from an old version of HardInfo. Results might not be comparable to current version. Some details are missing.") : "", _("Machine"), @@ -375,11 +397,12 @@ return ret; } -char *bench_result_more_info_complete(bench_result *b) { +static char *bench_result_more_info_complete(bench_result *b) { return g_strdup_printf("[%s]\n" /* bench name */"%s=%s\n" - /* result */ "%s=%0.2f\n" /* threads */ "%s=%d\n" + /* result */ "%s=%0.2f\n" + /* elapsed */ "%s=%0.2f\n" /* legacy */ "%s=%s\n" "[%s]\n" /* board */ "%s=%s\n" @@ -394,8 +417,9 @@ /* cfg_val */ "%s=%.2f\n", _("Benchmark Result"), _("Benchmark"), b->name, - _("Result"), b->result, - _("Threads"), b->threads, + _("Threads"), b->bvalue.threads_used, + _("Result"), b->bvalue.result, + _("Elapsed Time"), b->bvalue.elapsed_time, b->legacy ? _("Note") : "#Note", b->legacy ? _("This result is from an old version of HardInfo. Results might not be comparable to current version. Some details are missing.") : "", _("Machine"), @@ -411,3 +435,8 @@ _("cfg_val"), cpu_config_val(b->machine->cpu_config) ); } + +char *bench_result_more_info(bench_result *b) { + //return bench_result_more_info_complete(b); + return bench_result_more_info_less(b); +} diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/blowfish.c hardinfo-0.5.1+git20180227/modules/benchmark/blowfish.c --- hardinfo-0.5.1+git20171103/modules/benchmark/blowfish.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/blowfish.c 2018-02-27 15:43:20.000000000 +0000 @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - + + COMMENTS ON USING THIS CODE: @@ -31,7 +31,7 @@ [4] Decryption is the same as encryption except that the plaintext and ciphertext are reversed. -Warning #1: The code does not check key lengths. (Caveat encryptor.) +Warning #1: The code does not check key lengths. (Caveat encryptor.) Warning #2: Beware that Blowfish keys repeat such that "ab" = "abab". Warning #3: It is normally a good idea to zeroize the BLOWFISH_CTX before freeing it. @@ -41,33 +41,33 @@ Warning #5: Make sure to use a reasonable mode of operation for your application. (If you don't know what CBC mode is, see Warning #7.) Warning #6: This code is susceptible to timing attacks. -Warning #7: Security engineering is risky and non-intuitive. Have someone +Warning #7: Security engineering is risky and non-intuitive. Have someone check your work. If you don't know what you are doing, get help. This is code is fast enough for most applications, but is not optimized for speed. -If you require this code under a license other than LGPL, please ask. (I -can be located using your favorite search engine.) Unfortunately, I do not -have time to provide unpaid support for everyone who uses this code. +If you require this code under a license other than LGPL, please ask. (I +can be located using your favorite search engine.) Unfortunately, I do not +have time to provide unpaid support for everyone who uses this code. -- Paul Kocher -*/ - +*/ + #include "hardinfo.h" #include "benchmark.h" #include "blowfish.h" - + #define N 16 static const unsigned long ORIG_P[16 + 2] = { 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, 0xC0AC29B7L, - 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, 0x9216D5D9L, 0x8979FB1BL + 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, 0x9216D5D9L, 0x8979FB1BL }; -static const unsigned long ORIG_S[4][256] = { +static const unsigned long ORIG_S[4][256] = { {0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, 0x636920D8L, 0x71574E69L, 0xA458FEA3L, @@ -383,7 +383,7 @@ 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, - 0x3AC372E6L} + 0x3AC372E6L} }; static unsigned long F(BLOWFISH_CTX * ctx, unsigned long x) @@ -440,14 +440,14 @@ for (i = N + 1; i > 1; --i) { Xl = Xl ^ ctx->P[i]; Xr = F(ctx, Xl) ^ Xr; - - /* Exchange Xl and Xr */ + + /* Exchange Xl and Xr */ temp = Xl; Xl = Xr; Xr = temp; } - - /* Exchange Xl and Xr */ + + /* Exchange Xl and Xr */ temp = Xl; Xl = Xr; Xr = temp; @@ -502,7 +502,7 @@ L = 0xBEBACAFE; R = 0xDEADBEEF; - for (i = start; i <= end; i++) { + for (i = start; i <= end; i++) { Blowfish_Init(&ctx, (unsigned char*)data, 65536); Blowfish_Encrypt(&ctx, &L, &R); Blowfish_Decrypt(&ctx, &L, &R); @@ -514,12 +514,14 @@ void benchmark_fish(void) { + bench_value r = EMPTY_BENCH_VALUE; + gchar *tmpsrc; gchar *bdata_path; bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL); if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) { - bench_results[BENCHMARK_BLOWFISH] = -1.0f; + bench_results[BENCHMARK_BLOWFISH] = r; g_free(bdata_path); return; } @@ -527,7 +529,10 @@ shell_view_set_enabled(FALSE); shell_status_update("Performing Blowfish benchmark..."); - bench_results[BENCHMARK_BLOWFISH] = benchmark_parallel_for(0, 50000, parallel_blowfish, tmpsrc); + r = benchmark_parallel_for(0, 0, 50000, parallel_blowfish, tmpsrc); + r.result = r.elapsed_time; + + bench_results[BENCHMARK_BLOWFISH] = r; g_free(bdata_path); g_free(tmpsrc); } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/cryptohash.c hardinfo-0.5.1+git20180227/modules/benchmark/cryptohash.c --- hardinfo-0.5.1+git20171103/modules/benchmark/cryptohash.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/cryptohash.c 2018-02-27 15:43:20.000000000 +0000 @@ -20,21 +20,21 @@ #include "sha1.h" #include "benchmark.h" -static void inline md5_step(char *data, glong srclen) +void inline md5_step(char *data, glong srclen) { struct MD5Context ctx; guchar checksum[16]; - + MD5Init(&ctx); MD5Update(&ctx, (guchar *)data, srclen); MD5Final(checksum, &ctx); } -static void inline sha1_step(char *data, glong srclen) +void inline sha1_step(char *data, glong srclen) { SHA1_CTX ctx; guchar checksum[20]; - + SHA1Init(&ctx); SHA1Update(&ctx, (guchar*)data, srclen); SHA1Final(checksum, &ctx); @@ -43,37 +43,38 @@ static gpointer cryptohash_for(unsigned int start, unsigned int end, void *data, gint thread_number) { unsigned int i; - - for (i = start; i <= end; i++) { + + for (i = start; i <= end; i++) { if (i & 1) { md5_step(data, 65536); } else { sha1_step(data, 65536); } } - + return NULL; } void benchmark_cryptohash(void) { - gdouble elapsed = 0; + bench_value r = EMPTY_BENCH_VALUE; gchar *tmpsrc, *bdata_path; - + bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL); if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) { g_free(bdata_path); return; - } - + } + shell_view_set_enabled(FALSE); shell_status_update("Running CryptoHash benchmark..."); - - elapsed = benchmark_parallel_for(0, 5000, cryptohash_for, tmpsrc); - + + r = benchmark_parallel_for(0, 0, 5000, cryptohash_for, tmpsrc); + g_free(bdata_path); g_free(tmpsrc); - - bench_results[BENCHMARK_CRYPTOHASH] = 312.0 / elapsed; + + r.result = 312.0 / r.elapsed_time; //TODO: explain in code comments + bench_results[BENCHMARK_CRYPTOHASH] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/drawing.c hardinfo-0.5.1+git20180227/modules/benchmark/drawing.c --- hardinfo-0.5.1+git20171103/modules/benchmark/drawing.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/drawing.c 2018-02-27 15:43:20.000000000 +0000 @@ -22,8 +22,12 @@ void benchmark_gui(void) { + bench_value r = EMPTY_BENCH_VALUE; + shell_view_set_enabled(FALSE); shell_status_update("Running drawing benchmark..."); - - bench_results[BENCHMARK_GUI] = guibench(); + + r.result = guibench(); //TODO: explain in code comments + + bench_results[BENCHMARK_GUI] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/fft.c hardinfo-0.5.1+git20180227/modules/benchmark/fft.c --- hardinfo-0.5.1+git20171103/modules/benchmark/fft.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/fft.c 2018-02-27 15:43:20.000000000 +0000 @@ -25,43 +25,43 @@ unsigned int i; FFTBench **benches = (FFTBench **)data; FFTBench *fftbench = (FFTBench *)(benches[thread_number]); - - for (i = start; i <= end; i++) { + + for (i = start; i <= end; i++) { fft_bench_run(fftbench); } - + return NULL; } +#define FFT_MAXT 4 + void benchmark_fft(void) { - gdouble elapsed = 0; + bench_value r = EMPTY_BENCH_VALUE; + int n_cores, i; gchar *temp; FFTBench **benches; - + shell_view_set_enabled(FALSE); shell_status_update("Running FFT benchmark..."); - + /* Pre-allocate all benchmarks */ - temp = module_call_method("devices::getProcessorCount"); - n_cores = temp ? atoi(temp) : 1; - g_free(temp); - - benches = g_new0(FFTBench *, n_cores); - for (i = 0; i < n_cores; i++) { + benches = g_new0(FFTBench *, FFT_MAXT); + for (i = 0; i < FFT_MAXT; i++) { benches[i] = fft_bench_new(); } - + /* Run the benchmark */ - elapsed = benchmark_parallel_for(0, 4, fft_for, benches); - + r = benchmark_parallel_for(FFT_MAXT, 0, FFT_MAXT, fft_for, benches); + /* Free up the memory */ - for (i = 0; i < n_cores; i++) { + for (i = 0; i < FFT_MAXT; i++) { fft_bench_free(benches[i]); } g_free(benches); - - bench_results[BENCHMARK_FFT] = elapsed; + + r.result = r.elapsed_time; + bench_results[BENCHMARK_FFT] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/fib.c hardinfo-0.5.1+git20180227/modules/benchmark/fib.c --- hardinfo-0.5.1+git20171103/modules/benchmark/fib.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/fib.c 2018-02-27 15:43:20.000000000 +0000 @@ -18,8 +18,7 @@ #include "benchmark.h" -static gulong -fib(gulong n) +gulong fib(gulong n) { if (n == 0) return 0; @@ -32,19 +31,22 @@ benchmark_fib(void) { GTimer *timer = g_timer_new(); - gdouble elapsed; - + bench_value r = EMPTY_BENCH_VALUE; + shell_view_set_enabled(FALSE); shell_status_update("Calculating the 42nd Fibonacci number..."); - + g_timer_reset(timer); g_timer_start(timer); fib(42); - + g_timer_stop(timer); - elapsed = g_timer_elapsed(timer, NULL); + r.elapsed_time = g_timer_elapsed(timer, NULL); g_timer_destroy(timer); - - bench_results[BENCHMARK_FIB] = elapsed; + + r.threads_used = 1; + r.result = r.elapsed_time; + + bench_results[BENCHMARK_FIB] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/nqueens.c hardinfo-0.5.1+git20180227/modules/benchmark/nqueens.c --- hardinfo-0.5.1+git20171103/modules/benchmark/nqueens.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/nqueens.c 2018-02-27 15:43:20.000000000 +0000 @@ -25,7 +25,7 @@ int nqueens(int y) { int x; - + for (x = 0; x < QUEENS; x++) { if (safe((row[y - 1] = x), y - 1)) { if (y < QUEENS) { @@ -35,32 +35,33 @@ } } } - + return 0; } static gpointer nqueens_for(unsigned int start, unsigned int end, void *data, gint thread_number) { unsigned int i; - - for (i = start; i <= end; i++) { + + for (i = start; i <= end; i++) { nqueens(0); } - + return NULL; } void benchmark_nqueens(void) { - gdouble elapsed = 0; - + bench_value r = EMPTY_BENCH_VALUE; + shell_view_set_enabled(FALSE); shell_status_update("Running N-Queens benchmark..."); - - elapsed = benchmark_parallel_for(0, 10, nqueens_for, NULL); - - bench_results[BENCHMARK_NQUEENS] = elapsed; + + r = benchmark_parallel_for(0, 0, 10, nqueens_for, NULL); + r.result = r.elapsed_time; + + bench_results[BENCHMARK_NQUEENS] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/raytrace.c hardinfo-0.5.1+git20180227/modules/benchmark/raytrace.c --- hardinfo-0.5.1+git20171103/modules/benchmark/raytrace.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/raytrace.c 2018-02-27 15:43:20.000000000 +0000 @@ -24,24 +24,25 @@ parallel_raytrace(unsigned int start, unsigned int end, gpointer data, gint thread_number) { unsigned int i; - - for (i = start; i <= end; i++) { + + for (i = start; i <= end; i++) { fbench(); } - + return NULL; } void benchmark_raytrace(void) { - gdouble elapsed = 0; - + bench_value r = EMPTY_BENCH_VALUE; + shell_view_set_enabled(FALSE); shell_status_update("Performing John Walker's FBENCH..."); - - elapsed = benchmark_parallel_for(0, 1000, parallel_raytrace, NULL); - - bench_results[BENCHMARK_RAYTRACE] = elapsed; + + r = benchmark_parallel_for(0, 0, 1000, parallel_raytrace, NULL); + r.result = r.elapsed_time; + + bench_results[BENCHMARK_RAYTRACE] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark/zlib.c hardinfo-0.5.1+git20180227/modules/benchmark/zlib.c --- hardinfo-0.5.1+git20171103/modules/benchmark/zlib.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark/zlib.c 2018-02-27 15:43:20.000000000 +0000 @@ -31,8 +31,8 @@ compressed = malloc(bound); if (!compressed) return NULL; - - for (i = start; i <= end; i++) { + + for (i = start; i <= end; i++) { char uncompressed[65536]; uLong compressedBound = bound; uLong destBound = sizeof(uncompressed); @@ -42,30 +42,32 @@ } free(compressed); - + return NULL; } void benchmark_zlib(void) { - gdouble elapsed = 0; + bench_value r = EMPTY_BENCH_VALUE; gchar *tmpsrc, *bdata_path; - + bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL); if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) { g_free(bdata_path); return; - } - + } + shell_view_set_enabled(FALSE); shell_status_update("Running Zlib benchmark..."); - - elapsed = benchmark_parallel_for(0, 50000, zlib_for, tmpsrc); - + + r = benchmark_parallel_for(0, 0, 50000, zlib_for, tmpsrc); + g_free(bdata_path); g_free(tmpsrc); - gdouble marks = (50000. * 65536.) / (elapsed * 840205128.); - bench_results[BENCHMARK_ZLIB] = marks; + //TODO: explain in code comments + gdouble marks = (50000. * 65536.) / (r.elapsed_time * 840205128.); + r.result = marks; + bench_results[BENCHMARK_ZLIB] = r; } diff -Nru hardinfo-0.5.1+git20171103/modules/benchmark.c hardinfo-0.5.1+git20180227/modules/benchmark.c --- hardinfo-0.5.1+git20171103/modules/benchmark.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/benchmark.c 2018-02-27 15:43:20.000000000 +0000 @@ -32,48 +32,130 @@ #include "benchmark/bench_results.c" -void scan_fft(gboolean reload); -void scan_raytr(gboolean reload); -void scan_bfsh(gboolean reload); -void scan_cryptohash(gboolean reload); -void scan_fib(gboolean reload); -void scan_nqueens(gboolean reload); -void scan_zlib(gboolean reload); -void scan_gui(gboolean reload); - -gchar *callback_fft(); -gchar *callback_raytr(); -gchar *callback_bfsh(); -gchar *callback_fib(); -gchar *callback_cryptohash(); -gchar *callback_nqueens(); -gchar *callback_zlib(); -gchar *callback_gui(); - -static ModuleEntry entries[] = { - {N_("CPU Blowfish"), "blowfish.png", callback_bfsh, scan_bfsh, MODULE_FLAG_NONE}, - {N_("CPU CryptoHash"), "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE}, - {N_("CPU Fibonacci"), "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE}, - {N_("CPU N-Queens"), "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE}, - {N_("CPU Zlib"), "file-roller.png", callback_zlib, scan_zlib, MODULE_FLAG_NONE}, - {N_("FPU FFT"), "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE}, - {N_("FPU Raytracing"), "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE}, -#if !GTK_CHECK_VERSION(3,0,0) - {N_("GPU Drawing"), "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE}, -#endif - {NULL} -}; +bench_value bench_results[BENCHMARK_N_ENTRIES]; + +static void do_benchmark(void (*benchmark_function)(void), int entry); +static gchar *benchmark_include_results_reverse(bench_value result, const gchar * benchmark); +static gchar *benchmark_include_results(bench_value result, const gchar * benchmark); + +/* ModuleEntry entries, scan_*(), callback_*(), etc. */ +#include "benchmark/benches.c" static gboolean sending_benchmark_results = FALSE; +char *bench_value_to_str(bench_value r) { + return g_strdup_printf("%lf; %lf; %d", r.result, r.elapsed_time, r.threads_used); +} + +bench_value bench_value_from_str(const char* str) { + bench_value ret = EMPTY_BENCH_VALUE; + double r, e; + int t, c; + if (str) { + c = sscanf(str, "%lf; %lf; %d", &r, &e, &t); + if (c >= 3) { + ret.result = r; + ret.elapsed_time = e; + ret.threads_used = t; + } + } + return ret; +} + typedef struct _ParallelBenchTask ParallelBenchTask; struct _ParallelBenchTask { gint thread_number; guint start, end; gpointer data, callback; + int *stop; }; +static gpointer benchmark_crunch_for_dispatcher(gpointer data) +{ + ParallelBenchTask *pbt = (ParallelBenchTask *)data; + gpointer (*callback)(void *data, gint thread_number); + gpointer return_value = g_malloc(sizeof(int)); + int count = 0; + + if ((callback = pbt->callback)) { + while(!*pbt->stop) { + callback(pbt->data, pbt->thread_number); + /* don't count if didn't finish in time */ + if (!*pbt->stop) + count++; + } + } else { + DEBUG("this is thread %p; callback is NULL and it should't be!", g_thread_self()); + } + + g_free(pbt); + + *(double*)return_value = (double)count; + return return_value; +} + +bench_value benchmark_crunch_for(float seconds, gint n_threads, + gpointer callback, gpointer callback_data) { + int cpu_procs, cpu_cores, cpu_threads, thread_number, stop = 0; + GSList *threads = NULL, *t; + GTimer *timer; + bench_value ret = EMPTY_BENCH_VALUE; + + timer = g_timer_new(); + + cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); + if (n_threads > 0) + ret.threads_used = n_threads; + else if (n_threads < 0) + ret.threads_used = cpu_cores; + else + ret.threads_used = cpu_threads; + + g_timer_start(timer); + for (thread_number = 0; thread_number < ret.threads_used; thread_number++) { + ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); + GThread *thread; + + DEBUG("launching thread %d", thread_number); + + pbt->thread_number = thread_number; + pbt->data = callback_data; + pbt->callback = callback; + pbt->stop = &stop; + + thread = g_thread_new("dispatcher", + (GThreadFunc)benchmark_crunch_for_dispatcher, pbt); + threads = g_slist_prepend(threads, thread); + + DEBUG("thread %d launched as context %p", thread_number, thread); + } + + /* wait for time */ + //while ( g_timer_elapsed(timer, NULL) < seconds ) { } + g_usleep(seconds * 1000000); + + /* signal all threads to stop */ + stop = 1; + g_timer_stop(timer); + + ret.result = 0; + DEBUG("waiting for all threads to finish"); + for (t = threads; t; t = t->next) { + DEBUG("waiting for thread with context %p", t->data); + gpointer *rv = g_thread_join((GThread *)t->data); + ret.result += *(double*)rv; + g_free(rv); + } + + ret.elapsed_time = g_timer_elapsed(timer, NULL); + + g_slist_free(threads); + g_timer_destroy(timer); + + return ret; +} + static gpointer benchmark_parallel_for_dispatcher(gpointer data) { ParallelBenchTask *pbt = (ParallelBenchTask *)data; @@ -94,50 +176,73 @@ return return_value; } -gdouble benchmark_parallel_for(guint start, guint end, +/* one call for each thread to be used */ +bench_value benchmark_parallel(gint n_threads, gpointer callback, gpointer callback_data) { + int cpu_procs, cpu_cores, cpu_threads; + cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); + if (n_threads == 0) n_threads = cpu_threads; + else if (n_threads == -1) n_threads = cpu_cores; + return benchmark_parallel_for(n_threads, 0, n_threads, callback, callback_data); +} + +/* Note: + * benchmark_parallel_for(): element [start] included, but [end] is excluded. + * callback(): expected to processes elements [start] through [end] inclusive. + */ +bench_value benchmark_parallel_for(gint n_threads, guint start, guint end, gpointer callback, gpointer callback_data) { gchar *temp; - guint n_cores, iter_per_core, iter, thread_number = 0; - gdouble elapsed_time; + int cpu_procs, cpu_cores, cpu_threads; + guint iter_per_thread, iter, thread_number = 0; GSList *threads = NULL, *t; GTimer *timer; + bench_value ret = EMPTY_BENCH_VALUE; + timer = g_timer_new(); - temp = module_call_method("devices::getProcessorCount"); - n_cores = temp ? atoi(temp) : 1; - g_free(temp); - - while (n_cores > 0) { - iter_per_core = (end - start) / n_cores; - - if (iter_per_core == 0) { - DEBUG("not enough items per core; disabling one"); - n_cores--; + cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); + + if (n_threads > 0) + ret.threads_used = n_threads; + else if (n_threads < 0) + ret.threads_used = cpu_cores; + else + ret.threads_used = cpu_threads; + + while (ret.threads_used > 0) { + iter_per_thread = (end - start) / ret.threads_used; + + if (iter_per_thread == 0) { + DEBUG("not enough items per thread; disabling one thread"); + ret.threads_used--; } else { break; } } - DEBUG("processor has %d cores; processing %d elements (%d per core)", - n_cores, (end - start), iter_per_core); + DEBUG("Using %d threads across %d logical processors; processing %d elements (%d per thread)", + ret.threads_used, cpu_threads, (end - start), iter_per_thread); g_timer_start(timer); - for (iter = start; iter < end; iter += iter_per_core) { + for (iter = start; iter < end; ) { ParallelBenchTask *pbt = g_new0(ParallelBenchTask, 1); GThread *thread; - DEBUG("launching thread %d", 1 + (iter / iter_per_core)); + guint ts = iter, te = iter + iter_per_thread; + /* add the remainder of items/iter_per_thread to the last thread */ + if (end - te < iter_per_thread) + te = end; + iter = te; + + DEBUG("launching thread %d", 1 + thread_number); pbt->thread_number = thread_number++; - pbt->start = iter == 0 ? 0 : iter; - pbt->end = iter + iter_per_core - 1; + pbt->start = ts; + pbt->end = te - 1; pbt->data = callback_data; pbt->callback = callback; - if (pbt->end > end) - pbt->end = end; - thread = g_thread_new("dispatcher", (GThreadFunc)benchmark_parallel_for_dispatcher, pbt); threads = g_slist_prepend(threads, thread); @@ -148,18 +253,23 @@ DEBUG("waiting for all threads to finish"); for (t = threads; t; t = t->next) { DEBUG("waiting for thread with context %p", t->data); - g_thread_join((GThread *)t->data); + gpointer *rv = g_thread_join((GThread *)t->data); + if (rv) { + if (ret.result == -1.0) ret.result = 0; + ret.result += *(double*)rv; + } + g_free(rv); } g_timer_stop(timer); - elapsed_time = g_timer_elapsed(timer, NULL); + ret.elapsed_time = g_timer_elapsed(timer, NULL); g_slist_free(threads); g_timer_destroy(timer); - DEBUG("finishing; all threads took %f seconds to finish", elapsed_time); + DEBUG("finishing; all threads took %f seconds to finish", ret.elapsed_time); - return elapsed_time; + return ret; } static gchar *clean_cpuname(gchar *cpuname) @@ -212,7 +322,7 @@ *results_list = h_strdup_cprintf("$%s%s$%s=%.2f|%s\n", *results_list, select ? "*" : "", rkey, ckey, - b->result, b->machine->cpu_config); + b->bvalue.result, b->machine->cpu_config); moreinfo_add_with_prefix("BENCH", rkey, bench_result_more_info(b) ); @@ -220,7 +330,7 @@ g_free(rkey); } -static gchar *__benchmark_include_results(gdouble result, +static gchar *__benchmark_include_results(bench_value r, const gchar * benchmark, ShellOrderType order_type) { @@ -232,12 +342,8 @@ moreinfo_del_with_prefix("BENCH"); - if (result > 0.0) { - temp = module_call_method("devices::getProcessorCount"); - n_threads = temp ? atoi(temp) : 1; - g_free(temp); temp = NULL; - - b = bench_result_this_machine(benchmark, result, n_threads); + if (r.result > 0.0) { + b = bench_result_this_machine(benchmark, r); br_mi_add(&results, b, 1); temp = bench_result_benchmarkconf_line(b); @@ -292,76 +398,20 @@ return return_value; } - - -static gchar *benchmark_include_results_reverse(gdouble result, - const gchar * benchmark) +static gchar *benchmark_include_results_reverse(bench_value result, const gchar * benchmark) { - return __benchmark_include_results(result, benchmark, - SHELL_ORDER_DESCENDING); + return __benchmark_include_results(result, benchmark, SHELL_ORDER_DESCENDING); } -static gchar *benchmark_include_results(gdouble result, - const gchar * benchmark) +static gchar *benchmark_include_results(bench_value result, const gchar * benchmark) { - return __benchmark_include_results(result, benchmark, - SHELL_ORDER_ASCENDING); -} - -gdouble bench_results[BENCHMARK_N_ENTRIES]; - -gchar *callback_gui() -{ - return benchmark_include_results_reverse(bench_results[BENCHMARK_GUI], - "GPU Drawing"); -} - -gchar *callback_fft() -{ - return benchmark_include_results(bench_results[BENCHMARK_FFT], - "FPU FFT"); -} - -gchar *callback_nqueens() -{ - return benchmark_include_results(bench_results[BENCHMARK_NQUEENS], - "CPU N-Queens"); -} - -gchar *callback_raytr() -{ - return benchmark_include_results(bench_results[BENCHMARK_RAYTRACE], - "FPU Raytracing"); -} - -gchar *callback_bfsh() -{ - return benchmark_include_results(bench_results[BENCHMARK_BLOWFISH], - "CPU Blowfish"); -} - -gchar *callback_cryptohash() -{ - return benchmark_include_results_reverse(bench_results[BENCHMARK_CRYPTOHASH], - "CPU CryptoHash"); -} - -gchar *callback_fib() -{ - return benchmark_include_results(bench_results[BENCHMARK_FIB], - "CPU Fibonacci"); -} - -gchar *callback_zlib() -{ - return benchmark_include_results(bench_results[BENCHMARK_ZLIB], - "CPU Zlib"); + return __benchmark_include_results(result, benchmark, SHELL_ORDER_ASCENDING); } typedef struct _BenchmarkDialog BenchmarkDialog; struct _BenchmarkDialog { GtkWidget *dialog; - double result; + bench_value r; }; static gboolean do_benchmark_handler(GIOChannel *source, @@ -371,25 +421,19 @@ BenchmarkDialog *bench_dialog = (BenchmarkDialog*)data; GIOStatus status; gchar *result; - gchar *buffer; - float float_result; + bench_value r = EMPTY_BENCH_VALUE; status = g_io_channel_read_line(source, &result, NULL, NULL, NULL); if (status != G_IO_STATUS_NORMAL) { DEBUG("error while reading benchmark result"); - - bench_dialog->result = -1.0f; + r.result = -1.0f; + bench_dialog->r = r; gtk_widget_destroy(bench_dialog->dialog); return FALSE; } - float_result = strtof(result, &buffer); - if (buffer == result) { - DEBUG("error while converting floating point value"); - bench_dialog->result = -1.0f; - } else { - bench_dialog->result = float_result; - } + r = bench_value_from_str(result); + bench_dialog->r = r; gtk_widget_destroy(bench_dialog->dialog); g_free(result); @@ -412,6 +456,9 @@ GSpawnFlags spawn_flags = G_SPAWN_STDERR_TO_DEV_NULL; gchar *bench_status; + bench_value r = EMPTY_BENCH_VALUE; + bench_results[entry] = r; + bench_status = g_strdup_printf(_("Benchmarking: %s."), entries[entry].name); shell_view_set_enabled(FALSE); @@ -427,7 +474,7 @@ GtkWidget *content_area; GtkWidget *hbox; GtkWidget *label; - + bench_dialog = gtk_dialog_new_with_buttons("", NULL, GTK_DIALOG_MODAL, @@ -442,14 +489,13 @@ gtk_box_pack_end(GTK_BOX(hbox), label, TRUE, TRUE, 5); gtk_container_add(GTK_CONTAINER (content_area), hbox); gtk_widget_show_all(bench_dialog); -#else +#else bench_dialog = gtk_message_dialog_new(GTK_WINDOW(shell_get_main_shell()->window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE, _("Benchmarking. Please do not move your mouse " \ "or press any keys.")); - g_object_set_data(G_OBJECT(bench_dialog), "result", "0.0"); gtk_dialog_add_buttons(GTK_DIALOG(bench_dialog), _("Cancel"), GTK_RESPONSE_ACCEPT, NULL); gtk_message_dialog_set_image(GTK_MESSAGE_DIALOG(bench_dialog), bench_image); @@ -461,7 +507,7 @@ benchmark_dialog = g_new0(BenchmarkDialog, 1); benchmark_dialog->dialog = bench_dialog; - benchmark_dialog->result = -1.0f; + benchmark_dialog->r = r; if (!g_path_is_absolute(params.argv0)) { spawn_flags |= G_SPAWN_SEARCH_PATH; @@ -495,7 +541,7 @@ kill(bench_pid, SIGINT); } - bench_results[entry] = benchmark_dialog->result; + bench_results[entry] = benchmark_dialog->r; g_io_channel_unref(channel); shell_view_set_enabled(TRUE); @@ -518,94 +564,6 @@ setpriority(PRIO_PROCESS, 0, old_priority); } -void scan_gui(gboolean reload) -{ - SCAN_START(); - - if (params.run_benchmark) { - int argc = 0; - - ui_init(&argc, NULL); - } - - if (params.gui_running || params.run_benchmark) { - do_benchmark(benchmark_gui, BENCHMARK_GUI); - } else { - bench_results[BENCHMARK_GUI] = 0.0f; - } - SCAN_END(); -} - -void scan_fft(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fft, BENCHMARK_FFT); - SCAN_END(); -} - -void scan_nqueens(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_nqueens, BENCHMARK_NQUEENS); - SCAN_END(); -} - -void scan_raytr(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_raytrace, BENCHMARK_RAYTRACE); - SCAN_END(); -} - -void scan_bfsh(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fish, BENCHMARK_BLOWFISH); - SCAN_END(); -} - -void scan_cryptohash(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_cryptohash, BENCHMARK_CRYPTOHASH); - SCAN_END(); -} - -void scan_fib(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_fib, BENCHMARK_FIB); - SCAN_END(); -} - -void scan_zlib(gboolean reload) -{ - SCAN_START(); - do_benchmark(benchmark_zlib, BENCHMARK_ZLIB); - SCAN_END(); -} - -const gchar *hi_note_func(gint entry) -{ - switch (entry) { - case BENCHMARK_CRYPTOHASH: - return _("Results in MiB/second. Higher is better."); - - case BENCHMARK_ZLIB: - case BENCHMARK_GUI: - return _("Results in HIMarks. Higher is better."); - - case BENCHMARK_FFT: - case BENCHMARK_RAYTRACE: - case BENCHMARK_BLOWFISH: - case BENCHMARK_FIB: - case BENCHMARK_NQUEENS: - return _("Results in seconds. Lower is better."); - } - - return NULL; -} - gchar *hi_module_get_name(void) { return g_strdup(_("Benchmarks")); @@ -658,7 +616,7 @@ if (!scan_callback) continue; - if (bench_results[i] < 0.0) { + if (bench_results[i].result < 0.0) { /* benchmark was cancelled */ scan_callback(TRUE); } else { @@ -694,7 +652,24 @@ if ((scan_callback = entries[i].scan_callback)) { scan_callback(FALSE); - return g_strdup_printf("%f", bench_results[i]); +#define CHK_RESULT_FORMAT(F) (params.result_format && strcmp(params.result_format, F) == 0) + + if (params.run_benchmark) { + if (CHK_RESULT_FORMAT("conf") ) { + bench_result *b = bench_result_this_machine(name, bench_results[i]); + char *temp = bench_result_benchmarkconf_line(b); + bench_result_free(b); + return temp; + } else if (CHK_RESULT_FORMAT("shell") ) { + bench_result *b = bench_result_this_machine(name, bench_results[i]); + char *temp = bench_result_more_info_complete(b); + bench_result_free(b); + return temp; + } + /* defaults to "short" which is below*/ + } + + return bench_value_to_str(bench_results[i]); } } } @@ -706,7 +681,7 @@ { static ShellModuleMethod m[] = { {"runBenchmark", run_benchmark}, - {NULL} + {NULL} }; return m; @@ -730,9 +705,10 @@ sync_manager_add_entry(&se[0]); sync_manager_add_entry(&se[1]); + bench_value er = EMPTY_BENCH_VALUE; int i; for (i = 0; i < G_N_ELEMENTS(entries) - 1; i++) { - bench_results[i] = -1.0f; + bench_results[i] = er; } } diff -Nru hardinfo-0.5.1+git20171103/modules/devices/arm/processor.c hardinfo-0.5.1+git20180227/modules/devices/arm/processor.c --- hardinfo-0.5.1+git20171103/modules/devices/arm/processor.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/devices/arm/processor.c 2018-02-27 15:43:20.000000000 +0000 @@ -203,6 +203,97 @@ return tmp; } +#define khzint_to_mhzdouble(k) (((double)k)/1000) +#define cmp_clocks_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1; + +static gint cmp_cpufreq_data(cpufreq_data *a, cpufreq_data *b) { + gint i = 0; + i = g_strcmp0(a->shared_list, b->shared_list); if (i!=0) return i; + cmp_clocks_test(cpukhz_max); + cmp_clocks_test(cpukhz_min); + return 0; +} + +static gint cmp_cpufreq_data_ignore_affected(cpufreq_data *a, cpufreq_data *b) { + gint i = 0; + cmp_clocks_test(cpukhz_max); + cmp_clocks_test(cpukhz_min); + return 0; +} + +gchar *clocks_summary(GSList * processors) +{ + gchar *ret = g_strdup_printf("[%s]\n", _("Clocks")); + GSList *all_clocks = NULL, *uniq_clocks = NULL; + GSList *tmp, *l; + Processor *p; + cpufreq_data *c, *cur = NULL; + gint cur_count = 0, i = 0; + + /* create list of all clock references */ + for (l = processors; l; l = l->next) { + p = (Processor*)l->data; + if (p->cpufreq) { + all_clocks = g_slist_prepend(all_clocks, p->cpufreq); + } + } + + if (g_slist_length(all_clocks) == 0) { + ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") ); + g_slist_free(all_clocks); + return ret; + } + + /* ignore duplicate references */ + all_clocks = g_slist_sort(all_clocks, (GCompareFunc)cmp_cpufreq_data); + for (l = all_clocks; l; l = l->next) { + c = (cpufreq_data*)l->data; + if (!cur) { + cur = c; + } else { + if (cmp_cpufreq_data(cur, c) != 0) { + uniq_clocks = g_slist_prepend(uniq_clocks, cur); + cur = c; + } + } + } + uniq_clocks = g_slist_prepend(uniq_clocks, cur); + uniq_clocks = g_slist_reverse(uniq_clocks); + cur = 0, cur_count = 0; + + /* count and list clocks */ + for (l = uniq_clocks; l; l = l->next) { + c = (cpufreq_data*)l->data; + if (!cur) { + cur = c; + cur_count = 1; + } else { + if (cmp_cpufreq_data_ignore_affected(cur, c) != 0) { + ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"), + ret, + khzint_to_mhzdouble(cur->cpukhz_min), + khzint_to_mhzdouble(cur->cpukhz_max), + _("MHz"), + cur_count); + cur = c; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"), + ret, + khzint_to_mhzdouble(cur->cpukhz_min), + khzint_to_mhzdouble(cur->cpukhz_max), + _("MHz"), + cur_count); + + g_slist_free(all_clocks); + g_slist_free(uniq_clocks); + return ret; +} + gchar * processor_get_detailed_info(Processor *processor) { @@ -342,22 +433,26 @@ gchar *meta_soc = processor_name(processors); gchar *meta_cpu_desc = processor_describe(processors); gchar *meta_cpu_topo = processor_describe_default(processors); - gchar *meta_clocks = processor_frequency_desc(processors); + gchar *meta_freq_desc = processor_frequency_desc(processors); + gchar *meta_clocks = clocks_summary(processors); gchar *ret = NULL; UNKIFNULL(meta_cpu_desc); ret = g_strdup_printf("[%s]\n" "%s=%s\n" "%s=%s\n" "%s=%s\n" - "%s=%s\n", + "%s=%s\n" + "%s", _("SOC/Package"), _("Name"), meta_soc, _("Description"), meta_cpu_desc, _("Topology"), meta_cpu_topo, - _("Clocks"), meta_clocks ); + _("Logical CPU Config"), meta_freq_desc, + meta_clocks ); g_free(meta_soc); g_free(meta_cpu_desc); g_free(meta_cpu_topo); + g_free(meta_freq_desc); g_free(meta_clocks); return ret; } diff -Nru hardinfo-0.5.1+git20171103/modules/devices/x86/processor.c hardinfo-0.5.1+git20180227/modules/devices/x86/processor.c --- hardinfo-0.5.1+git20171103/modules/devices/x86/processor.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/devices/x86/processor.c 2018-02-27 15:43:20.000000000 +0000 @@ -176,6 +176,7 @@ { ProcessorCache *cache; gchar *endpoint, *entry, *index; + gchar *uref = NULL; gint i; gint processor_number = processor->id; @@ -212,11 +213,29 @@ cache->size = h_sysfs_read_int(endpoint, entry); g_free(entry); - entry = g_strconcat(index, "ways_of_associativity", NULL); cache->ways_of_associativity = h_sysfs_read_int(endpoint, entry); g_free(entry); + /* unique cache references: id is nice, but share_cpu_list can be + * used if it is not available. */ + entry = g_strconcat(index, "id", NULL); + uref = h_sysfs_read_string(endpoint, entry); + g_free(entry); + if (uref != NULL && *uref != 0 ) + cache->uid = atoi(uref); + else + cache->uid = -1; + g_free(uref); + entry = g_strconcat(index, "shared_cpu_list", NULL); + cache->shared_cpu_list = h_sysfs_read_string(endpoint, entry); + g_free(entry); + + /* reacharound */ + entry = g_strconcat(index, "../../topology/physical_package_id", NULL); + cache->phy_sock = h_sysfs_read_int(endpoint, entry); + g_free(entry); + g_free(index); processor->cache = g_slist_append(processor->cache, cache); @@ -226,18 +245,226 @@ g_free(endpoint); } +#define khzint_to_mhzdouble(k) (((double)k)/1000) +#define cmp_clocks_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1; + +static gint cmp_cpufreq_data(cpufreq_data *a, cpufreq_data *b) { + gint i = 0; + i = g_strcmp0(a->shared_list, b->shared_list); if (i!=0) return i; + cmp_clocks_test(cpukhz_max); + cmp_clocks_test(cpukhz_min); + return 0; +} + +static gint cmp_cpufreq_data_ignore_affected(cpufreq_data *a, cpufreq_data *b) { + gint i = 0; + cmp_clocks_test(cpukhz_max); + cmp_clocks_test(cpukhz_min); + return 0; +} + +gchar *clocks_summary(GSList * processors) +{ + gchar *ret = g_strdup_printf("[%s]\n", _("Clocks")); + GSList *all_clocks = NULL, *uniq_clocks = NULL; + GSList *tmp, *l; + Processor *p; + cpufreq_data *c, *cur = NULL; + gint cur_count = 0, i = 0; + + /* create list of all clock references */ + for (l = processors; l; l = l->next) { + p = (Processor*)l->data; + if (p->cpufreq) { + all_clocks = g_slist_prepend(all_clocks, p->cpufreq); + } + } + + if (g_slist_length(all_clocks) == 0) { + ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") ); + g_slist_free(all_clocks); + return ret; + } + + /* ignore duplicate references */ + all_clocks = g_slist_sort(all_clocks, (GCompareFunc)cmp_cpufreq_data); + for (l = all_clocks; l; l = l->next) { + c = (cpufreq_data*)l->data; + if (!cur) { + cur = c; + } else { + if (cmp_cpufreq_data(cur, c) != 0) { + uniq_clocks = g_slist_prepend(uniq_clocks, cur); + cur = c; + } + } + } + uniq_clocks = g_slist_prepend(uniq_clocks, cur); + uniq_clocks = g_slist_reverse(uniq_clocks); + cur = 0, cur_count = 0; + + /* count and list clocks */ + for (l = uniq_clocks; l; l = l->next) { + c = (cpufreq_data*)l->data; + if (!cur) { + cur = c; + cur_count = 1; + } else { + if (cmp_cpufreq_data_ignore_affected(cur, c) != 0) { + ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"), + ret, + khzint_to_mhzdouble(cur->cpukhz_min), + khzint_to_mhzdouble(cur->cpukhz_max), + _("MHz"), + cur_count); + cur = c; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf(_("%.2f-%.2f %s=%dx\n"), + ret, + khzint_to_mhzdouble(cur->cpukhz_min), + khzint_to_mhzdouble(cur->cpukhz_max), + _("MHz"), + cur_count); + + g_slist_free(all_clocks); + g_slist_free(uniq_clocks); + return ret; +} + +#define cmp_cache_test(f) if (a->f < b->f) return -1; if (a->f > b->f) return 1; + +static gint cmp_cache(ProcessorCache *a, ProcessorCache *b) { + gint i = 0; + cmp_cache_test(phy_sock); + i = g_strcmp0(a->type, b->type); if (i!=0) return i; + cmp_cache_test(level); + cmp_cache_test(size); + cmp_cache_test(uid); /* uid is unique among caches with the same (type, level) */ + if (a->uid == -1) { + /* if id wasn't available, use shared_cpu_list as a unique ref */ + i = g_strcmp0(a->shared_cpu_list, b->shared_cpu_list); if (i!=0) + return i; + } + return 0; +} + +static gint cmp_cache_ignore_id(ProcessorCache *a, ProcessorCache *b) { + gint i = 0; + cmp_cache_test(phy_sock); + i = g_strcmp0(a->type, b->type); if (i!=0) return i; + cmp_cache_test(level); + cmp_cache_test(size); + return 0; +} + +gchar *caches_summary(GSList * processors) +{ + gchar *ret = g_strdup_printf("[%s]\n", _("Caches")); + GSList *all_cache = NULL, *uniq_cache = NULL; + GSList *tmp, *l; + Processor *p; + ProcessorCache *c, *cur = NULL; + gint cur_count = 0, i = 0; + + /* create list of all cache references */ + for (l = processors; l; l = l->next) { + p = (Processor*)l->data; + if (p->cache) { + tmp = g_slist_copy(p->cache); + if (all_cache) { + all_cache = g_slist_concat(all_cache, tmp); + } else { + all_cache = tmp; + } + } + } + + if (g_slist_length(all_cache) == 0) { + ret = h_strdup_cprintf("%s=\n", ret, _("(Not Available)") ); + g_slist_free(all_cache); + return ret; + } + + /* ignore duplicate references */ + all_cache = g_slist_sort(all_cache, (GCompareFunc)cmp_cache); + for (l = all_cache; l; l = l->next) { + c = (ProcessorCache*)l->data; + if (!cur) { + cur = c; + } else { + if (cmp_cache(cur, c) != 0) { + uniq_cache = g_slist_prepend(uniq_cache, cur); + cur = c; + } + } + } + uniq_cache = g_slist_prepend(uniq_cache, cur); + uniq_cache = g_slist_reverse(uniq_cache); + cur = 0, cur_count = 0; + + /* count and list caches */ + for (l = uniq_cache; l; l = l->next) { + c = (ProcessorCache*)l->data; + if (!cur) { + cur = c; + cur_count = 1; + } else { + if (cmp_cache_ignore_id(cur, c) != 0) { + ret = h_strdup_cprintf(_("Level %d (%s)#%d=%dx %dKB (%dKB), %d-way set-associative, %d sets\n"), + ret, + cur->level, + C_("cache-type", cur->type), + cur->phy_sock, + cur_count, + cur->size, + cur->size * cur_count, + cur->ways_of_associativity, + cur->number_of_sets); + cur = c; + cur_count = 1; + } else { + cur_count++; + } + } + } + ret = h_strdup_cprintf(_("Level %d (%s)#%d=%dx %dKB (%dKB), %d-way set-associative, %d sets\n"), + ret, + cur->level, + C_("cache-type", cur->type), + cur->phy_sock, + cur_count, + cur->size, + cur->size * cur_count, + cur->ways_of_associativity, + cur->number_of_sets); + + g_slist_free(all_cache); + g_slist_free(uniq_cache); + return ret; +} + +#define PROC_SCAN_READ_BUFFER_SIZE 896 GSList *processor_scan(void) { GSList *procs = NULL, *l = NULL; Processor *processor = NULL; FILE *cpuinfo; - gchar buffer[512]; + gchar buffer[PROC_SCAN_READ_BUFFER_SIZE]; cpuinfo = fopen(PROC_CPUINFO, "r"); if (!cpuinfo) return NULL; - while (fgets(buffer, 512, cpuinfo)) { + while (fgets(buffer, PROC_SCAN_READ_BUFFER_SIZE, cpuinfo)) { + int rlen = strlen(buffer); + if (rlen >= PROC_SCAN_READ_BUFFER_SIZE - 1) { + fprintf(stderr, "Warning: truncated a line (probably flags list) longer than %d bytes while reading %s.\n", PROC_SCAN_READ_BUFFER_SIZE, PROC_CPUINFO); + } gchar **tmp = g_strsplit(buffer, ":", 2); if (!tmp[1] || !tmp[0]) { g_strfreev(tmp); @@ -351,19 +578,27 @@ gchar tmp_flag[64] = ""; const gchar *meaning; gchar *tmp = NULL; - gint j = 0; + gint j = 0, i = 0; flags = g_strsplit(strflags, " ", 0); old = flags; while (flags[j]) { - sprintf(tmp_flag, "%s%s", lookup_prefix, flags[j]); - meaning = x86_flag_meaning(tmp_flag); - - if (meaning) { - tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning); + if ( sscanf(flags[j], "[%d]", &i) ) { + /* Some flags are indexes, like [13], and that looks like + * a new section to hardinfo shell */ + tmp = h_strdup_cprintf("(%s%d)=\n", tmp, + (lookup_prefix) ? lookup_prefix : "", + i ); } else { - tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]); + sprintf(tmp_flag, "%s%s", lookup_prefix, flags[j]); + meaning = x86_flag_meaning(tmp_flag); + + if (meaning) { + tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning); + } else { + tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]); + } } j++; } @@ -446,15 +681,27 @@ gchar *processor_meta(GSList * processors) { gchar *meta_cpu_name = processor_name(processors); gchar *meta_cpu_desc = processor_describe(processors); + gchar *meta_freq_desc = processor_frequency_desc(processors); + gchar *meta_clocks = clocks_summary(processors); + gchar *meta_caches = caches_summary(processors); gchar *ret = NULL; UNKIFNULL(meta_cpu_desc); ret = g_strdup_printf("[%s]\n" "%s=%s\n" - "%s=%s\n", + "%s=%s\n" + "%s=%s\n" + "%s" + "%s", _("Package Information"), _("Name"), meta_cpu_name, - _("Description"), meta_cpu_desc); + _("Topology"), meta_cpu_desc, + _("Logical CPU Config"), meta_freq_desc, + meta_clocks, + meta_caches); g_free(meta_cpu_desc); + g_free(meta_freq_desc); + g_free(meta_clocks); + g_free(meta_caches); return ret; } @@ -473,10 +720,13 @@ for (l = processors; l; l = l->next) { processor = (Processor *) l->data; - tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n", + tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s|%d:%d|%d\n", tmp, processor->id, processor->model_name, - processor->cpu_mhz, _("MHz")); + processor->cpu_mhz, _("MHz"), + processor->cputopo->socket_id, + processor->cputopo->core_id, + processor->cputopo->id ); hashkey = g_strdup_printf("CPU%d", processor->id); moreinfo_add_with_prefix("DEV", hashkey, @@ -486,8 +736,10 @@ ret = g_strdup_printf("[$ShellParam$]\n" "ViewType=1\n" + "ColumnTitle$Extra1=%s\n" + "ColumnTitle$Extra2=%s\n" "[Processors]\n" - "%s", tmp); + "%s", _("Socket:Core"), _("Thread" /*TODO: +s*/), tmp); g_free(tmp); return ret; diff -Nru hardinfo-0.5.1+git20171103/modules/devices/x86/x86_data.c hardinfo-0.5.1+git20180227/modules/devices/x86/x86_data.c --- hardinfo-0.5.1+git20171103/modules/devices/x86/x86_data.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/modules/devices/x86/x86_data.c 2018-02-27 15:43:20.000000000 +0000 @@ -278,6 +278,10 @@ { "bug:swapgs_fence", NC_("x86-flag", /*/bug:swapgs_fence*/ "SWAPGS without input dep on GS") }, { "bug:monitor", NC_("x86-flag", /*/bug:monitor*/ "IPI required to wake up remote CPU") }, { "bug:amd_e400", NC_("x86-flag", /*/bug:amd_e400*/ "AMD Erratum 400") }, + { "bug:cpu_insecure", NC_("x86-flag", /*/bug:cpu_insecure & bug:cpu_meltdown*/ "CPU is affected by meltdown attack and needs kernel page table isolation") }, + { "bug:cpu_meltdown", NC_("x86-flag", /*/bug:cpu_insecure & bug:cpu_meltdown*/ "CPU is affected by meltdown attack and needs kernel page table isolation") }, + { "bug:spectre_v1", NC_("x86-flag", /*/bug:spectre_v1*/ "CPU is affected by Spectre variant 1 attack with conditional branches") }, + { "bug:spectre_v2", NC_("x86-flag", /*/bug:spectre_v2*/ "CPU is affected by Spectre variant 2 attack with indirect branches") }, /* power management * ... from arch/x86/kernel/cpu/powerflags.h */ { "pm:ts", NC_("x86-flag", /*/flag:pm:ts*/ "temperature sensor") }, diff -Nru hardinfo-0.5.1+git20171103/shell/report.c hardinfo-0.5.1+git20180227/shell/report.c --- hardinfo-0.5.1+git20171103/shell/report.c 2017-11-07 06:06:08.000000000 +0000 +++ hardinfo-0.5.1+git20180227/shell/report.c 2018-02-27 15:43:20.000000000 +0000 @@ -300,7 +300,7 @@ { gint columns = report_get_visible_columns(ctx); gchar **values; - gint i; + gint i, mc; if (columns == 2) { ctx->output = h_strdup_cprintf("%s" @@ -309,10 +309,11 @@ key, value); } else { values = g_strsplit(value, "|", columns); + mc = g_strv_length(values) - 1; ctx->output = h_strdup_cprintf("\n\n%s", ctx->output, key); - for (i = columns - 2; i >= 0; i--) { + for (i = mc; i >= 0; i--) { ctx->output = h_strdup_cprintf("%s", ctx->output, values[i]); @@ -371,7 +372,7 @@ { gint columns = report_get_visible_columns(ctx); gchar **values; - gint i; + gint i, mc; if (columns == 2) { if (strlen(value)) @@ -380,10 +381,11 @@ ctx->output = h_strdup_cprintf("%s\n", ctx->output, key); } else { values = g_strsplit(value, "|", columns); + mc = g_strv_length(values) - 1; ctx->output = h_strdup_cprintf("%s\t", ctx->output, key); - for (i = columns - 2; i >= 0; i--) { + for (i = mc; i >= 0; i--) { ctx->output = h_strdup_cprintf("%s\t", ctx->output, values[i]);