From patchwork Fri May 23 12:42:42 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Ian King X-Patchwork-Id: 351825 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 30253140092; Fri, 23 May 2014 22:42:57 +1000 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1WnooK-0002qr-4W; Fri, 23 May 2014 12:42:56 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1Wnoo9-0002pk-7Q for fwts-devel@lists.ubuntu.com; Fri, 23 May 2014 12:42:45 +0000 Received: from cpc3-craw6-2-0-cust180.croy.cable.virginm.net ([77.100.248.181] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Wnoo9-0002QT-4t for fwts-devel@lists.ubuntu.com; Fri, 23 May 2014 12:42:45 +0000 From: Colin King To: fwts-devel@lists.ubuntu.com Subject: [PATCH 3/4] cpu: cpufreq: sort frequencies using almost equal comparison (LP: #1322531) Date: Fri, 23 May 2014 13:42:42 +0100 Message-Id: <1400848963-18477-4-git-send-email-colin.king@canonical.com> X-Mailer: git-send-email 2.0.0.rc0 In-Reply-To: <1400848963-18477-1-git-send-email-colin.king@canonical.com> References: <1400848963-18477-1-git-send-email-colin.king@canonical.com> X-BeenThere: fwts-devel@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Firmware Test Suite Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: fwts-devel-bounces@lists.ubuntu.com Sender: fwts-devel-bounces@lists.ubuntu.com From: Colin Ian King Some _PSS states have top turbo frequencies that are set at the same level or nearly the same level as the next fast _PSS non-turbo level. Sometimes this confuses the qsort, so make the qsort compare function also sub-sort Signed-off-by: Colin Ian King Acked-by: Keng-Yu Lin Acked-by: Alex Hung --- src/cpu/cpufreq/cpufreq.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/cpu/cpufreq/cpufreq.c b/src/cpu/cpufreq/cpufreq.c index 91e44f9..22e16ef 100644 --- a/src/cpu/cpufreq/cpufreq.c +++ b/src/cpu/cpufreq/cpufreq.c @@ -59,6 +59,34 @@ static int num_cpus; #define GET_PERFORMANCE_MIN (1) #define GET_PERFORMANCE_AVG (2) +#define MAX_ABSOLUTE_ERROR 20.0 /* In Hz */ +#define MAX_RELATIVE_ERROR 0.0025 /* as fraction */ + +/* + * hz_almost_equal() + * used to compare CPU _PSS levels, are they almost + * equal? E.g. within MAX_ABSOLUTE_ERROR Hz difference + * between each other, or a relative difference of + * MAX_RELATIVE_ERROR. If they are, then they are deemed + * almost equal. + */ +static int hz_almost_equal(const uint64_t a, const uint64_t b) +{ + double da = (double)a, db = (double)b; + double relative_error, abs_diff = fabs(da - db); + + if (a == b) + return true; + if (abs_diff < MAX_ABSOLUTE_ERROR) + return true; + if (db > da) + relative_error = abs_diff / db; + else + relative_error = abs_diff / da; + + return relative_error <= MAX_RELATIVE_ERROR; +} + static inline void cpu_mkpath( char *const path, const int len, @@ -224,7 +252,16 @@ static int cpu_freq_compare(const void *v1, const void *v2) const fwts_cpu_freq *cpu_freq1 = (fwts_cpu_freq *)v1; const fwts_cpu_freq *cpu_freq2 = (fwts_cpu_freq *)v2; - return cpu_freq1->Hz - cpu_freq2->Hz; + /* + * Some _PSS states can be the same or very nearly + * the same when Turbo mode is available, + * so if they are we also differentiate the two by + * the speed to get a fully sorted ordering + */ + if (hz_almost_equal(cpu_freq1->Hz, cpu_freq2->Hz)) + return cpu_freq1->speed - cpu_freq2->speed; + else + return cpu_freq1->Hz - cpu_freq2->Hz; } static int read_freqs_available(const int cpu, fwts_cpu_freq *freqs)