[En-Nut-Discussion] Preview Fix 060626

Harald Kipp harald.kipp at egnite.de
Tue Jun 27 13:30:59 CEST 2006


Michael,

At 13:00 27.06.2006 +0200, you wrote:

>Therefore, as far as I am concerned the driver is not the problem.

Adding one line to static void NicInterrupt(void *arg) in
arch/avr/dev/lanc111.c

     if (isr & INT_RX_OVRN) {
         imr &= ~INT_RX_OVRN; <------------ This line
         nic_outlb(NIC_ACK, INT_RX_OVRN);
         //nic_outlb(NIC_MMUCR, MMU_TOP);
     }

Replacing

     while (td) {
         qhp = (NUTTHREADINFO **)(td->td_queue);
         if (qhp) {
             cnt = 0;
             for (;;) {
                 NutEnterCritical();
                 cnt += td->td_qpec;
                 td->td_qpec = 0;
                 tqp = *qhp;
                 NutExitCritical();
                 if (cnt == 0 || tqp == SIGNALED) {
                     break;
                 }
                 NutEventPostAsync((HANDLE *)qhp);
                 cnt--;
             }
         }
         td = td->td_next;
     }

by

     while (td) {
         NutEnterCritical();
         cnt = td->td_qpec;
         NutExitCritical();
         if (cnt) {
             qhp = (NUTTHREADINFO **)(td->td_queue);
             NutEnterCritical();
             td->td_qpec--;
             tqp = *qhp;
             NutExitCritical();
             if (tqp != SIGNALED) {
                 NutEventPostAsync((HANDLE *)qhp);
             }
         }
         td = td->td_next;
     }

reduces the context switch. The idea behind this is, that only the
top of the queue needs to be activated.

This is contrary to the demand of alternating threads of the same
priority. However, in this special case it is acceptable.

Harald





More information about the En-Nut-Discussion mailing list