Compiler seems to be ignoring volatile (timer_wait issue)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
yutani
Posts: 3
Joined: Tue Feb 21, 2023 10:38 am
Libera.chat IRC: chainbits

Compiler seems to be ignoring volatile (timer_wait issue)

Post 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
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: Compiler seems to be ignoring volatile (timer_wait issue

Post 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?
yutani
Posts: 3
Joined: Tue Feb 21, 2023 10:38 am
Libera.chat IRC: chainbits

Re: Compiler seems to be ignoring volatile (timer_wait issue

Post 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
User avatar
SeaLiteral
Posts: 19
Joined: Wed Sep 27, 2017 1:44 pm

Re: Compiler seems to be ignoring volatile (timer_wait issue

Post 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.)
Last edited by SeaLiteral on Wed Mar 08, 2023 1:37 pm, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5562
Joined: Mon Mar 25, 2013 7:01 pm

Re: Compiler seems to be ignoring volatile (timer_wait issue

Post 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.
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Compiler seems to be ignoring volatile (timer_wait issue

Post 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?
Post Reply