-1

I am making a kernel from scratch in c (Not linux. COMPLETELY from scratch) and I have come along a bit of a problem. I have this code:

#include "timer.h"
int ms = 0;
void timer_handler(struct regs *r){
    ms++;
    println("I print every tick");
}
void sleep(int ticks){
    unsigned long eticks;

    eticks = ms + ticks;
    while(ms < eticks);
}

And timer_handler is attached to IRQ0 (The PIT) and works perfectly fine. The println that says "I print every tick" works just fine, and If I print the ms variable in my code, it prints the correct amount. But, If I call the sleep function, the timer_handler stops firing and it gets stuck in an infinite loop. Is there any way I can allow interrupts to fire while in a while loop?

REST OF CODE: https://github.com/Codepixl/CodeOS

ByteDuck
  • 1,821
  • 3
  • 15
  • 27
  • It's YOUR OS code - cannot you work it out? For one thing, I cannot see how 'sleepc' ever changes from -1. If ticks is passed into sleep() as 0, then eticks==ms and, since ms is continually increasing, the while loop will not exit ,(for a very long time). I/O calls like println() are also usually very difficult to arrange to be safe in interrupts. – Martin James Jul 09 '15 at 03:03
  • @MartinJames oh, sorry about the sleepc part, that was old code. I edited it out. Also, how this works is: if ms = 1000 and i want to sleep for 500, then eticks will equal 1500. So once ms is 1500, it will exit, so that will be 500ms of wait time. I know for sure it isn't firing the interrupt, because if i print ms in my while loop, it stays the same. I have been trying different methods for about 1hr by myself now. – ByteDuck Jul 09 '15 at 03:09
  • You should use a volatile for ms. The compiler has no idea that it is changing. – Martin James Jul 09 '15 at 03:27
  • Also, that is a non-optimal method of achieving sleep() functionality. Usually, the calling thread is removed from execution and a thread control block pointer is placed in a delta-queue, ordered by by expiry-tick-count, so that the timer only has to examine the queue head at each interrupt, no matter how many sleep() calls are in progress. – Martin James Jul 09 '15 at 03:33
  • ..but I have no idea how your interrupt is getting disabled, (if it is). I assume that you are not calling sleep() from another interrupt-handler without re-enabling higher-priority interrupts, (assuming the timer has a higher priority)? – Martin James Jul 09 '15 at 03:36
  • @MartinJames Correct. I am just calling it from the main function of my kernel. Also, volatile didn't work. All I want the sleep function to do is to halt everything happening (Hence the while loop), and once the loop finishes, the code keeps going. (I only have one thread) – ByteDuck Jul 09 '15 at 03:41
  • OK, I'm officially baffled. I have no clue:( – Martin James Jul 09 '15 at 12:07

2 Answers2

0

It sounds like you are not sending the end of interrupt. You need to do an outb(0x20,0x20) (port and data value are the same so it doesn't matter how you have defined outb) for IRQ0 in your interrupt handler. If you are getting only one interrupt, from your question it is not clear if you are getting any interrupts or not, then this is most likely your problem. If not post all the relevant code, e.g. where you are setting up your IDT.

If this is not the case one simple thing you can do to debug is to cause a software interrupt via the int instruction for the corresponding IDT. If that works then it has something to do with the PIC or PIT and not your IDT entry.

Also as others have mentioned you should make ms volatile or use a barrier so the compiler doesn't optimize reading the value. I don't think this is your problem though as you would still be seeing multiple prints if the timer interrupt was occurring.

missimer
  • 4,022
  • 1
  • 19
  • 33
  • I am sending the EOI elswhere in my code, but I'll try that. Another thing is that I'm running this in virtualbox, so I'll try running it on my actual PC to see if it's just VirtualBox. – ByteDuck Jul 09 '15 at 15:19
  • @user3042719 if you add more relevant code I might be able to help – missimer Jul 09 '15 at 15:21
  • I have my source code up on github. (I don't have the timer function on there yet, but the rest of my code is) Just please be aware the a lot of my code is very inefficient because I'm a beginner :). I edited my main post to include the link. Thanks! – ByteDuck Jul 09 '15 at 15:30
  • @user3042719 posting your code to github makes your question and the answers unusable to all future people who visit this page (who knows you might delete the repo at some time and the code is most likely going to change). Please add all relevant code to your question. – missimer Jul 09 '15 at 15:33
  • I actually just figured it out now. It was virtualBox for some reason. It worked on my actual machine, so I'll have to look into that later. Thanks for your help! – ByteDuck Jul 09 '15 at 15:35
0

It was just virtualbox for some reason, it works on my actual PC.

ByteDuck
  • 1,821
  • 3
  • 15
  • 27