| EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | ||||
| static void runFromYield() { | static void runFromYield() { | ||||
| // First, check if yield was called from an interrupt | |||||
| // never call normal handler functions from any interrupt context | |||||
| uint32_t ipsr; | |||||
| __asm__ volatile("mrs %0, ipsr\n" : "=r" (ipsr)::); | |||||
| if (ipsr != 0) return; | |||||
| // Next, check if any events have been triggered | |||||
| EventResponder *first = firstYield; | EventResponder *first = firstYield; | ||||
| // FIXME: also check if yield() called from an interrupt | |||||
| // never run these functions from any interrupt context | |||||
| if (first && !runningFromYield) { | |||||
| runningFromYield = true; | |||||
| firstYield = first->_next; | |||||
| if (firstYield) { | |||||
| firstYield->_prev = nullptr; | |||||
| } else { | |||||
| lastYield = nullptr; | |||||
| } | |||||
| first->_pending = false; | |||||
| (*(first->_function))(*first); | |||||
| runningFromYield = false; | |||||
| if (first == nullptr) return; | |||||
| // Finally, make sure we're not being recursively called, | |||||
| // which can happen if the user's function does anything | |||||
| // that calls yield. | |||||
| if (runningFromYield) return; | |||||
| // Ok, update the runningFromYield flag and process event | |||||
| runningFromYield = true; | |||||
| firstYield = first->_next; | |||||
| if (firstYield) { | |||||
| firstYield->_prev = nullptr; | |||||
| } else { | |||||
| lastYield = nullptr; | |||||
| } | } | ||||
| first->_pending = false; | |||||
| (*(first->_function))(*first); | |||||
| runningFromYield = false; | |||||
| } | } | ||||
| static void runFromInterrupt(); | static void runFromInterrupt(); | ||||
| operator bool() { return _pending; } | operator bool() { return _pending; } |