#include <stdio.h>
#include "threads/interrupt.h"
#include "threads/io.h"
+#include "threads/synch.h"
#include "threads/thread.h"
/* See [8254] for hardware details of the 8254 timer chip. */
#error TIMER_FREQ <= 1000 recommended
#endif
-/* Number of timer ticks that a process gets before being
- preempted. */
-#define TIME_SLICE 1
-
/* Number of timer ticks since OS booted. */
-static volatile int64_t ticks;
+static int64_t ticks;
/* Number of loops per timer tick.
Initialized by timer_calibrate(). */
outb (0x40, count & 0xff);
outb (0x40, count >> 8);
- intr_register (0x20, 0, INTR_OFF, timer_interrupt, "8254 Timer");
+ intr_register_ext (0x20, timer_interrupt, "8254 Timer");
}
/* Calibrates loops_per_tick, used to implement brief delays. */
/* Approximate loops_per_tick as the largest power-of-two
still less than one timer tick. */
loops_per_tick = 1u << 10;
- while (!too_many_loops (loops_per_tick << 1))
- loops_per_tick <<= 1;
+ while (!too_many_loops (loops_per_tick << 1))
+ {
+ loops_per_tick <<= 1;
+ ASSERT (loops_per_tick != 0);
+ }
/* Refine the next 8 bits of loops_per_tick. */
high_bit = loops_per_tick;
enum intr_level old_level = intr_disable ();
int64_t t = ticks;
intr_set_level (old_level);
+ barrier ();
return t;
}
void
timer_print_stats (void)
{
- printf ("Timer: %"PRId64" ticks\n", ticks);
+ printf ("Timer: %"PRId64" ticks\n", timer_ticks ());
}
\f
/* Timer interrupt handler. */
{
ticks++;
thread_tick ();
- if (ticks % TIME_SLICE == 0)
- intr_yield_on_return ();
}
/* Returns true if LOOPS iterations waits for more than one timer
static bool
too_many_loops (unsigned loops)
{
- int64_t start;
-
/* Wait for a timer tick. */
- start = ticks;
+ int64_t start = ticks;
while (ticks == start)
- continue;
+ barrier ();
/* Run LOOPS loops. */
start = ticks;
busy_wait (loops);
/* If the tick count changed, we iterated too long. */
+ barrier ();
return start != ticks;
}
busy_wait (int64_t loops)
{
while (loops-- > 0)
- continue;
+ barrier ();
}
/* Sleep for approximately NUM/DENOM seconds. */