“Intellectuals solve problems; geniuses prevent them.” Albert Einstein
This profound quote says very succinctly where and how we should focus our efforts. How many of us are guilty of writing firmware and then getting it to work without thorough testing? Are we likely to make a change to the code then throw it at the test team to see if anything broke? Or, in our work, do we try to plan ahead and anticipate any problems that may occur?
I was working with event timing in a printer and needed to determine which of two printing events occurred first, Event A or Event B. Event timestamps are obtained in ticks, where 1 tick = 1 ms. I can compare the two timestamps and know which came first, like this:
if (eventA < eventB) eventA occurred first else eventB occurred first (or at the same time)
For this printer, event timestamps are of type uint32, which means the tick count can get as high as 4,294,967,295 ms, or approximately 49.7 days. It is conceivable that a printer is left on for that long (hopefully it is a green printer), so that after 49.7 days, the tick counter is going to roll over to zero to continue counting. Suppose that eventA=0xFFFFFFFA, just before a rollover, and eventB=0x00000007, just after the rollover. Using the above if() statement, it will appear that eventB occurred first because it is a smaller number. Of course, that is wrong.
But, how likely is it to occur? Not very. Only once every 50 days, and only if it happens to be printing a page during that time, and only if those two events happen to straddle the rollover. If it does happen while printing a page, it is not life threatening. So maybe it doesn’t matter and we don’t need to worry about it. But we don’t want to be that careless in a pacemaker or an airplane flight system.
Even though this printer is not a safety-critical device, I still recognized a potential quality and customer satisfaction problem and wanted to prevent it from occurring. This is one possible solution to prevent that problem:
if ((int32)(eventB – eventA) > 0) eventA occurred first else eventB occurred first (or at the same time)
By subtracting A from B and converting it to a signed value, I can test if it is greater or less than zero. This will produce the correct results even if the two events straddle the rollover. This technique does, however, expose a different problem; this will produce incorrect results if the two events are more that 25 days apart. However, since I know it never, ever, ever takes a printer 25 days to print one page, then that will never be a problem. Of course, it would be wise to document that assumption in the comments.
Following Einstein’s implied advice, let us be better than intellectuals that solve problems. Let us be geniuses and prevent them.
Until my next genius newsletter…