[En-Nut-Discussion] Fingerprints found at crime site....

Michael Jones Michael.Jones at l-s-b.de
Tue Jun 27 23:42:55 CEST 2006


Hello,

After some serious head banging I found this little peace of DNA at the site
of the crime: "...{.R1-*}{.R1-*}{.RS.O.O.O..." - The forensic lab was in
tumult...

With this little sequence it was possible to locate the exact spot of the
crime and take some quite distinct fingerprints (see:
http://private.l-s-b.de:81/evidence.png).



The simplest way to "fix" this (for verification of problem only) is:

int NutEventWait(volatile HANDLE * qhp, u_long ms)
{
    NUTTHREADINFO *tdp;
    
    /* Get the queue's root atomically. */

    NutEnterCritical();		// <===================== Patch
    tdp = *qhp;

    /*
     * Check for posts on a previously empty queue. 
     */
    if (tdp == SIGNALED) {
        /*
         * Even if already signaled, switch to any other thread, which 
         * is ready to run and has the same or higher priority.
         */
        *qhp = 0;
	  NutExitCritical();	// <===================== Patch
        
        NutThreadYield();
        return 0;
    }
    /*
     * Remove the current thread from the list of running threads 
     * and add it to the specified queue.
     */
    NutThreadRemoveQueue(runningThread, &runQueue);
    NutThreadAddPriQueue(runningThread, (NUTTHREADINFO **) qhp);

    NutExitCritical();		// <===================== Patch

	.
	.
	.

But, as the problem is in NutThreadAddPriQueue(...) I propose the following
less Critical-Section intensive version (which possibly can be further
refined):

void NutThreadAddPriQueue(NUTTHREADINFO * td, NUTTHREADINFO * volatile
*tqpp)
{
    NUTTHREADINFO *tqp;

    td->td_queue = (HANDLE) tqpp;
    td->td_qpec = 0;			// start with clean event count

    NutEnterCritical();
    tqp = *tqpp;

    if (tqp == SIGNALED) {
        tqp = 0;
        td->td_qpec++;			// transfer the signaled state 
    } else if (tqp) {
        NutExitCritical();		// there are other threads in queue
						// so its save to leave
critical.          

        while (tqp && tqp->td_priority <= td->td_priority) {
            tqpp = &tqp->td_qnxt;
            tqp = tqp->td_qnxt;
        }

        NutEnterCritical();		// back into critical
    }

    td->td_qnxt = tqp;

    *tqpp = td;
    if (td->td_qnxt && td->td_qnxt->td_qpec) {
        td->td_qpec += td->td_qnxt->td_qpec; // don't overwrite count
        td->td_qnxt->td_qpec = 0;
    }
    NutExitCritical();
}

With this change I feel confident that we have finally got to the bottom of
the problem! Bashing the OS with massive amounts of ARP & Random packets
(about 25% utilization of 100Mbps) has virtually no effect any more - just
the to be expected decrease of throughput (actually one of our Linux
machines stopped dead during the test - probably something that it ate).



Cu,
Michael






More information about the En-Nut-Discussion mailing list