| /* |
| * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include <string.h> |
| #include "pico/async_context_poll.h" |
| #include "pico/async_context_base.h" |
| #include "pico/sync.h" |
| |
| static void noop(__unused async_context_t *context) { } |
| |
| static const async_context_type_t template; |
| |
| bool async_context_poll_init_with_defaults(async_context_poll_t *self) { |
| memset(self, 0, sizeof(*self)); |
| self->core.core_num = get_core_num(); |
| self->core.type = &template; |
| self->core.flags = ASYNC_CONTEXT_FLAG_POLLED | ASYNC_CONTEXT_FLAG_CALLBACK_FROM_NON_IRQ; |
| sem_init(&self->sem, 1, 1); |
| return true; |
| } |
| |
| static void async_context_poll_wake_up(async_context_t *self_base) { |
| sem_release(&((async_context_poll_t *)self_base)->sem); |
| } |
| |
| static void async_context_poll_requires_update(async_context_t *self_base, async_when_pending_worker_t *worker) { |
| worker->work_pending = true; |
| async_context_poll_wake_up(self_base); |
| } |
| |
| static void async_context_poll_poll(async_context_t *self_base) { |
| async_context_base_execute_once(self_base); |
| } |
| |
| static void async_context_poll_wait_until(__unused async_context_t *self_base, absolute_time_t until) { |
| sleep_until(until); |
| } |
| |
| static void async_context_poll_wait_for_work_until(async_context_t *self_base, absolute_time_t until) { |
| absolute_time_t next_time = self_base->next_time; |
| async_context_poll_t *self = (async_context_poll_t *)self_base; |
| sem_acquire_block_until(&self->sem, absolute_time_min(next_time, until)); |
| } |
| |
| static void async_context_poll_lock_check(async_context_t *self_base) { |
| if (__get_current_exception() || get_core_num() != self_base->core_num) { |
| panic("async_context_poll context check failed (IRQ or wrong core)"); |
| } |
| } |
| |
| uint32_t async_context_poll_execute_sync(__unused async_context_t *context, uint32_t (*func)(void *param), void *param) { |
| return func(param); |
| } |
| |
| static const async_context_type_t template = { |
| .type = ASYNC_CONTEXT_POLL, |
| .acquire_lock_blocking = noop, |
| .release_lock = noop, |
| .lock_check = async_context_poll_lock_check, |
| .execute_sync = async_context_poll_execute_sync, |
| .add_at_time_worker = async_context_base_add_at_time_worker, |
| .remove_at_time_worker = async_context_base_remove_at_time_worker, |
| .add_when_pending_worker = async_context_base_add_when_pending_worker, |
| .remove_when_pending_worker = async_context_base_remove_when_pending_worker, |
| .set_work_pending = async_context_poll_requires_update, |
| .poll = async_context_poll_poll, |
| .wait_until = async_context_poll_wait_until, |
| .wait_for_work_until = async_context_poll_wait_for_work_until, |
| .deinit = noop, |
| }; |