12th-day timer for 30-day self-made OS

Source: Internet
Author: User

The timer interrupt processing program must be optimized to ensure high efficiency. The optimization method is described here. For an operating system, there will be multiple timers. Assuming that the operating system maintains 500 timers, when each scheduled interruption occurs (Here we set 100 interruptions in one second ), when the interrupt handler is called, the interrupt handler will determine if for the 500 timers to see which ones are being used. In this way, 500x100 = 10000 if queries will be made within one second, however, the interrupt handler is time-saving. In fact, we don't have to judge the 500 timers every time a scheduled interruption occurs. For example, if we use 10 of the 500 timers, and the minimum timeout value of the 10 timers is 10 s, that is, the first timer is triggered after 10 s, and within 10 s, 10000x10 = 0.1 million useless if judgments will be made. If the 0.1 million if judgments can be omitted, the performance will be greatly improved. The optimization strategy adopted here is: we maintain a next chain, that is, 10 timer in use form the next chain according to the time-out period from small to large, next indicates the minimum timeout time (10 s in this example). In this case, each call to the interrupt handler compares the current time count with next. If count <next, it indicates that there is no time-out at this time, so you do not have to judge the 500 timers. If Count = next, it indicates that the timer with the minimum timeout time has reached the timeout time in the currently used and no time-out timer. Next, let the timer time-out and select the next, that is, the timeout time of the remaining timer that is in use and has no timeout. In this way, with the passage of time, each interruption, count is added with 1, count will encounter each timeout time in the next chain, once encountered, it means that there is a timer to time out, if it is not met, it means that no timer will time out, saving a lot of useless if judgments. The following is an optimized scheduled interrupt handler:

// when IRQ0(timer interrupt) happens, invoke the interrupt handler: inthandler20void inthandler20(int *esp){io_out8(PIC0_OCW2, 0x60); // Inform PIC the information that IRQ0-00 has been received.timerctl.count++; // each second it adds 100if (timerctl.next > timerctl.count) {return; // the next time has not arrived, so finish}timerctl.next = 0xffffffff;int i;for (i = 0; i < MAX_TIMER; i++) {if (timerctl.timer[i].flags == TIMER_FLAGS_USING) {if (timerctl.timer[i].timeout <= timerctl.count) {// timeout timerctl.timer[i].flags = TIMER_FLAGS_ALLOC;fifo8_put(timerctl.timer[i].fifo, timerctl.timer[i].data);} else {// not timeoutif (timerctl.next > timerctl.timer[i].timeout) {timerctl.next = timerctl.timer[i].timeout; // elect the next time of timeout}}}}return;}

In fact, our optimization work is not over yet. The scheduled interruptions between the arrival of count at the next time and the arrival of the next time are very different in the processing time (if we do not get to the next time, we will execute only one judgment and return, when next is reached, 500 timers must be judged ). The program structure is not good. Because programs that run very fast often occasionally drag Too long due to interrupt processing, it seems like the main program is about to stop, more specifically, this sometimes makes people feel "Somehow, the mouse is occasionally slow, very slow", because at this time the processor is busy timing interrupt processing programs to determine if 500 timers. Therefore, we need to shorten the processing time of timer interruption at the next time. We maintain an array of timers, which only stores the address of the timer currently in use and has not timed out. When the next time is reached, we no longer need to judge the 500 timers, you only need to judge the timer in the timers array to see which timer times out, and then shift the timers array again to remove the timer that just timed out. The scheduled interrupt processing program after optimization is as follows:

// when IRQ0(timer interrupt) happens, invoke the interrupt handler: inthandler20void inthandler20(int *esp){int i, j;io_out8(PIC0_OCW2, 0x60); // Inform PIC the information that IRQ0-00 has been received.timerctl.count++; // each second it adds 100if (timerctl.next > timerctl.count) {return; // the next time has not arrived, so finish}// checking in all of the timers which are being used, which timer time out.// now we do not have to do MAX_TIMER times of 'if'for (i = 0; i < timerctl.using; i++) {if (timerctl.timers[i]->timeout > timerctl.count) {break;}// timeouttimerctl.timers[i]->flags = TIMER_FLAGS_ALLOC;fifo8_put(timerctl.timers[i]->fifo, timerctl.timers[i]->data);}// a timer has timed out, we need shift the rest using timertimerctl.using -= i;for (j = 0; j < timerctl.using; j++) {timerctl.timers[j] = timerctl.timers[i + j];}if (timerctl.using > 0) {timerctl.next = timerctl.timers[0]->timeout;} else {timerctl.next = 0xffffffff;}return;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.