Page 1 of 1

Compiler seems to be ignoring volatile (timer_wait issue)

Posted: Tue Feb 21, 2023 11:01 am
by yutani
I'm fairly early in my OS development. I've got it booting and have a basic "console" for commands. For my first proper command I figured I'd make the speaker beep - I can start the sound but can't stop it, because timer_wait() isn't working.

I've searched the wiki and I thought volatile was the answer, but even with volatile it's not returning.

Code: Select all

#include "timer.h"
#include <stdint.h>
#include "ports.h"
#include "../libc/function.h"
#include "isr.h"

volatile uint32_t timer_ticks = 0;

void timer_callback(registers_t *regs)
{
        timer_ticks++;
    UNUSED(regs);
}

void timer_wait(uint32_t ticks)
{
        uint32_t eticks;
        eticks = timer_ticks+ticks;
        while(timer_ticks < eticks);
        {
                dkprint("ok \n");
        }
        dkprint("end");
}

void init_timer(uint32_t freq) {
    register_interrupt_handler(IRQ0, timer_callback);
    u32 divisor = 1193180 / freq;       /* Calculate our divisor */
    u8 low  = (u8)(divisor & 0xFF);
    u8 high = (u8)( (divisor >> 8) & 0xFF);
    port_byte_out(0x43, 0x36);             /* Set our command byte 0x36 */
    port_byte_out(0x40, low);   /* Set low byte of divisor */
    port_byte_out(0x40, high);     /* Set high byte of divisor */
    
}
The callback does run - if I add code to print timer_ticks in the timer_callback() it counts up. But I can't access timer_ticks reliably from anywhere else.

I added some code to timer_wait to output timer_ticks on a loop, and when timer_wait() is called for the first time, timer_ticks is a sensible value (it's counting up over time), but whatever that starting value is, it stays at, so timer_wait() just prints, for example "608" over and over again, and never stops.

It's as if volatile is being ignored by my compiler?

I tried using a pointer to timer_ticks inside timer_wait() but that's not behaving as expected either, so now I'm rather confused. I'd appreciate any suggestions/tips.

Thanks

Re: Compiler seems to be ignoring volatile (timer_wait issue

Posted: Sat Mar 04, 2023 4:01 pm
by Octocontrabass
I'm not sure what's wrong, I'm not able to reproduce the problem on my compiler. Which compiler are you using? Which compiler options are you using?

Code: Select all

        while(timer_ticks < eticks);
Is that semicolon supposed to be there?

Re: Compiler seems to be ignoring volatile (timer_wait issue

Posted: Wed Mar 08, 2023 11:12 am
by yutani
Thanks for taking time to reply. Sorry for the slow response, this was in the moderation queue for a while then I was working away from home when it got accepted.

I'm using:
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

I appreciate that's a very old version but the initial guide I was using wouldn't compile with the current version in the Ubuntu 20.04 repo. The guide said to downgrade so I did. I suppose the obvious answer would be to upgrade C, but I'd have thought volatile would be a fairly "normal" flag?

The semicolon is a typo from when I copied the code over, it's not in my actual code.

Thanks

Re: Compiler seems to be ignoring volatile (timer_wait issue

Posted: Wed Mar 08, 2023 1:20 pm
by SeaLiteral
yutani wrote: I appreciate that's a very old version but the initial guide I was using wouldn't compile with the current version in the Ubuntu 20.04 repo. The guide said to downgrade so I did. I suppose the obvious answer would be to upgrade C, but I'd have thought volatile would be a fairly "normal" flag?
Thanks
I don't know which versions of GCC handl volatile correctly, but if you think it might be the compiler ignoring it and want to know for sure if that's the case, I guess the first thing you should look at is if it outputs any warnings when trying to compile the code (if it ignores a keyword, it should probably warn about it). Or if you think it might have a bug so it ignores it without warning, you could check the documentation (changelogs of later versions mentioning fixing bugs related to that keyword) or you could ask it to generate assembly output (pass -S filename.s instead of -o filename.o) or you could use objdump to disassemble the generated .o file, but that's kinda unnecessary when you can generate assembly directly from GCC.

(I hope that at least helps figure out if it's the compiler ignoring the keyword. If it is that, perhaps you could try compiling the file with -o0, but I don't know if that would fix it.)

Re: Compiler seems to be ignoring volatile (timer_wait issue

Posted: Wed Mar 08, 2023 1:29 pm
by Octocontrabass
yutani wrote:I appreciate that's a very old version but the initial guide I was using wouldn't compile with the current version in the Ubuntu 20.04 repo. The guide said to downgrade so I did.
That's a bad guide. Ideally, you should switch to a cross-compiler, but it wouldn't hurt to track down the reason why it doesn't compile. If it's a bug, switching to a cross-compiler won't fix it.
yutani wrote:I suppose the obvious answer would be to upgrade C, but I'd have thought volatile would be a fairly "normal" flag?
It is, and it works perfectly fine on my copy of GCC 5.4.

Re: Compiler seems to be ignoring volatile (timer_wait issue

Posted: Thu Mar 09, 2023 9:57 am
by MichaelPetch
I'd be curious - where are you calling timer_wait() from? Are you calling it from inside an interrupt handler or outside an interrupt handler? I could see something like this occurring if you called it from inside an interrupt handler. As an example I remember seeing someone create a command console that was contained inside the keyboard handler routine and experienced this kind of thing because they were running with interrupts off (inside the keyboard interrupt handler) and then didn't actually have the timer firing anymore. In their case they had code inside the keyboard interrupt that would build up strings and then compare it with a known command and then execute some function based on the command. All of this was done inside interrupt context which was a serious design problem that caused his issue.

I think the chances of the compiler (an older GCC 5.4) having a problem with volatile is pretty remote. I'd be considering that this is being caused by something you are doing incorrectly. Do you have a project in Github or some other service so we could look at it?