While loop never ends unless terminal is written to? [SLVED]
Posted: Sat Jun 11, 2016 7:07 pm
This issue is baffling me - my PIT is set up, oscillating at the default frequency, and 'calibrated' (~59 ms per interrupt). I have used a visual indicator to confirm this - I receive a debug message once per second once I begin receiving interrupts from IRQ0.
I am using the PIT as a timer with the following code (timer_ticks increments every time the PIT handler is called):
Inexplicably, this while loop never exits (although interrupts on IRQ1 are still received; I have a keyboard handler set up which allows me to type) unless I write to the terminal in the while loop. This leads me to believe that I am dealing with a code optimization problem (or my IRQ handler is broken) - I am compiling with O2, but changing to O0 or O1 doesn't fix my problem.
However, nothing else fixes the issue - I have tried adding in an internal counter that ticks up and sending STI before the while loop to ensure interrupts are received and neither cause the loop to exit to allow the rest of the kernel to load.
To clarify, this code does work - the timer exits as expected:
I have tested this in VMWare Player and Bochs. Any thoughts on why this is happening? I can provide additional code if necessary.
Edit: Global variable 'int timer_ticks' changed to 'volatile int timer_ticks' - fixed my problem with an explanation below
I am using the PIT as a timer with the following code (timer_ticks increments every time the PIT handler is called):
Code: Select all
void timer_wait(int ticks) { // Time offset in ticks as argument
unsigned long w_ticks; // Ticks to wait for
w_ticks = timer_ticks + ticks; // The current tick count plus the time offset
while(timer_ticks < w_ticks) {
} // Loop until timer_ticks > ticks count to wait for
}
However, nothing else fixes the issue - I have tried adding in an internal counter that ticks up and sending STI before the while loop to ensure interrupts are received and neither cause the loop to exit to allow the rest of the kernel to load.
To clarify, this code does work - the timer exits as expected:
Code: Select all
void timer_wait(int ticks) { // Time offset in ticks as argument
unsigned long w_ticks; // Ticks to wait for
w_ticks = timer_ticks + ticks; // The sum of the initial tick count and the time offset
while(timer_ticks < w_ticks) {
terminal_writestring(" \b"); // Write a space and delete it to produce no net output
} // Loop until timer_ticks > ticks count to wait for
Edit: Global variable 'int timer_ticks' changed to 'volatile int timer_ticks' - fixed my problem with an explanation below