Skip to content

millis() timeouts not wrap-safe #742

@PaulZC

Description

@PaulZC

As reported by Clive:

} while (isBlocking && (millis() < (start + waitForSemaphoreTimeout_millis)));

needs to be of the form

} while (isBlocking && ((millis() - start) < waitForSemaphoreTimeout_millis));

Tricky to test using millis()... The wrap occurs at 49.71 days (2^32 seconds).

Testing on ESP32 (Arduino esp32 v3.0.7):

unsigned long sfeMillis = 0xFFFFFFF8;
unsigned long sfeStart;
const unsigned long sfeTimeout = 0x10;

void setup() {
  delay(1000);
  Serial.begin(115200);
  sfeStart = sfeMillis;
}

void loop() {
  Serial.printf("%lu %lu %lu %d\r\n",
    sfeStart,
    sfeTimeout,
    sfeMillis,
    ((sfeMillis - sfeStart) < sfeTimeout));

  sfeMillis = sfeMillis + 1;
  
  delay(1000);
}

produces:

09:42:46.864 -> 4294967288 16 4294967289 1
09:42:47.822 -> 4294967288 16 4294967290 1
09:42:48.831 -> 4294967288 16 4294967291 1
09:42:49.838 -> 4294967288 16 4294967292 1
09:42:50.845 -> 4294967288 16 4294967293 1
09:42:51.855 -> 4294967288 16 4294967294 1
09:42:52.862 -> 4294967288 16 4294967295 1
09:42:53.821 -> 4294967288 16 0 1
09:42:54.829 -> 4294967288 16 1 1
09:42:55.834 -> 4294967288 16 2 1
09:42:56.839 -> 4294967288 16 3 1
09:42:57.844 -> 4294967288 16 4 1
09:42:58.848 -> 4294967288 16 5 1
09:42:59.854 -> 4294967288 16 6 1
09:43:00.857 -> 4294967288 16 7 1
09:43:01.863 -> 4294967288 16 8 0
09:43:02.821 -> 4294967288 16 9 0
09:43:03.829 -> 4294967288 16 10 0
09:43:04.835 -> 4294967288 16 11 0
09:43:05.836 -> 4294967288 16 12 0
09:43:06.837 -> 4294967288 16 13 0
09:43:07.840 -> 4294967288 16 14 0
09:43:08.844 -> 4294967288 16 15 0

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions