Rename printk() to printf().
[pintos-anon] / src / devices / timer.c
index 4adca8989cf1192612a0c009d187f999c2d5e25a..1706201f4ea8590b54a9bc58792667128bb23cf7 100644 (file)
@@ -1,16 +1,16 @@
-#include "timer.h"
-#include "debug.h"
-#include "interrupt.h"
-#include "io.h"
+#include "devices/timer.h"
+#include <debug.h>
+#include "threads/interrupt.h"
+#include "threads/io.h"
   
-static volatile uint64_t ticks;
+#if TIMER_FREQ < 19
+#error 8254 timer requires TIMER_FREQ >= 19
+#endif
 
-static void
-irq20_timer (struct intr_frame *args UNUSED)
-{
-  ticks++;
-  intr_yield_on_return ();
-}
+/* Number of timer ticks since OS booted. */
+static volatile int64_t ticks;
+
+static intr_handler_func timer_interrupt;
 
 /* Sets up the 8254 Programmable Interrupt Timer (PIT) to
    interrupt PIT_FREQ times per second, and registers the
@@ -26,28 +26,58 @@ timer_init (void)
   outb (0x40, count & 0xff);
   outb (0x40, count >> 8);
 
-  intr_register (0x20, 0, IF_OFF, irq20_timer);
+  intr_register (0x20, 0, INTR_OFF, timer_interrupt, "8254 Timer");
 }
 
-uint64_t
+/* Returns the number of timer ticks since the OS booted. */
+int64_t
 timer_ticks (void) 
 {
-  enum if_level old_level = intr_disable ();
-  uint64_t t = ticks;
+  enum intr_level old_level = intr_disable ();
+  int64_t t = ticks;
   intr_set_level (old_level);
   return t;
 }
 
-uint64_t
-timer_elapsed (uint64_t then) 
+/* Returns the number of timer ticks elapsed since THEN, which
+   should be a value once returned by timer_ticks(). */
+int64_t
+timer_elapsed (int64_t then) 
+{
+  return timer_ticks () - then;
+}
+
+/* Suspends execution for approximately MS milliseconds. */
+void
+timer_msleep (int64_t ms) 
+{
+  int64_t ticks = (int64_t) ms * TIMER_FREQ / 1000;
+  int64_t start = timer_ticks ();
+
+  while (timer_elapsed (start) < ticks) 
+    continue;
+}
+
+/* Suspends execution for approximately US microseconds.
+   Note: this is ridiculously inaccurate. */
+void
+timer_usleep (int64_t us) 
 {
-  uint64_t now = timer_ticks ();
-  return now > then ? now - then : ((uint64_t) -1 - then) + now + 1;
+  timer_msleep (us / 1000 + 1);
 }
 
-/* Suspends execution for at least DURATION ticks. */
+/* Suspends execution for approximately NS nanoseconds.
+   Note: this is ridiculously inaccurate. */
 void
-timer_wait_until (uint64_t duration
+timer_nsleep (int64_t ns
 {
-  /* FIXME */
+  timer_msleep (ns / 1000000 + 1);
+}
+\f
+/* Timer interrupt handler. */
+static void
+timer_interrupt (struct intr_frame *args UNUSED)
+{
+  ticks++;
+  intr_yield_on_return ();
 }