From patchwork Sun Sep 14 13:06:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laszlo Ersek X-Patchwork-Id: 37385 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-we0-f200.google.com (mail-we0-f200.google.com [74.125.82.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BF122202A1 for ; Sun, 14 Sep 2014 13:07:29 +0000 (UTC) Received: by mail-we0-f200.google.com with SMTP id u57sf1541414wes.11 for ; Sun, 14 Sep 2014 06:07:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:reply-to:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :errors-to:x-original-sender:x-original-authentication-results :mailing-list:content-type:content-transfer-encoding; bh=sJZ0qGXmZqSPjnZ/KnChgYa8Ht0GvMTgp1c5d4T+fXE=; b=D1nASryuswdTQcbOpsDRYYsWT+I+jw+Q9R0ZJaFFH/fCHS8XMAReHvMpSrbbYPZ3zn KHIl9rT8lXoFdoWSy0Ql/16uo51cbGejKUaUZt2jgom1xe3zyc0Y8W90PBqSJ5zrR3cJ oa+MrdhsdBVAY8fdH354dEjgKw7/KSeloifB7iPMJsNh4nxlXQ4RaoEgESTV5NaauAj0 cebM43pDCltFWTU0G+lBeAMpfG1fJcIA7fuJ7H8ZTxRV3MfzNu8vQ/WtX/Mp8ckWTdp8 tsjTa43HkoD5xBQbb5ON9zT0x1N9cwyxFg4UZO664seCBlaAk8I0vARbGultnpdaowjB 1yrw== X-Gm-Message-State: ALoCoQlstVsG1zvkmtBRPZk1V0zOySyfHDNiBg87ZFizrwnLTJs+dVJ2LxnzNQGSQE3DocxM47a4 X-Received: by 10.181.13.195 with SMTP id fa3mr4025100wid.0.1410700049009; Sun, 14 Sep 2014 06:07:29 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.19.131 with SMTP id f3ls19818lae.38.gmail; Sun, 14 Sep 2014 06:07:28 -0700 (PDT) X-Received: by 10.152.42.231 with SMTP id r7mr21870824lal.23.1410700048595; Sun, 14 Sep 2014 06:07:28 -0700 (PDT) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com [209.85.217.181]) by mx.google.com with ESMTPS id ck13si14951429lbb.57.2014.09.14.06.07.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 14 Sep 2014 06:07:28 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by mail-lb0-f181.google.com with SMTP id z11so3072947lbi.26 for ; Sun, 14 Sep 2014 06:07:28 -0700 (PDT) X-Received: by 10.112.4.33 with SMTP id h1mr20102011lbh.67.1410700048156; Sun, 14 Sep 2014 06:07:28 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.130.169 with SMTP id of9csp80127lbb; Sun, 14 Sep 2014 06:07:27 -0700 (PDT) X-Received: by 10.50.142.100 with SMTP id rv4mr15326672igb.43.1410700046397; Sun, 14 Sep 2014 06:07:26 -0700 (PDT) Received: from lists.sourceforge.net (lists.sourceforge.net. [216.34.181.88]) by mx.google.com with ESMTPS id ie20si7053574igb.35.2014.09.14.06.07.25 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 14 Sep 2014 06:07:26 -0700 (PDT) Received-SPF: pass (google.com: domain of edk2-devel-bounces@lists.sourceforge.net designates 216.34.181.88 as permitted sender) client-ip=216.34.181.88; Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1XT9WK-0007Sh-AK; Sun, 14 Sep 2014 13:07:12 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1XT9WJ-0007SZ-03 for edk2-devel@lists.sourceforge.net; Sun, 14 Sep 2014 13:07:11 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=lersek@redhat.com; helo=mx1.redhat.com; Received: from mx1.redhat.com ([209.132.183.28]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1XT9WH-00075D-UF for edk2-devel@lists.sourceforge.net; Sun, 14 Sep 2014 13:07:10 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ED73Ra016381 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 14 Sep 2014 09:07:03 -0400 Received: from lacos-laptop-7.usersys.redhat.com (ovpn-116-29.ams2.redhat.com [10.36.116.29]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ED6xtk011371 for ; Sun, 14 Sep 2014 09:07:02 -0400 From: Laszlo Ersek To: edk2-devel@lists.sourceforge.net Date: Sun, 14 Sep 2014 15:06:55 +0200 Message-Id: <1410700015-23791-3-git-send-email-lersek@redhat.com> In-Reply-To: <1410700015-23791-1-git-send-email-lersek@redhat.com> References: <1410700015-23791-1-git-send-email-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -2.2 (--) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1XT9WH-00075D-UF Subject: [edk2] [PATCH 2/2] MdeModulePkg: CoreStall: improve accuracy in iterating branch X-BeenThere: edk2-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list Reply-To: edk2-devel@lists.sourceforge.net List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.sourceforge.net X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lersek@redhat.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The iterating branch of CoreStall() adds an extra tick for each iteration if the division returned a nonzero remainder; effectively rounding up to whole ticks separately per iteration. This has the potential to waste up to 9 ticks. While the current code is technically correct ("the Stall() function stalls execution on the processor for *at least* the requested number of microseconds", according to the UEFI spec, emphasis mine), we can improve the accuracy by rounding up to the exact whole number of ticks. We accumulate fractional ticks during the iteration, and flush whole ticks as they become available. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek --- MdeModulePkg/Core/Dxe/Misc/Stall.c | 44 +++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Misc/Stall.c b/MdeModulePkg/Core/Dxe/Misc/Stall.c index aae54fd..4c63624 100644 --- a/MdeModulePkg/Core/Dxe/Misc/Stall.c +++ b/MdeModulePkg/Core/Dxe/Misc/Stall.c @@ -51,51 +51,75 @@ CoreInternalWaitForTick ( **/ EFI_STATUS EFIAPI CoreStall ( IN UINTN Microseconds ) { UINT64 Counter; UINT32 Remainder; UINTN Index; + UINT64 Accumulator; if (gMetronome == NULL) { return EFI_NOT_AVAILABLE_YET; } // // Counter = Microseconds * 10 / gMetronome->TickPeriod // 0x1999999999999999 = (2^64 - 1) / 10 // if (Microseconds > 0x1999999999999999ULL) { // // Microseconds is too large to multiple by 10 first. Perform the divide // operation first and loop 10 times to avoid 64-bit math overflow. // Counter = DivU64x32Remainder ( Microseconds, gMetronome->TickPeriod, &Remainder ); + + Accumulator = 0; + // + // In each iteration we wait for Counter whole ticks, and + // (Remainder/TickPeriod) fractional ticks (the latter being strictly less + // than one). Clearly we can only pass whole ticks to + // CoreInternalWaitForTick(), therefore we keep a running account of the + // fractional ticks. Whenever enough fractional ticks accumulate, we flush + // a whole tick from them. + // + // Note that Accumulator will never reach or exceed 2*TickPeriod, because + // Remainder < TickPeriod. This has two consequences: + // - We never have to flush more than 1 whole tick. + // - Accumulator is always expressible as UINT64 (TickPeriod being UINT32). + // for (Index = 0; Index < 10; Index++) { - CoreInternalWaitForTick (Counter); - } + Accumulator += Remainder; + if (Accumulator < gMetronome->TickPeriod) { + CoreInternalWaitForTick (Counter); + } else { + Accumulator -= gMetronome->TickPeriod; + if (Counter == MAX_UINT64) { + CoreInternalWaitForTick (Counter); + CoreInternalWaitForTick (1); + } else { + CoreInternalWaitForTick (Counter + 1); + } + } + } - if (Remainder != 0) { - // - // If Remainder was not zero, then normally, Counter would be rounded - // up by 1 tick. In this case, since a loop for 10 counts was used - // to emulate the multiply by 10 operation, Counter needs to be rounded - // up by 10 counts. - // - CoreInternalWaitForTick (10); + // + // Flush any remaining fractional ticks. + // + if (Accumulator > 0) { + CoreInternalWaitForTick (1); } } else { // // Calculate the number of ticks by dividing the number of microseconds by // the TickPeriod. Calculation is based on 100ns unit. // Counter = DivU64x32Remainder ( MultU64x32 (Microseconds, 10), gMetronome->TickPeriod, &Remainder