Commit 08e250b8 authored by Adam Wujek's avatar Adam Wujek 💬

userspace/libwr: use predefined constant for loops_per_msec

Our software runs only on a single kind of CPU, so we don't need to calculate
it at every boot. The way how daemons are spawned at boot changed
since the function shw_udelay_init was written. Before daemons were spawned one
after another, now they are spawned at the same time and compete during
initialization phase for the CPU.
The loop calculating loops_per_msec was interrupted by few context switches.
When using the kernel 2.6.39, the problem was not visible and usually
loops_per_msec was estimated correctly.
However, introduction new kernel 3.16 lowered probability of getting
correct results. Probably due to the different behaviour of the scheduler.
Bug was found because HAL was not able to detect SFP with
vn=ZyXEL
pn=SFP-BX1310-10-D
vs=S131151000226
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent ecde84a6
......@@ -13,6 +13,31 @@ void shw_udelay_init(void)
volatile int i;
int j, cur, min = 0;
uint64_t tv1, tv2;
/*
* The kernel's scheduler is triggered 1000 times a second, to avoid
* a problem with a context switching, one iteration of loop with "j"
* should be shorter that a half of a scheduler's period.
* Based on the previous calculations that one iteration is about
* 5 CPU instructions (comment at the end of this function, our loop
* shall be shorter than:
* 197000000 / (5 * 1000 * 2) = 19 700
* Before it was 100*1000.
*
* However, at the system call triggered by get_monotonic_us() there
* is a context switch. If there are more processes waiting for the CPU
* (like during the boot, when few daemons are spawned at the same
* time) computations in this function can be underestimated by a
* factor 2-3 (experimental value).
*/
loops_per_msec = 39400;
return;
/*
* If we change the CPU this code can be used to estimate
* loops_per_msec, but should not be run avery time.
*/
for (j = 0; j < 10; j++) {
tv1 = get_monotonic_us();
for (i = 0; i < 100*1000; i++)
......@@ -27,6 +52,7 @@ void shw_udelay_init(void)
if (0)
printf("loops per msec %i\n", loops_per_msec);
/*
* I get 39400 more or less; it makes sense at 197 bogomips.
* The loop is 6 instructions with 3 (cached) memory accesses
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment