title: Modify clock interrupt handler xinu
body: <p>I have an operating systems project due tonight, and needed clarification on a topic. We are working with the operating system XINU. I am trying to change the default OS scheduler to account for some processes being starved. I was directed towards the clkint.S file, which I think is the clock interrupt handler. My question is, how do I know how often it interrupts? How do I set the time to lets say make a function call every 5 seconds? I have looked at the intel x86 manuals, but they have an absurd amount of information to sift through, and I am short on time If someone can point me in the right direction, I'd be grateful.</p>
  <p>Here are a couple of files I think necessary:</p>
  <pre><code>clkint.S:
  
      /* clkint.s - _clkint */
  
  #include &lt;icu.s&gt;
          .text
  count1000:  .word   1000
          .globl  sltop
          .globl  clkint
  clkint:
          pushal
          cli
          movb    $EOI,%al
          outb    %al,$OCW1_2
  
          incl    ctr1000
          subw    $1,count1000
          ja  cl1
          incl    clktime
          movw    $1000,count1000
  cl1:
          cmpl    $0,slnonempty   # if no sleeping processes,
          je  clpreem     #   skip to preemption check
          movl    sltop,%eax  # decrement key of first
          decl    (%eax)      #   sleeping process
          jg  clpreem     # must use jg for signed int
          call    wakeup      # if zero, call wakeup
  clpreem:    decl    preempt     # decrement preemption counter
          jg  clret       # must use jg for signed int
          call    resched     # if preemption, call resched
  clret:                  # return from interrupt
          sti
          popal
          iret
  </code></pre>
  <p>clkinit.c:</p>
  <pre class="lang-c prettyprint-override"><code>/* clkinit.c - clkinit */
  
  #include &lt;xinu.h&gt;
  #include &lt;interrupt.h&gt;
  #include &lt;clock.h&gt;
  
  uint32  clktime;        /* seconds since boot           */
  uint32  ctr1000 = 0;        /* milliseconds since boot      */
  qid16   sleepq;         /* queue of sleeping processes      */
  int32   slnempty;       /* zero if the sleep queue is empty;    */
                  /*   non-zero otherwise         */
  int32   *sltop;         /* ptr to key in first entry of sleepq  */
                  /*   if sleepq is not empty     */
  uint32  preempt;        /* preemption counter           */
     
  /*------------------------------------------------------------------------
   * clkinit - initialize the clock and sleep queue at startup
   *------------------------------------------------------------------------
   */
  void    clkinit(void)
  {
      uint16  intv;           /* clock rate in KHz        */
  
      /* Set interrupt vector for clock to invoke clkint */
  
      set_evec(IRQBASE, (uint32)clkint);
  
      /* clock rate is 1.190 Mhz; this is 10ms interrupt rate */
      intv = 1190;
  
      sleepq = newqueue();    /* allocate a queue to hold the delta   */
                  /* list of sleeping processes       */
      preempt = QUANTUM;  /* initial time quantum         */
  
      /* Specify that seepq is initially empty */
  
      slnonempty = FALSE;
  
      clktime = 0;        /* start counting seconds       */
  
      /*  set to: timer 0, 16-bit counter, rate generator mode,
          counter is binary */
      outb(CLKCNTL, 0x34);
  
      /* must write LSB first, then MSB */
      outb(CLOCK0, (char)intv);
      outb(CLOCK0, intv&gt;&gt;8);
      return;
  }
  </code></pre>
  <p>clkhandler.c:</p>
  <pre class="lang-c prettyprint-override"><code>/* clkhandler.c - clkhandler */
  
  #include &lt;xinu.h&gt;
  
  /*------------------------------------------------------------------------
   *  clkhandler - handle clock interrupt and process preemption events
   *          as well as awakening sleeping processes
   *------------------------------------------------------------------------
   */
  interrupt clkhandler(void)
  {
      clkupdate(CLKCYCS_PER_TICK);
  
      /* record clock ticks */
  
      clkticks++;
  
      /* update global counter for seconds */
  
      if (clkticks == CLKTICKS_PER_SEC) {
          clktime++;
          clkticks = 0;
      }
  
      /* If sleep queue is nonempty, decrement first key; when the    */
      /* key reaches zero, awaken a sleeping process          */
  
      if (nonempty(sleepq) &amp;&amp; (--firstkey(sleepq) &lt;= 0)) {
          wakeup();
      }
  
      /* Check to see if this proc should be preempted */
  
      if (--preempt &lt;= 0) {
          preempt = QUANTUM;
          resched();
      }
      return;
  }
  </code></pre>
  <p>I can add all of the starvation functionality on my own, I just need to figure out how to make the clkint.s handler call my function lets say A every 5 seconds...I don't understand how the clock works or the assembly entirely. I am not asking for someone to give me a solution, I just need some guidance.</p>