[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