[PATCH] 1/6: 64 bit jiffies

From: Tim Schmielau (tim@physik3.uni-rostock.de)
Date: Sat May 11 2002 - 05:25:48 EST


Dear Linus,

since nobody commented on my last post, I think the 64 bit jiffies patch
seems to be mature enough for submission now.
I assume you still prefer the chunks in seperate mails, this way also my
Bitkeeper stats will look better ;-)

OK, here comes the basic chunk:
Provide a 64 bit jiffies value, updating the high 32 bits with a timer
on 32 bit platforms. Details are encapsulated in the get_jiffies64() call.
Credit for the idea for this lock-free version is due to Albert Cahalan.

Tim

--- linux-2.5.15/include/linux/sched.h Thu May 9 17:47:15 2002
+++ linux-2.5.15-j64/include/linux/sched.h Thu May 9 17:48:20 2002
@@ -460,6 +460,18 @@
 #include <asm/current.h>
 
 extern unsigned long volatile jiffies;
+#if BITS_PER_LONG < 48
+#define NEEDS_JIFFIES64
+ extern u64 get_jiffies64(void);
+#else
+ /* jiffies is wide enough to not wrap for 8716 years at HZ==1024 */
+ static inline u64 get_jiffies64(void)
+ {
+ return (u64)jiffies;
+ }
+#endif
+
+
 extern unsigned long itimer_ticks;
 extern unsigned long itimer_next;
 extern void do_timer(struct pt_regs *);

--- linux-2.5.15/kernel/timer.c Mon Mar 18 21:37:09 2002
+++ linux-2.5.15-j64/kernel/timer.c Thu May 9 17:48:20 2002
@@ -68,6 +68,9 @@
 extern int do_setitimer(int, struct itimerval *, struct itimerval *);
 
 unsigned long volatile jiffies;
+#ifdef NEEDS_JIFFIES64
+static unsigned int volatile jiffies_msb_flips;
+#endif
 
 unsigned int * prof_buffer;
 unsigned long prof_len;
@@ -105,6 +108,8 @@
 
 #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
 
+static inline void init_jiffieswrap_timer(void);
+
 void init_timervecs (void)
 {
         int i;
@@ -117,6 +122,8 @@
         }
         for (i = 0; i < TVR_SIZE; i++)
                 INIT_LIST_HEAD(tv1.vec + i);
+
+ init_jiffieswrap_timer();
 }
 
 static unsigned long timer_jiffies;
@@ -674,6 +681,60 @@
         if (TQ_ACTIVE(tq_timer))
                 mark_bh(TQUEUE_BH);
 }
+
+
+#ifdef NEEDS_JIFFIES64
+
+u64 get_jiffies64(void)
+{
+ unsigned long j;
+ unsigned int f;
+
+ f = jiffies_msb_flips; /* avoid races */
+ rmb();
+ j = jiffies;
+
+ /* account for not yet detected flips */
+ f += (f ^ (j>>(BITS_PER_LONG-1))) & 1;
+ return ((u64) f << (BITS_PER_LONG-1)) | j;
+}
+
+/*
+ * Use a timer to periodically check for jiffies wraparounds.
+ * Instead of overflows we count flips of the highest bit so
+ * that we can easily check whether the latest flip is already
+ * accounted for.
+ * Not racy as invocations are several days apart in time and
+ * jiffies_flips is not modified elsewhere.
+ */
+
+static struct timer_list jiffieswrap_timer;
+#define CHECK_JIFFIESWRAP_INTERVAL (1ul << (BITS_PER_LONG-2))
+
+static void check_jiffieswrap(unsigned long data)
+{
+ mod_timer(&jiffieswrap_timer, jiffies + CHECK_JIFFIESWRAP_INTERVAL);
+
+ jiffies_msb_flips += 1 & (jiffies_msb_flips
+ ^ (jiffies>>(BITS_PER_LONG-1)));
+}
+
+static inline void init_jiffieswrap_timer(void)
+{
+ init_timer(&jiffieswrap_timer);
+ jiffieswrap_timer.expires = jiffies + CHECK_JIFFIESWRAP_INTERVAL;
+ jiffieswrap_timer.function = check_jiffieswrap;
+ add_timer(&jiffieswrap_timer);
+}
+
+#else
+
+static inline void init_jiffieswrap_timer(void)
+{
+}
+
+#endif /* NEEDS_JIFFIES64 */
+
 
 #if !defined(__alpha__) && !defined(__ia64__)
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue May 14 2002 - 12:00:16 EST