/* * Copyright (C) 2019 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup tests * @{ * * @file * @brief Test application to test event wait timeout * * @author Hauke Petersen * * @} */ #include #include #include #include "event.h" #include "thread.h" #include "xtimer.h" #include "thread_flags.h" #define STATIC_TIMEOUT (10U * US_PER_MS) /* 10ms */ #define TIMEOUT (50U * US_PER_MS) /* 50ms */ #define PRIO (THREAD_PRIORITY_MAIN - 5) #define STACKSIZE (THREAD_STACKSIZE_DEFAULT) #define FLAG_SYNC (0x0040) static void _on_evt(event_t *evt); static event_queue_t _evtq; static event_t _evt = { .handler = _on_evt }; static char _stack[STACKSIZE]; static thread_t *_thread_main; static atomic_uint _wakeup_evt = ATOMIC_VAR_INIT(0); static atomic_uint _wakeup_timeout = ATOMIC_VAR_INIT(0); static void _on_evt(event_t *evt) { (void)evt; atomic_fetch_add(&_wakeup_evt, 1); } static void *_cnt_thread(void *arg) { (void)arg; event_queue_init(&_evtq); while (1) { event_t *evt = event_wait_timeout(&_evtq, TIMEOUT); if (evt) { evt->handler(evt); } else { atomic_fetch_add(&_wakeup_timeout, 1); } } return NULL; } int main(void) { /* setup */ _thread_main = thread_get_active(); puts("[START] event_wait_timeout test application.\n"); /* test 'instant' return */ event_queue_t tmp_eq = EVENT_QUEUE_INIT; event_t *tmp_evt = event_wait_timeout(&tmp_eq, 0); if (tmp_evt != NULL) { puts("[FAILED]"); return 1; } tmp_evt = event_wait_timeout64(&tmp_eq, 0); if (tmp_evt != NULL) { puts("[FAILED]"); return 1; } /* test return in a predefined amount of time */ puts("waiting for event with 10ms timeout..."); uint32_t before = xtimer_now_usec(); tmp_evt = event_wait_timeout(&tmp_eq, STATIC_TIMEOUT); if (tmp_evt != NULL) { puts("[FAILED]"); return 1; } uint32_t diff = xtimer_now_usec() - before; printf("event_wait time out after %"PRIu32"us\n", diff); puts("waiting for event with 10ms timeout (using uint64)..."); uint64_t static_timeout = STATIC_TIMEOUT; before = xtimer_now_usec(); tmp_evt = event_wait_timeout64(&tmp_eq, static_timeout); if (tmp_evt != NULL) { puts("[FAILED]"); return 1; } diff = xtimer_now_usec() - before; printf("event_wait time out after %"PRIu32"us\n", diff); thread_create(_stack, sizeof(_stack), PRIO, 0, _cnt_thread, NULL, "cnt"); /* first, wait 155ms -> should lead to 3 timeout wakeups */ xtimer_msleep(155U); /* post event 3 times -> should lead to 3 event wakeups */ for (unsigned i = 0; i < 3; i++) { event_post(&_evtq, &_evt); xtimer_msleep(5U); } /* wait for 35ms and post another event -> +1 event wakeup */ xtimer_msleep(35U); event_post(&_evtq, &_evt); /* finally, wait 60ms and collect results -> +1 timeout wakeup */ xtimer_msleep(60U); unsigned events = atomic_load(&_wakeup_evt); unsigned timeouts = atomic_load(&_wakeup_timeout); /* rate results */ printf("finished: %u/4 events and %u/4 timeouts recorded\n", events, timeouts); if ((events == 4) && (timeouts == 4)) { puts("[SUCCESS]"); } else { puts("[FAILED]"); } return 0; }