sleep function freezing

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
User avatar
apadayo
Posts: 2
Joined: Tue Nov 30, 2010 3:55 pm

sleep function freezing

Post by apadayo »

Hi, I have been working on my own small OS just on the side and I ran into a problem while adding a sleep() function to wait while the FDD motor spins up. When you call the sleep function, IRQ 0 seems to stop firing and the while loop never ends because the timer count is never increased to the point where the while loop would end.

Here is my code

Code: Select all

/* This will keep track of how many ticks that the system
*  has been running for */
volatile int timer_ticks = 0;

/* IRQ 0 Handler */
void timer_handler(struct regs *r)
{
    /* Increment our 'tick count' */
    timer_ticks++;
	if(timer_ticks % 1000 == 0)
	{
		printf("one second has passed\n");
	}
}

/* Sleep function that doesn't work */
void sleep(int ticks)
{
    unsigned long sleep_ticks = timer_ticks + ticks;
    while(timer_ticks < sleep_ticks);
}
As you can see, the code is supposed to output the "one second has passed" message every second. This stops happening the second I call the sleep function from the built in command line.

The IRQ handler is called from a stub function in another file.

Code: Select all

void irq_handler(struct regs *r)
{
    /* This is a blank function pointer */
    void (*handler)(struct regs *r);

    /* Find out if we have a custom handler to run for this
    *  IRQ, and then finally, run it */
    handler = irq_routines[r->int_no - 32];
    if (handler)
    {
        handler(r);
    }

    /* If the IDT entry that was invoked was greater than 40
    *  (meaning IRQ8 - 15), then we need to send an EOI to
    *  the slave controller */
    if (r->int_no >= 40)
    {
        outportb(0xA0, 0x20);
    }

    /* In either case, we need to send an EOI to the master
    *  interrupt controller too */
    outportb(0x20, 0x20);
	asm("sti");
}
This in turn is called by an assembly stub (the IRQ specific code is set before hand)

Code: Select all

irq_common_stub:
    pusha
    push ds
    push es
    push fs
    push gs

    mov ax, 0x10
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp

    push eax
    mov eax, _irq_handler
    call eax
    pop eax

    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8
    iret
IRQ0 example

Code: Select all

; 32: IRQ0
_irq0:
    cli
    push byte 0
    push byte 32
    jmp irq_common_stub
If anyone can spot an error in the code, or explain what I am doing wrong, that would be great.
Regards,
apadayo
Duct tape is like the force. It has a light side and a dark side and holds the universe together.
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: sleep function freezing

Post by NickJohnson »

Are you calling that sleep() functions with interrupts on or off? If they're off (which is the usual case when in another interrupt handler), then the IRQ won't fire while the loop is running, and therefore the loop will never end. In order to get the scheme you have to work, you're going to need to allow some sort of nested interrupt handling, which I don't think your setup can support (if it's based off of JamesM's tutorial as I suspect.)
User avatar
apadayo
Posts: 2
Joined: Tue Nov 30, 2010 3:55 pm

Re: sleep function freezing

Post by apadayo »

Thanks! It was a stupid mistake. I forgot to re enable interrupts before the loop started because the sleep() call was from the keyboard interrupt handler for the enter key.
Duct tape is like the force. It has a light side and a dark side and holds the universe together.
Post Reply