/* Timer interrupt handler. * To receive the scheduled interrupt, the software must have previously enabled the corresponding * IRQ line using the BCM2835 interrupt controller. */ static void timer_irq_handler(struct interrupts_stack_frame *stack_frame) { // printf("\nKernel - Timer Interrupt Handler."); // The System Timer compare has to be reseted after the timer interrupt. timer_reset_timer_compare(IRQ_1); thread_tick(stack_frame); //timer_msleep(1000000); timer_msleep(300000); // The System Timer compare register has to be set up with the new time after the timer interrupt. timer_set_interval(IRQ_1, TIMER_PERIODIC_INTERVAL); }
/* Briefly beep the PC speaker. */ void speaker_beep (void) { /* Only attempt to beep the speaker if interrupts are enabled, because we don't want to freeze the machine during the beep. We could add a hook to the timer interrupt to avoid that problem, but then we'd risk failing to ever stop the beep if Pintos crashes for some unrelated reason. There's nothing more annoying than a machine whose beeping you can't stop without a power cycle. We can't just enable interrupts while we sleep. For one thing, we get called (indirectly) from printf, which should always work, even during boot before we're ready to enable interrupts. */ if (intr_get_level () == INTR_ON) { speaker_on (440); timer_msleep (250); speaker_off (); } }
static void clock_daemon(void *aux) { // printf("starting clock\n"); struct frame *head, *tail; bool got_frame = false; /* while(true) thread_yield();*/ // sema_down(&clockwaiting); // int i; while(1) { // printf("locking\n"); lock_acquire(&clocklock); // printf("Checking list is empty\n"); if(list_empty(&clocklist)) { // printf("Releasing lock\n"); lock_release(&clocklock); // printf("Sleeping\n"); timer_msleep(CLOCK_WAIT_MS); // thread_yield(); // printf("Woke up\n"); continue; } // printf("List is not empty\n"); if(clockmodified) { // printf("clockmodified"); head = tail = get_clock_frame(list_begin(&clocklist)); // i = 0; } // printf("clock got lock\n"); for(int i = 0; i < CLOCK_DIFF_COUNT; i++) { // printf("in for loop"); // if(!clockmodified) // i = CLOCK_WAIT_COUNT; // printf("clock on frame %p: checking semaphore at %p\n", current, ¤t->evicting); /* Clear head's accessed bit. */ if(lock_try_acquire(&head->evicting)) { // printf("\t\tgot head sema\n"); pagedir_set_accessed(head->page->thread->pagedir, head->page->vaddr, false);//TODO check if it is being moved lock_release(&head->evicting); } /* If clock hands have reached proper angle, use tail hand. */ if(!clockmodified/*i >= CLOCK_WAIT_COUNT*/) { /* Check if frame has been changed accessed since head passed. */ if(lock_try_acquire(&tail->evicting)) { if(!pagedir_is_writeable/*accessed*/(tail->page->thread->pagedir, tail->page->vaddr)) { /* Wait for clock frame to be cleared then set it to tail. */ // if(sema_try_down(&clockwaiting)) lock_acquire(&clockcondlock); if(clockwaiters > 0 && clockrecieved) { printf("Found non accessed dir\n"); clock_frame = tail; clockrecieved = false; got_frame = true; cond_signal(&clockwaiting, &clockcondlock); } lock_release(&clockcondlock); // sema_up(&clockready); // break; // } } if(!got_frame) { lock_release(&tail->evicting); } else { got_frame = true; } } tail = get_next_clock_frame(tail); } // printf("getting next frame\n"); head = get_next_clock_frame(head); // printf("sleeping\n"); } clockmodified = false; lock_release(&clocklock); timer_msleep(CLOCK_WAIT_MS); // thread_yield(); } PANIC("Frame eviction daemon quit!\n"); }