diff options
| author | Simon Quigley <tsimonq2@ubuntu.com> | 2018-02-27 22:34:49 -0600 | 
|---|---|---|
| committer | Simon Quigley <tsimonq2@ubuntu.com> | 2018-02-27 22:34:49 -0600 | 
| commit | 00831e690c4581ee8f0f92902ebdb75304bde817 (patch) | |
| tree | 55a37b9cc5d60ad047631ffb39d2f822a22d6d39 /modules | |
| parent | d95f107ef2b9e82c341060be0def97d7bfa430b9 (diff) | |
| parent | 09fcc751ef158898c315ebc9299a0fa3a722d914 (diff) | |
Update upstream source from tag 'upstream/0.5.1+git20180227'
Update to upstream version '0.5.1+git20180227'
with Debian dir 7ca675e2ccb4367b7cc5b255a36b5173afaf9d2c
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/benchmark.c | 440 | ||||
| -rw-r--r-- | modules/benchmark/bench_results.c | 109 | ||||
| -rw-r--r-- | modules/benchmark/benches.c | 106 | ||||
| -rw-r--r-- | modules/benchmark/blowfish.c | 45 | ||||
| -rw-r--r-- | modules/benchmark/cryptohash.c | 33 | ||||
| -rw-r--r-- | modules/benchmark/drawing.c | 8 | ||||
| -rw-r--r-- | modules/benchmark/fft.c | 36 | ||||
| -rw-r--r-- | modules/benchmark/fib.c | 20 | ||||
| -rw-r--r-- | modules/benchmark/nqueens.c | 23 | ||||
| -rw-r--r-- | modules/benchmark/raytrace.c | 19 | ||||
| -rw-r--r-- | modules/benchmark/zlib.c | 26 | ||||
| -rw-r--r-- | modules/devices/arm/processor.c | 101 | ||||
| -rw-r--r-- | modules/devices/x86/processor.c | 282 | ||||
| -rw-r--r-- | modules/devices/x86/x86_data.c | 4 | 
14 files changed, 865 insertions, 387 deletions
| diff --git a/modules/benchmark.c b/modules/benchmark.c index 857904a8..26de9557 100644 --- a/modules/benchmark.c +++ b/modules/benchmark.c @@ -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 @@ static gpointer benchmark_parallel_for_dispatcher(gpointer data)      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); +    cpu_procs_cores_threads(&cpu_procs, &cpu_cores, &cpu_threads); -    while (n_cores > 0) { -        iter_per_core = (end - start) / n_cores; +    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; -        if (iter_per_core == 0) { -          DEBUG("not enough items per core; disabling one"); -          n_cores--; +    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 @@ gdouble benchmark_parallel_for(guint start, guint end,      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 @@ static void br_mi_add(char **results_list, bench_result *b, gboolean select) {      *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 @@ static void br_mi_add(char **results_list, bench_result *b, gboolean select) {      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 @@ static gchar *__benchmark_include_results(gdouble result,      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 @@ static gchar *__benchmark_include_results(gdouble result,      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 @@ static gboolean do_benchmark_handler(GIOChannel *source,      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 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)         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: <b>%s</b>."), entries[entry].name);         shell_view_set_enabled(FALSE); @@ -427,7 +474,7 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)         GtkWidget *content_area;         GtkWidget *hbox;         GtkWidget *label; -        +         bench_dialog = gtk_dialog_new_with_buttons("",                                                    NULL,                                                    GTK_DIALOG_MODAL, @@ -442,14 +489,13 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)         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 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)         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 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)                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 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)      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 @@ static gchar *get_benchmark_results()          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 @@ static gchar *run_benchmark(gchar *name)          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 @@ ShellModuleMethod *hi_exported_methods(void)  {      static ShellModuleMethod m[] = {          {"runBenchmark", run_benchmark}, -	{NULL} +        {NULL}      };      return m; @@ -730,9 +705,10 @@ void hi_module_init(void)      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 --git a/modules/benchmark/bench_results.c b/modules/benchmark/bench_results.c index 226f595c..27a33a65 100644 --- a/modules/benchmark/bench_results.c +++ b/modules/benchmark/bench_results.c @@ -32,13 +32,12 @@ typedef struct {      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 @@ static int cpu_config_is_close(char *str0, char *str1) {      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 @@ static gen_machine_id(simple_machine *m) {      }  } -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 @@ simple_machine *simple_machine_this() {          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 simple_machine_free(simple_machine *s) {  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 @@ static int nx_prefix(const char *str) {      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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c      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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c                  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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c              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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c              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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c                      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 @@ bench_result *bench_result_benchmarkconf(const char *section, const char *key, c  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 @@ char *bench_result_benchmarkconf_line(bench_result *b) {              (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 @@ char *bench_result_more_info(bench_result *b) {          /* 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 @@ char *bench_result_more_info(bench_result *b) {      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 @@ char *bench_result_more_info_complete(bench_result *b) {          /* 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 @@ char *bench_result_more_info_complete(bench_result *b) {                          _("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 --git a/modules/benchmark/benches.c b/modules/benchmark/benches.c new file mode 100644 index 00000000..e09dedcc --- /dev/null +++ b/modules/benchmark/benches.c @@ -0,0 +1,106 @@ +/* + *    HardInfo - Displays System Information + *    Copyright (C) 2003-2017 Leandro A. F. Pereira <leandro@hardinfo.org> + * + *    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 --git a/modules/benchmark/blowfish.c b/modules/benchmark/blowfish.c index feadc430..2aa11a2a 100644 --- a/modules/benchmark/blowfish.c +++ b/modules/benchmark/blowfish.c @@ -15,8 +15,8 @@ You should have received a copy of the GNU Lesser General Public  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 @@ Normal usage is as follows:     [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 #4:  Endianness conversions are the responsibility of the caller.  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 @@ static const unsigned long ORIG_S[4][256] = {   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 @@ void Blowfish_Decrypt(BLOWFISH_CTX * ctx, unsigned long *xl,      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 @@ parallel_blowfish(unsigned int start, unsigned int end, void *data, gint thread_      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 @@ parallel_blowfish(unsigned int start, unsigned int end, void *data, gint thread_  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 @@ benchmark_fish(void)      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 --git a/modules/benchmark/cryptohash.c b/modules/benchmark/cryptohash.c index d97e85c7..6150f3ef 100644 --- a/modules/benchmark/cryptohash.c +++ b/modules/benchmark/cryptohash.c @@ -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 void inline sha1_step(char *data, glong srclen)  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 --git a/modules/benchmark/drawing.c b/modules/benchmark/drawing.c index 67a2c264..d0905954 100644 --- a/modules/benchmark/drawing.c +++ b/modules/benchmark/drawing.c @@ -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 --git a/modules/benchmark/fft.c b/modules/benchmark/fft.c index 7c5889c8..caa52d3d 100644 --- a/modules/benchmark/fft.c +++ b/modules/benchmark/fft.c @@ -25,43 +25,43 @@ static gpointer fft_for(unsigned int start, unsigned int end, void *data, gint t      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 --git a/modules/benchmark/fib.c b/modules/benchmark/fib.c index 0f88be59..d75ac367 100644 --- a/modules/benchmark/fib.c +++ b/modules/benchmark/fib.c @@ -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 @@ void  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 --git a/modules/benchmark/nqueens.c b/modules/benchmark/nqueens.c index a32ed8c1..78293abb 100644 --- a/modules/benchmark/nqueens.c +++ b/modules/benchmark/nqueens.c @@ -25,7 +25,7 @@ bool safe(int x, int y)  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 @@ int nqueens(int y)              }          }      } -     +      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 --git a/modules/benchmark/raytrace.c b/modules/benchmark/raytrace.c index 2ee36a93..c7963583 100644 --- a/modules/benchmark/raytrace.c +++ b/modules/benchmark/raytrace.c @@ -24,24 +24,25 @@ static gpointer  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 --git a/modules/benchmark/zlib.c b/modules/benchmark/zlib.c index eeec9d0e..2ded59a4 100644 --- a/modules/benchmark/zlib.c +++ b/modules/benchmark/zlib.c @@ -31,8 +31,8 @@ static gpointer zlib_for(unsigned int start, unsigned int end, void *data, gint      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 @@ static gpointer zlib_for(unsigned int start, unsigned int end, void *data, gint      }      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 --git a/modules/devices/arm/processor.c b/modules/devices/arm/processor.c index 37f07d79..3bee39f8 100644 --- a/modules/devices/arm/processor.c +++ b/modules/devices/arm/processor.c @@ -203,6 +203,97 @@ gchar *processor_get_capabilities_from_flags(gchar * strflags)      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 *processor_meta(GSList * processors) {      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 --git a/modules/devices/x86/processor.c b/modules/devices/x86/processor.c index ad3c7ca4..f1c2b6e9 100644 --- a/modules/devices/x86/processor.c +++ b/modules/devices/x86/processor.c @@ -176,6 +176,7 @@ static void __cache_obtain_info(Processor *processor)  {      ProcessorCache *cache;      gchar *endpoint, *entry, *index; +    gchar *uref = NULL;      gint i;      gint processor_number = processor->id; @@ -212,11 +213,29 @@ static void __cache_obtain_info(Processor *processor)        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 @@ fail:      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 *processor_get_capabilities_from_flags(gchar *strflags, gchar *lookup_pref      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_describe(GSList * processors) {  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 @@ gchar *processor_get_info(GSList * processors)      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 @@ gchar *processor_get_info(GSList * processors)      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 --git a/modules/devices/x86/x86_data.c b/modules/devices/x86/x86_data.c index ebd434bb..c052f4e1 100644 --- a/modules/devices/x86/x86_data.c +++ b/modules/devices/x86/x86_data.c @@ -278,6 +278,10 @@ static struct {      { "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")     }, | 
