# [ECOS] nc_test_slave.c fix

Grant Edwards grante@visi.com
Fri Apr 7 09:29:00 GMT 2000

```On Thu, Apr 06, 2000 at 05:48:53PM -0600, Gary Thomas wrote:
>
> On 06-Apr-00 Grant Edwards wrote:
> >
> > In the calibrate_load() function in nc_test_slave.c, the while(1)
> > loop will never terminate if percent_load >= desired_load && delta == 1.
> >
> > The code at the end of the loop needs to be changed from
> >
> > to
> >             load_thread_level -= (delta / 2) ? (delta / 2) : 1;
>
> Yes, I've already encountered this (has a lot to do with testing on
> machines of vastly different speeds).  Here's how I changed it:
>
>         } else {
>             if (delta < 0) {
>                 // Trying to decrease load, but haven't gone far enough yet
>                 if (abs(delta) < 2) delta = -2;
>                 delta = abs(delta);
>             }
>         }
>
>
> Does this work for you as well?

Yes, but I think there's still a problem:  when delta==1,

A new option would be:

#define max(a,b) ((a)>(b)?(a):(b))

[...]

} else {
}

Unless I've botched my test program these are the four
algorithms (the number shown in the right hand column is the

delta orig mine yours new

-10   -5   -5    5    5
-9   -4   -4    4    4
-8   -4   -4    4    4
-7   -3   -3    3    3
-6   -3   -3    3    3
-5   -2   -2    2    2
-4   -2   -2    2    2
-3   -1   -1    1    1
-2   -1   -1    1    1
-1    0    1    1    1
0    0    1    0    1
1    0    1    0    1
2    1    1    1    1
3    1    1    1    1
4    2    2    2    2
5    2    2    2    2
6    3    3    3    3
7    3    3    3    3
8    4    4    4    4
9    4    4    4    4
10    5    5    5    5

owever, [there's always a "however"], the other potential
problem is that the loop never terminates because the actual
load is never within +/- 2 of the desired load.  On my target,
to 20%, so the loop terminates.

If the desired value is 25% instead of 20%, the loop doesn't
terminate.

What I would probably do is use a binary search that terminates
when we've gotten as close as we can, independant of the amount
of error in the result:

static void
{
int high=20,low=0;

// Compute the "no load" idle value
cyg_thread_delay(1*100);               // Pause for one second
high=20;
low=0;
while (true)
{

cyg_thread_delay(1*100);               // Pause for one second
test_printf("high=%d, low=%d\n",high,low);

if ((high-low) <= 1)
break;

else
}
}

When the loop terminates, you could add code to see if the
"high" value or the "low" value is closer to the desired result
(if you want to minimize the magnitude of the error).

Or if you care more about the sign of the error than the
magnitude, you just always return one (e.g. if you always want
the actual load to be less than or equal to the desired, use
the "low" value).

--
Grant Edwards
grante@visi.com
```