Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
mbed_Fixes/ticker_api_fix.c@116:7a67265d7c19, 2021-10-01 (annotated)
- Committer:
- arnoz
- Date:
- Fri Oct 01 08:19:46 2021 +0000
- Revision:
- 116:7a67265d7c19
- Parent:
- 79:682ae3171a08
- Correct information regarding your last merge
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 79:682ae3171a08 | 1 | #include <stddef.h> |
mjr | 79:682ae3171a08 | 2 | #include "ticker_api.h" |
mjr | 79:682ae3171a08 | 3 | |
mjr | 79:682ae3171a08 | 4 | void $Sub$$ticker_insert_event(const ticker_data_t *const data, ticker_event_t *obj, timestamp_t timestamp, uint32_t id) { |
mjr | 79:682ae3171a08 | 5 | /* disable interrupts for the duration of the function */ |
mjr | 79:682ae3171a08 | 6 | __disable_irq(); |
mjr | 79:682ae3171a08 | 7 | |
mjr | 79:682ae3171a08 | 8 | // initialise our data |
mjr | 79:682ae3171a08 | 9 | obj->timestamp = timestamp; |
mjr | 79:682ae3171a08 | 10 | obj->id = id; |
mjr | 79:682ae3171a08 | 11 | |
mjr | 79:682ae3171a08 | 12 | /* Go through the list until we either reach the end, or find |
mjr | 79:682ae3171a08 | 13 | an element this should come before (which is possibly the |
mjr | 79:682ae3171a08 | 14 | head). */ |
mjr | 79:682ae3171a08 | 15 | ticker_event_t *prev = NULL, *p = data->queue->head; |
mjr | 79:682ae3171a08 | 16 | while (p != NULL) { |
mjr | 79:682ae3171a08 | 17 | /* check if we come before p */ |
mjr | 79:682ae3171a08 | 18 | if ((int)(timestamp - p->timestamp) < 0) { |
mjr | 79:682ae3171a08 | 19 | break; |
mjr | 79:682ae3171a08 | 20 | } |
mjr | 79:682ae3171a08 | 21 | /* go to the next element */ |
mjr | 79:682ae3171a08 | 22 | prev = p; |
mjr | 79:682ae3171a08 | 23 | p = p->next; |
mjr | 79:682ae3171a08 | 24 | } |
mjr | 79:682ae3171a08 | 25 | |
mjr | 79:682ae3171a08 | 26 | /* if we're at the end p will be NULL, which is correct */ |
mjr | 79:682ae3171a08 | 27 | // BUG FIX: do this BEFORE calling set_interrupt(), to ensure |
mjr | 79:682ae3171a08 | 28 | // that the list is in a consistent state if set_interrupt() |
mjr | 79:682ae3171a08 | 29 | // happens to call the event handler, and the event handler |
mjr | 79:682ae3171a08 | 30 | // happens to call back here to re-queue the event. Such |
mjr | 79:682ae3171a08 | 31 | // things aren't hypothetical: this exact thing will happen |
mjr | 79:682ae3171a08 | 32 | // if a Ticker object gets more than one cycle behind. The |
mjr | 79:682ae3171a08 | 33 | // inconsistent state of the list caused crashes. |
mjr | 79:682ae3171a08 | 34 | obj->next = p; |
mjr | 79:682ae3171a08 | 35 | |
mjr | 79:682ae3171a08 | 36 | /* if prev is NULL we're at the head */ |
mjr | 79:682ae3171a08 | 37 | if (prev == NULL) { |
mjr | 79:682ae3171a08 | 38 | data->queue->head = obj; |
mjr | 79:682ae3171a08 | 39 | data->interface->set_interrupt(timestamp); |
mjr | 79:682ae3171a08 | 40 | } else { |
mjr | 79:682ae3171a08 | 41 | prev->next = obj; |
mjr | 79:682ae3171a08 | 42 | } |
mjr | 79:682ae3171a08 | 43 | |
mjr | 79:682ae3171a08 | 44 | __enable_irq(); |
mjr | 79:682ae3171a08 | 45 | } |
mjr | 79:682ae3171a08 | 46 |