def run() -> None: """ Loop forever, stepping through scheduled tasks and awaiting I/O events in between. Use `schedule` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. """ if __debug__: global log_delay_pos max_delay = const(1000000) # usec delay if queue is empty task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while _queue or _paused: # compute the maximum amount of time we can wait for a message if _queue: delay = utime.ticks_diff(_queue.peektime(), utime.ticks_us()) else: delay = max_delay if __debug__: # add current delay to ring buffer for performance stats log_delay_rb[log_delay_pos] = delay log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len # process synthetic events if synthetic_events: iface, event = synthetic_events[0] msg_tasks = _paused.pop(iface, ()) if msg_tasks: synthetic_events.pop(0) for task in msg_tasks: _step(task, event) if io.poll(_paused, msg_entry, delay): # message received, run tasks paused on the interface msg_tasks = _paused.pop(msg_entry[0], ()) for task in msg_tasks: _step(task, msg_entry[1]) else: # timeout occurred, run the first scheduled task if _queue: _queue.pop(task_entry) _step(task_entry[1], task_entry[2]) # type: ignore
def run() -> None: """ Loop forever, stepping through scheduled tasks and awaiting I/O events in between. Use `schedule` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. """ task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while _queue or _paused: if __debug__: # process synthetic events if synthetic_events: iface, event = synthetic_events[0] msg_tasks = _paused.pop(iface, ()) if msg_tasks: synthetic_events.pop(0) for task in msg_tasks: _step(task, event) # XXX: we assume that synthetic events are rare. If there is a lot of them, # this degrades to "while synthetic_events" and would ignore all real ones. continue # compute the maximum amount of time we can wait for a message if _queue: delay = utime.ticks_diff(_queue.peektime(), utime.ticks_ms()) else: delay = 1000 # wait for 1 sec maximum if queue is empty if io.poll(_paused, msg_entry, delay): # message received, run tasks paused on the interface msg_tasks = _paused.pop(msg_entry[0], ()) for task in msg_tasks: _step(task, msg_entry[1]) else: # timeout occurred, run the first scheduled task if _queue: _queue.pop(task_entry) _step( task_entry[1], task_entry[2] ) # type: ignore [Argument of type "int" cannot be assigned to parameter "task" of type "Task" in function "_step"]
def run(): ''' Loop forever, stepping through scheduled tasks and awaiting I/O events inbetween. Use `schedule_task` first to add a coroutine to the task queue. Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. ''' if __debug__: global log_delay_pos task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while True: # compute the maximum amount of time we can wait for a message if _scheduled_tasks: delay = utime.ticks_diff( _scheduled_tasks.peektime(), utime.ticks_us()) else: delay = _MAX_SELECT_DELAY if __debug__: # add current delay to ring buffer for performance stats log_delay_rb[log_delay_pos] = delay log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len if io.poll(_paused_tasks, msg_entry, delay): # message received, run tasks paused on the interface msg_tasks = _paused_tasks.pop(msg_entry[0], ()) for task in msg_tasks: _step_task(task, msg_entry[1]) else: # timeout occurred, run the first scheduled task if _scheduled_tasks: _scheduled_tasks.pop(task_entry) _step_task(task_entry[1], task_entry[2])