public inbox for linux-ia64@vger.kernel.org
 help / color / mirror / Atom feed
From: David Mosberger <davidm@napali.hpl.hp.com>
To: linux-ia64@vger.kernel.org
Subject: Re: sched_clock
Date: Thu, 03 Jun 2004 22:46:58 +0000	[thread overview]
Message-ID: <16575.43618.900768.859629@napali.hpl.hp.com> (raw)
In-Reply-To: <40B4868F.B649611C@nospam.org>

>>>>> On Wed, 26 May 2004 13:59:11 +0200, Zoltan Menyhart <Zoltan.Menyhart_AT_bull.net@nospam.org> said:

  Zoltan> Time can go backward.  At least for the IA64 implementation
  Zoltan> where "sched_clock()" overflows.

Yes, you're right, there is an intermediate-result overflow problem in
sched_clock() that I missed.  How does the attached patch work for you?

  Zoltan> Funny results can be obtained in "schedule()". E.g.:

  Zoltan> unsigned long run_time;
  Zoltan> now = sched_clock();
  Zoltan> run_time = now - prev->timestamp;

  Zoltan> I do think it is a good programming solution to abuse the
  Zoltan> fact that the variables are unsigned, and should
  Zoltan> "sched_clock()" overflow, we would be saved by the "else"
  Zoltan> branch.

Ingo, please correct me if I'm wrong, but I believe the code in
kernel/sched.c assumes that the cycle-counter will NOT overflow for
all practical purposes.  For example, a 64-bit cycle-counter running
at 10GHz would overflow only once every 532,249,697 years.  However,
this assumes that the cycle counter starts at (or near) zero at
boot-time.  I don't think there is any such guarantee on ia64 so
perhaps we should reset AR.ITC to zero on the boot-strap processor at
boot-time (or on all CPUs if the cycle-counters are not synchronized).

Ingo, is there something on x86 that guarantees that the cycle-counter
will start out near zero at boot time?

	--david

=== arch/ia64/kernel/head.S 1.22 vs edited ==--- 1.22/arch/ia64/kernel/head.S	Thu May 27 15:44:02 2004
+++ edited/arch/ia64/kernel/head.S	Thu Jun  3 14:36:56 2004
@@ -815,6 +815,36 @@
 	br.ret.sptk.many rp
 END(ia64_delay_loop)
 
+/*
+ * Return a CPU-local timestamp in nano-seconds.  This timestamp is NOT synchronized
+ * across CPUs its return value must never be compared against the values returned
+ * on another CPU.  The usage in kernel/sched.c ensures that.
+ *
+ * The code below basically calculates:
+ *
+ *   (ia64_get_itc() * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT
+ *
+ * except that the multiplication and the shift are done with 128-bit intermediate
+ * precision so that we can produce a full 64-bit result.
+ */
+GLOBAL_ENTRY(sched_clock)
+	addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+	mov.m r9=ar.itc		// fetch cycle-counter				(35 cyc)
+	;;
+	ldf8 f8=[r8]
+	;;
+	setf.sig f9=r9		// certain to stall, so issue it _after_ ldf8...
+	;;
+	xmpy.lu f10ù,f8	// calculate low 64 bits of 128-bit product	(4 cyc)
+	xmpy.hu f11ù,f8	// calculate high 64 bits of 128-bit product
+	;;
+	getf.sig r8ñ0		//						(5 cyc)
+	getf.sig r9ñ1
+	;;
+	shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
+	br.ret.sptk.many rp
+END(sched_clock)
+
 GLOBAL_ENTRY(start_kernel_thread)
 	.prologue
 	.save rp, r0				// this is the end of the call-chain
=== arch/ia64/kernel/time.c 1.41 vs edited ==--- 1.41/arch/ia64/kernel/time.c	Fri May 14 19:00:12 2004
+++ edited/arch/ia64/kernel/time.c	Thu Jun  3 14:26:19 2004
@@ -45,14 +45,6 @@
 
 #endif
 
-unsigned long long
-sched_clock (void)
-{
-	unsigned long offset = ia64_get_itc();
-
-	return (offset * local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
-}
-
 static void
 itc_reset (void)
 {

  reply	other threads:[~2004-06-03 22:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-26 11:59 sched_clock Zoltan Menyhart
2004-06-03 22:46 ` David Mosberger [this message]
2004-06-04  9:43 ` sched_clock Ingo Molnar
2004-06-04 11:02 ` sched_clock Andi Kleen
2004-06-04 11:11 ` sched_clock Zoltan Menyhart
2004-06-04 22:23 ` sched_clock David Mosberger
2004-06-04 22:52 ` sched_clock David Mosberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=16575.43618.900768.859629@napali.hpl.hp.com \
    --to=davidm@napali.hpl.hp.com \
    --cc=linux-ia64@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox