From patchwork Tue Dec 11 12:04:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 205189 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 43AC42C0090 for ; Tue, 11 Dec 2012 23:04:18 +1100 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TiOZN-0003PD-1e; Tue, 11 Dec 2012 12:04:17 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1TiOZD-0003Le-G7 for fwts-devel@lists.ubuntu.com; Tue, 11 Dec 2012 12:04:07 +0000 Received: from cpc3-craw6-2-0-cust180.croy.cable.virginmedia.com ([77.100.248.181] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1TiOZD-0004tl-CQ for fwts-devel@lists.ubuntu.com; Tue, 11 Dec 2012 12:04:07 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 1/4] lib: cpu: add common CPU performance measuring code to fwts library Date: Tue, 11 Dec 2012 12:04:03 +0000 Message-Id: <1355227446-14380-2-git-send-email-colin.king@canonical.com> X-Mailer: git-send-email 1.8.0 In-Reply-To: <1355227446-14380-1-git-send-email-colin.king@canonical.com> References: <1355227446-14380-1-git-send-email-colin.king@canonical.com> X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: fwts-devel-bounces@lists.ubuntu.com Errors-To: fwts-devel-bounces@lists.ubuntu.com From: Colin Ian King The C-states and CPU frequency tests use fairly common code to load the CPUs. Move this into fwts_cpu.c as fwts_cpu_performance() which measures the performance of a specified CPU for just 1 second and returns a bogo metric of CPU performance. Also add in a CPU load helper function. Signed-off-by: Colin Ian King Acked-by: Keng-Yu Lin Acked-by: Ivan Hu --- src/lib/include/fwts_cpu.h | 3 ++ src/lib/src/fwts_cpu.c | 98 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/lib/include/fwts_cpu.h b/src/lib/include/fwts_cpu.h index a90141d..daf48a2 100644 --- a/src/lib/include/fwts_cpu.h +++ b/src/lib/include/fwts_cpu.h @@ -20,6 +20,8 @@ #ifndef __FWTS_CPU_H__ #define __FWTS_CPU_H__ +#include "fwts_framework.h" + #include typedef struct cpuinfo_x86 { @@ -44,5 +46,6 @@ int fwts_cpu_enumerate(void); int fwts_cpu_consume(const int seconds); int fwts_cpu_consume_start(void); void fwts_cpu_consume_complete(void); +int fwts_cpu_performance(fwts_framework *fw, const int cpu, uint64_t *loop_count); #endif diff --git a/src/lib/src/fwts_cpu.c b/src/lib/src/fwts_cpu.c index 80d7824..91cb87e 100644 --- a/src/lib/src/fwts_cpu.c +++ b/src/lib/src/fwts_cpu.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include "fwts_types.h" #include "fwts_cpu.h" @@ -287,6 +290,92 @@ static void fwts_cpu_sigint_handler(int dummy) _exit(0); } + +/* + * fwts_cpu_burn_cycles() + * burn some CPU cycles + */ +static void fwts_cpu_burn_cycles(void) +{ + double A = 1.234567; + double B = 3.121213; + int i; + + for (i = 0; i < 100; i++) { + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + A = A * B; + B = A * A; + A = A - B + sqrt(A); + } +} + +/* + * fwts_cpu_performance() + * + */ +int fwts_cpu_performance( + fwts_framework *fw, + const int cpu, /* CPU we want to measure performance */ + uint64_t *loop_count) /* Returned measure of bogo compute power */ +{ + cpu_set_t mask, oldset; + time_t current; + int ncpus = fwts_cpu_enumerate(); + + *loop_count = 0; + + if (ncpus == FWTS_ERROR) + return FWTS_ERROR; + + if (cpu < 0 || cpu > ncpus) + return FWTS_ERROR; + + /* Pin to the specified CPU */ + + if (sched_getaffinity(0, sizeof(oldset), &oldset) < 0) { + fwts_log_error(fw, "Cannot get scheduling affinity."); + return FWTS_ERROR; + } + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (sched_setaffinity(0, sizeof(mask), &mask) < 0) { + fwts_log_error(fw, "Cannot set scheduling affinity to CPU %d.", cpu); + return FWTS_ERROR; + } + + /* Wait until we get a new second */ + current = time(NULL); + while (current == time(NULL)) + sched_yield(); + + current = time(NULL); + + /* + * And burn some CPU cycles and get a bogo-compute like + * loop count measure of CPU performance. + */ + do { + fwts_cpu_burn_cycles(); + (*loop_count)++; + } while (current == time(NULL)); + + if (sched_setaffinity(0, sizeof(oldset), &oldset) < 0) { + fwts_log_error(fw, "Cannot restore old CPU affinity settings."); + return FWTS_ERROR; + } + + return FWTS_OK; +} + /* * fwts_cpu_consume_cycles() * eat up CPU cycles @@ -294,17 +383,14 @@ static void fwts_cpu_sigint_handler(int dummy) static void fwts_cpu_consume_cycles(void) { signal(SIGUSR1, fwts_cpu_consume_sighandler); + uint64_t i; - float dummy = 0.000001; - unsigned long long i = 0; - - while (dummy > 0.0) { - dummy += 0.0000037; + for (;;) { + fwts_cpu_burn_cycles(); i++; } } - /* * fwts_cpu_consume_complete() * kill all CPU consumes, free up pid info