summaryrefslogtreecommitdiff
path: root/samples/nanokernel/test/test_lifo/src/lifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'samples/nanokernel/test/test_lifo/src/lifo.c')
-rw-r--r--samples/nanokernel/test/test_lifo/src/lifo.c1087
1 files changed, 0 insertions, 1087 deletions
diff --git a/samples/nanokernel/test/test_lifo/src/lifo.c b/samples/nanokernel/test/test_lifo/src/lifo.c
deleted file mode 100644
index 439101580..000000000
--- a/samples/nanokernel/test/test_lifo/src/lifo.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Wind River Systems, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @file
- * @brief Test nanokernel LIFO APIs
- *
- * DESCRIPTION
- * This module tests four basic scenarios with the usage of the following LIFO
- * routines:
- *
- * nano_isr_lifo_get, nano_isr_lifo_put
- * nano_fiber_lifo_get, nano_fiber_lifo_put
- * nano_task_lifo_get, nano_task_lifo_put
- *
- * Scenario #1
- * Getting (and waiting for an object) from an empty LIFO. Both fibers and
- * tasks can wait on a LIFO, but an ISR can not.
- *
- * Scenario #2
- * Getting objects from a non-empty LIFO. Fibers, tasks and ISRs are all
- * allowed to get an object from a non-empty LIFO.
- *
- * Scenario #3:
- * Multiple fibers pend on the same LIFO.
- *
- * Scenario #4:
- * Timeout scenarios with multiple LIFOs and fibers.
- *
- * These scenarios will be tested using a combinations of tasks, fibers and
- * ISRs.
- */
-
-#include <zephyr.h>
-#include <tc_util.h>
-#include <misc/util.h>
-#include <misc/__assert.h>
-#include <irq_offload.h>
-
-/* test uses 2 software IRQs */
-#define NUM_SW_IRQS 2
-
-#include <util_test_common.h>
-
-#ifndef FIBER_STACKSIZE
-#define FIBER_STACKSIZE 2000
-#endif
-#define FIBER_PRIORITY 4
-
-typedef struct {
- struct nano_lifo *lifo_ptr; /* LIFO */
- void *data; /* pointer to data to add */
-} ISR_LIFO_INFO;
-
-typedef struct {
- uint32_t link; /* 32-bit word for LIFO to use as a link */
- uint32_t data; /* miscellaneous data put on LIFO (not important) */
-} LIFO_ITEM;
-
-/* Items to be added/removed from LIFO during the test */
-static LIFO_ITEM lifoItem[4] = {
- {0, 1},
- {0, 2},
- {0, 3},
- {0, 4},
- };
-
-static struct nano_lifo test_lifo; /* LIFO used in test */
-static struct nano_sem taskWaitSem; /* task waits on this semaphore */
-static struct nano_sem fiberWaitSem; /* fiber waits on this semaphore */
-static struct nano_timer timer;
-static void *timerData[1];
-static ISR_LIFO_INFO isrLifoInfo = {&test_lifo, NULL};
-
-static volatile int fiberDetectedFailure = 0; /* non-zero on failure */
-
-static char __stack fiberStack[FIBER_STACKSIZE];
-
-static struct nano_lifo multi_waiters;
-static struct nano_sem reply_multi_waiters;
-
-/**
- *
- * @brief Add an item to a LIFO
- *
- * This routine is the ISR handler for _trigger_nano_isr_lifo_put(). It adds
- * an item to the LIFO in the context of an ISR.
- *
- * @param data pointer to ISR handler parameter
- *
- * @return N/A
- */
-
-void isr_lifo_put(void *data)
-{
- ISR_LIFO_INFO *pInfo = (ISR_LIFO_INFO *) data;
-
- nano_isr_lifo_put(pInfo->lifo_ptr, pInfo->data);
-}
-
-static void _trigger_nano_isr_lifo_put(void)
-{
- irq_offload(isr_lifo_put, &isrLifoInfo);
-}
-
-
-/**
- *
- * @brief Get an item from a LIFO
- *
- * This routine is the ISR handler for _trigger_nano_isr_lifo_get(). It gets
- * an item from the LIFO in the context of an ISR.
- *
- * @param data pointer to ISR handler parameter
- *
- * @return N/A
- */
-
-void isr_lifo_get(void *data)
-{
- ISR_LIFO_INFO *pInfo = (ISR_LIFO_INFO *) data;
-
- pInfo->data = nano_isr_lifo_get(pInfo->lifo_ptr, TICKS_NONE);
-}
-
-static void _trigger_nano_isr_lifo_get(void)
-{
- irq_offload(isr_lifo_get, &isrLifoInfo);
-}
-
-
-/**
- *
- * @brief Fiber portion of test that waits on a LIFO
- *
- * This routine works with taskLifoWaitTest() to test the addition and removal
- * of items to/from a LIFO. The cases covered will have a fiber or task waiting
- * on an empty LIFO.
- *
- * @return 0 on success, -1 on failure
- */
-
-int fiberLifoWaitTest(void)
-{
- void *data; /* ptr to data retrieved from LIFO */
-
- /*
- * The LIFO is empty; wait for an item to be added to the LIFO
- * from the task.
- */
-
- TC_PRINT("Fiber waiting on an empty LIFO\n");
- nano_fiber_sem_give(&taskWaitSem);
- data = nano_fiber_lifo_get(&test_lifo, TICKS_UNLIMITED);
- if (data != &lifoItem[0]) {
- fiberDetectedFailure = 1;
- return -1;
- }
-
- nano_fiber_sem_take(&fiberWaitSem, TICKS_UNLIMITED);
- data = nano_fiber_lifo_get(&test_lifo, TICKS_UNLIMITED);
- if (data != &lifoItem[2]) {
- fiberDetectedFailure = 1;
- return -1;
- }
-
- /*
- * Give the task some time to check the results. Ideally, this would
- * be waiting for a semaphore instead of a using a delay, but if the
- * main task wakes the fiber before it blocks on the LIFO, the fiber
- * will add the item to the LIFO too soon. Obviously, a semaphore could
- * not be given if the task is blocked on the LIFO; hence the delay.
- */
-
- nano_fiber_timer_start(&timer, SECONDS(2));
- nano_fiber_timer_test(&timer, TICKS_UNLIMITED);
-
- /* The task is waiting on an empty LIFO. Wake it up. */
- nano_fiber_lifo_put(&test_lifo, &lifoItem[3]);
- nano_fiber_lifo_put(&test_lifo, &lifoItem[1]);
-
- /*
- * Wait for the task to check the results. If the results pass, then the
- * the task will wake the fiber. If the results do not pass, then the
- * fiber will wait forever.
- */
-
- nano_fiber_sem_take(&fiberWaitSem, TICKS_UNLIMITED);
-
- return 0;
-}
-
-/**
- *
- * @brief Fiber portion of test that does not wait on a LIFO
- *
- * This routine works with fiberLifoNonWaitTest() to test the addition and
- * removal of items from a LIFO without having to wait.
- *
- * @return 0 on success, -1 on failure
- */
-
-int fiberLifoNonWaitTest(void)
-{
- void *data; /* pointer to data retrieved from LIFO */
-
- /* The LIFO has two items in it; retrieve them both */
-
- data = nano_fiber_lifo_get(&test_lifo, TICKS_NONE);
- if (data != (void *) &lifoItem[3]) {
- goto errorReturn;
- }
-
- data = nano_fiber_lifo_get(&test_lifo, TICKS_NONE);
- if (data != (void *) &lifoItem[2]) {
- goto errorReturn;
- }
-
- /* LIFO should be empty--verify. */
- data = nano_fiber_lifo_get(&test_lifo, TICKS_NONE);
- if (data != NULL) {
- goto errorReturn;
- }
-
- /*
- * The LIFO is now empty. Add two items to the LIFO and then wait
- * for the semaphore so that the task can retrieve them.
- */
-
- TC_PRINT("Task to get LIFO items without waiting\n");
- nano_fiber_lifo_put(&test_lifo, &lifoItem[0]);
- nano_fiber_lifo_put(&test_lifo, &lifoItem[1]);
- nano_fiber_sem_give(&taskWaitSem); /* Wake the task (if blocked) */
-
- /*
- * Wait for the task to get the items and then trigger an ISR to populate
- * the LIFO.
- */
-
- nano_fiber_sem_take(&fiberWaitSem, TICKS_UNLIMITED);
-
- /*
- * The task retrieved the two items from the LIFO and then triggered
- * two interrupts to add two other items to the LIFO. The fiber will
- * now trigger two interrupts to read the two items.
- */
-
- _trigger_nano_isr_lifo_get();
- if (isrLifoInfo.data != &lifoItem[1]) {
- goto errorReturn;
- }
-
- _trigger_nano_isr_lifo_get();
- if (isrLifoInfo.data != &lifoItem[3]) {
- goto errorReturn;
- }
-
- /* The LIFO should now be empty--verify */
- _trigger_nano_isr_lifo_get();
- if (isrLifoInfo.data != NULL) {
- goto errorReturn;
- }
-
- return 0;
-
-errorReturn:
- fiberDetectedFailure = 1;
- return -1;
-}
-
-/**
- *
- * @brief Entry point for the fiber portion of the LIFO tests
- *
- * NOTE: The fiber portion of the tests have higher priority than the task
- * portion of the tests.
- *
- * @param arg1 unused
- * @param arg2 unused
- *
- * @return N/A
- */
-
-static void fiberEntry(int arg1, int arg2)
-{
- int rv; /* return value from a test */
-
- ARG_UNUSED(arg1);
- ARG_UNUSED(arg2);
-
- rv = fiberLifoWaitTest();
-
- if (rv == 0) {
- fiberLifoNonWaitTest();
- }
-
-}
-
-/**
- *
- * @brief Task portion of test that waits on a LIFO
- *
- * This routine works with fiberLifoWaitTest() to test the addition and removal
- * of items to/from a LIFO. The cases covered will have a fiber or task waiting
- * on an empty LIFO.
- *
- * @return TC_PASS on success, TC_FAIL on failure
- */
-
-int taskLifoWaitTest(void)
-{
- void *data; /* ptr to data retrieved from LIFO */
-
- /* Wait on <taskWaitSem> in case fiber's print message blocked */
- nano_fiber_sem_take(&taskWaitSem, TICKS_UNLIMITED);
-
- /* The fiber is waiting on the LIFO. Wake it. */
- nano_task_lifo_put(&test_lifo, &lifoItem[0]);
-
- /*
- * The fiber ran, but is now blocked on the semaphore. Add an item to the
- * LIFO before giving the semaphore that wakes the fiber so that we can
- * cover the path of nano_fiber_lifo_get(TICKS_UNLIMITED) not waiting on
- * the LIFO.
- */
-
- nano_task_lifo_put(&test_lifo, &lifoItem[2]);
- nano_task_sem_give(&fiberWaitSem);
-
- /* Check that the fiber got the correct item (lifoItem[0]) */
-
- if (fiberDetectedFailure) {
- TC_ERROR(" *** nano_task_lifo_put()/nano_fiber_lifo_get() failure\n");
- return TC_FAIL;
- }
-
- /* The LIFO is empty. This time the task will wait for the item. */
-
- TC_PRINT("Task waiting on an empty LIFO\n");
- data = nano_task_lifo_get(&test_lifo, TICKS_UNLIMITED);
- if (data != (void *) &lifoItem[1]) {
- TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
- return TC_FAIL;
- }
-
- data = nano_task_lifo_get(&test_lifo, TICKS_UNLIMITED);
- if (data != (void *) &lifoItem[3]) {
- TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
- return TC_FAIL;
- }
-
-
- /* Waiting on an empty LIFO passed for both fiber and task. */
-
- return TC_PASS;
-}
-
-/**
- *
- * @brief Task portion of test that does not wait on a LIFO
- *
- * This routine works with fiberLifoNonWaitTest() to test the addition and
- * removal of items from a LIFO without having to wait.
- *
- * @return TC_PASS on success, TC_FAIL on failure
- */
-
-int taskLifoNonWaitTest(void)
-{
- void *data; /* ptr to data retrieved from LIFO */
-
- /*
- * The fiber is presently waiting for <fiberWaitSem>. Populate the LIFO
- * before waking the fiber.
- */
-
- TC_PRINT("Fiber to get LIFO items without waiting\n");
- nano_task_lifo_put(&test_lifo, &lifoItem[2]);
- nano_task_lifo_put(&test_lifo, &lifoItem[3]);
- nano_task_sem_give(&fiberWaitSem); /* Wake the fiber */
-
- /* Check that fiber received the items correctly */
- if (fiberDetectedFailure) {
- TC_ERROR(" *** nano_task_lifo_put()/nano_fiber_lifo_get() failure\n");
- return TC_FAIL;
- }
-
- /* Wait for the fiber to be ready */
- nano_task_sem_take(&taskWaitSem, TICKS_UNLIMITED);
-
- data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
- if (data != (void *) &lifoItem[1]) {
- TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
- return TC_FAIL;
- }
-
- data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
- if (data != (void *) &lifoItem[0]) {
- TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
- return TC_FAIL;
- }
-
- data = nano_task_lifo_get(&test_lifo, TICKS_NONE);
- if (data != NULL) {
- TC_ERROR(" *** nano_task_lifo_get()/nano_fiber_lifo_put() failure\n");
- return TC_FAIL;
- }
-
- /*
- * Software interrupts have been configured so that when invoked,
- * the ISR will add an item to the LIFO. The fiber (when unblocked)
- * trigger software interrupts to get the items from the LIFO from
- * within an ISR.
- *
- * Populate the LIFO.
- */
-
- TC_PRINT("ISR to get LIFO items without waiting\n");
- isrLifoInfo.data = &lifoItem[3];
- _trigger_nano_isr_lifo_put();
- isrLifoInfo.data = &lifoItem[1];
- _trigger_nano_isr_lifo_put();
-
- isrLifoInfo.data = NULL; /* Force NULL to ensure [data] changes */
-
- nano_task_sem_give(&fiberWaitSem); /* Wake the fiber */
-
- if (fiberDetectedFailure) {
- TC_ERROR(" *** nano_isr_lifo_put()/nano_isr_lifo_get() failure\n");
- return TC_FAIL;
- }
-
- return TC_PASS;
-}
-
-/**
- *
- * @brief Initialize nanokernel objects
- *
- * This routine initializes the nanokernel objects used in the LIFO tests.
- *
- * @return N/A
- */
-
-void initNanoObjects(void)
-{
- nano_lifo_init(&test_lifo); /* Initialize the LIFO */
- nano_sem_init(&taskWaitSem); /* Initialize the task waiting semaphore */
- nano_sem_init(&fiberWaitSem); /* Initialize the fiber waiting semaphore */
- nano_timer_init(&timer, timerData);
-
- nano_lifo_init(&multi_waiters);
- nano_sem_init(&reply_multi_waiters);
-
- TC_PRINT("Nano objects initialized\n");
-}
-
-/*
- * Multiple-waiters test
- *
- * NUM_WAITERS fibers pend on the multi_waiters LIFO, then the task puts data
- * on the LIFO NUM_WAITERS times. Each time, the first fiber in the queue wakes
- * up, is context-switched to, verifies the data is the one expected, and gives
- * the reply_multi_waiters semaphore, for a total of NUM_WAITERS times. The
- * task finally must be able to obtain the reply_multi_waiters semaphore
- * NUM_WAITERS times.
- */
-#define NUM_WAITERS 3
-static char __stack fiber_multi_waiters_stacks[NUM_WAITERS][FIBER_STACKSIZE];
-static LIFO_ITEM multi_waiters_items[NUM_WAITERS] = {
- [0 ...(NUM_WAITERS-1)].link = 0,
- [0 ...(NUM_WAITERS-1)].data = 0xabad1dea,
-};
-
-/**
- *
- * @brief Fiber entry point for multiple-waiters test
- *
- * @return N/A
- */
-
-static void fiber_multi_waiters(int arg1, int arg2)
-{
- void *item;
-
- TC_PRINT("multiple-waiter fiber %d receiving item...\n", arg1);
- item = nano_fiber_lifo_get(&multi_waiters, TICKS_UNLIMITED);
- if (item != &multi_waiters_items[arg1]) {
- TC_ERROR(" *** fiber %d did not receive correct item\n", arg1);
- TC_ERROR(" *** received %p instead of %p.\n",
- item, &multi_waiters_items[arg1]);
-
- /* do NOT give the semaphore, signifying an error */
- return;
- }
- TC_PRINT("multiple-waiter fiber %d got correct item, giving semaphore\n",
- arg1);
- nano_fiber_sem_give(&reply_multi_waiters);
-}
-
-/**
- *
- * @brief Task part of multiple-waiter test, repeatable
- *
- * @return N/A
- */
-
-static int do_test_multiple_waiters(void)
-{
- int ii;
-
- /* pend all fibers one the same lifo */
- for (ii = 0; ii < NUM_WAITERS; ii++) {
- task_fiber_start(fiber_multi_waiters_stacks[ii], FIBER_STACKSIZE,
- fiber_multi_waiters, ii, 0, FIBER_PRIORITY, 0);
- }
-
- /* wake up all the fibers: the task is preempted each time */
- for (ii = 0; ii < NUM_WAITERS; ii++) {
- nano_task_lifo_put(&multi_waiters, &multi_waiters_items[ii]);
- }
-
- /* reply_multi_waiters will have been given once for each fiber */
- for (ii = 0; ii < NUM_WAITERS; ii++) {
- if (!nano_task_sem_take(&reply_multi_waiters, TICKS_NONE)) {
- TC_ERROR(" *** Cannot take sem supposedly given by waiters.\n");
- return TC_FAIL;
- }
- }
-
- TC_PRINT("Task took multi-waiter reply semaphore %d times, as expected.\n",
- NUM_WAITERS);
-
- if (nano_task_lifo_get(&multi_waiters, TICKS_NONE)) {
- TC_ERROR(" *** multi_waiters should have been empty.\n");
- return TC_FAIL;
- }
-
- return TC_PASS;
-}
-
-/**
- *
- * @brief Entry point for multiple-waiters test
- *
- * @return N/A
- */
-
-static int test_multiple_waiters(void)
-{
- TC_PRINT("First pass\n");
- if (do_test_multiple_waiters() == TC_FAIL) {
- TC_ERROR(" *** First pass test failed.\n");
- return TC_FAIL;
- }
-
- /*
- * Verity a wait q that has been emptied has been reset correctly, so
- * redo the test. This time, send one message before starting the fibers.
- */
-
- TC_PRINT("Second pass\n");
- if (do_test_multiple_waiters() == TC_FAIL) {
- TC_ERROR(" *** Second pass test failed.\n");
- return TC_FAIL;
- }
-
- return TC_PASS;
-}
-
-/* timeout tests
- *
- * Test the nano_xxx_lifo_wait_timeout() APIs.
- *
- * First, the task waits with a timeout and times out. Then it wait with a
- * timeout, but gets the data in time.
- *
- * Then, multiple timeout tests are done for the fibers, to test the ordering
- * of queueing/dequeueing when timeout occurs, first on one lifo, then on
- * multiple lifos.
- *
- * Finally, multiple fibers pend on one lifo, and they all get the
- * data in time, except the last one: this tests that the timeout is
- * recomputed correctly when timeouts are aborted.
- */
-
-#include <tc_nano_timeout_common.h>
-
-struct scratch_q_packet {
- void *link_in_q;
- void *data_if_needed;
-};
-
-struct reply_packet {
- void *link_in_fifo;
- int reply;
-};
-
-#define NUM_SCRATCH_Q_PACKETS 20
-struct scratch_q_packet scratch_q_packets[NUM_SCRATCH_Q_PACKETS];
-
-struct nano_fifo scratch_q_packets_fifo;
-
-void *get_scratch_packet(void)
-{
- void *packet = nano_fifo_get(&scratch_q_packets_fifo, TICKS_NONE);
-
- __ASSERT_NO_MSG(packet);
-
- return packet;
-}
-
-void put_scratch_packet(void *packet)
-{
- nano_fifo_put(&scratch_q_packets_fifo, packet);
-}
-
-static struct nano_lifo lifo_timeout[2];
-struct nano_fifo timeout_order_fifo;
-
-struct timeout_order_data {
- void *link_in_lifo;
- struct nano_lifo *lifo;
- int32_t timeout;
- int timeout_order;
- int q_order;
-};
-
-struct timeout_order_data timeout_order_data[] = {
- {0, &lifo_timeout[0], TIMEOUT(2), 2, 0},
- {0, &lifo_timeout[0], TIMEOUT(4), 4, 1},
- {0, &lifo_timeout[0], TIMEOUT(0), 0, 2},
- {0, &lifo_timeout[0], TIMEOUT(1), 1, 3},
- {0, &lifo_timeout[0], TIMEOUT(3), 3, 4},
-};
-
-struct timeout_order_data timeout_order_data_mult_lifo[] = {
- {0, &lifo_timeout[1], TIMEOUT(0), 0, 0},
- {0, &lifo_timeout[0], TIMEOUT(3), 3, 1},
- {0, &lifo_timeout[0], TIMEOUT(5), 5, 2},
- {0, &lifo_timeout[1], TIMEOUT(8), 8, 3},
- {0, &lifo_timeout[1], TIMEOUT(7), 7, 4},
- {0, &lifo_timeout[0], TIMEOUT(1), 1, 5},
- {0, &lifo_timeout[0], TIMEOUT(6), 6, 6},
- {0, &lifo_timeout[0], TIMEOUT(2), 2, 7},
- {0, &lifo_timeout[1], TIMEOUT(4), 4, 8},
-};
-
-#define TIMEOUT_ORDER_NUM_FIBERS ARRAY_SIZE(timeout_order_data_mult_lifo)
-static char __stack timeout_stacks[TIMEOUT_ORDER_NUM_FIBERS][FIBER_STACKSIZE];
-
-/* a fiber sleeps then puts data on the lifo */
-static void test_fiber_put_timeout(int lifo, int timeout)
-{
- fiber_sleep((int32_t)timeout);
- nano_fiber_lifo_put((struct nano_lifo *)lifo, get_scratch_packet());
-}
-
-/* a fiber pends on a lifo then times out */
-static void test_fiber_pend_and_timeout(int data, int unused)
-{
- struct timeout_order_data *d = (void *)data;
- int32_t orig_ticks = sys_tick_get();
- void *packet;
-
- ARG_UNUSED(unused);
-
- packet = nano_fiber_lifo_get(d->lifo, d->timeout);
- if (packet) {
- TC_ERROR(" *** timeout of %d did not time out.\n",
- d->timeout);
- return;
- }
- if (!is_timeout_in_range(orig_ticks, d->timeout)) {
- return;
- }
-
- nano_fiber_fifo_put(&timeout_order_fifo, d);
-}
-
-/* the task spins several fibers that pend and timeout on lifos */
-static int test_multiple_fibers_pending(struct timeout_order_data *test_data,
- int test_data_size)
-{
- int ii;
-
- for (ii = 0; ii < test_data_size; ii++) {
- task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
- test_fiber_pend_and_timeout,
- (int)&test_data[ii], 0,
- FIBER_PRIORITY, 0);
- }
-
- for (ii = 0; ii < test_data_size; ii++) {
- struct timeout_order_data *data =
- nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);
-
- if (data->timeout_order == ii) {
- TC_PRINT(" got fiber (q order: %d, t/o: %d, lifo %p) as expected\n",
- data->q_order, data->timeout, data->lifo);
- } else {
- TC_ERROR(" *** fiber %d woke up, expected %d\n",
- data->timeout_order, ii);
- return TC_FAIL;
- }
- }
-
- return TC_PASS;
-}
-
-/* a fiber pends on a lifo with a timeout and gets the data in time */
-static void test_fiber_pend_and_get_data(int data, int unused)
-{
- struct timeout_order_data *d = (void *)data;
- void *packet;
-
- ARG_UNUSED(unused);
-
- packet = nano_fiber_lifo_get(d->lifo, d->timeout);
- if (!packet) {
- TC_PRINT(" *** fiber (q order: %d, t/o: %d, lifo %p) timed out!\n",
- d->q_order, d->timeout, d->lifo);
- return;
- }
-
- put_scratch_packet(packet);
- nano_fiber_fifo_put(&timeout_order_fifo, d);
-}
-
-/* the task spins fibers that get lifo data in time, except the last one */
-static int test_multiple_fibers_get_data(struct timeout_order_data *test_data,
- int test_data_size)
-{
- struct timeout_order_data *data;
- int ii;
-
- for (ii = 0; ii < test_data_size-1; ii++) {
- task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
- test_fiber_pend_and_get_data,
- (int)&test_data[ii], 0,
- FIBER_PRIORITY, 0);
- }
- task_fiber_start(timeout_stacks[ii], FIBER_STACKSIZE,
- test_fiber_pend_and_timeout,
- (int)&test_data[ii], 0,
- FIBER_PRIORITY, 0);
-
- for (ii = 0; ii < test_data_size-1; ii++) {
-
- nano_task_lifo_put(test_data[ii].lifo, get_scratch_packet());
-
- data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);
-
- if (data->q_order == ii) {
- TC_PRINT(" got fiber (q order: %d, t/o: %d, lifo %p) as expected\n",
- data->q_order, data->timeout, data->lifo);
- } else {
- TC_ERROR(" *** fiber %d woke up, expected %d\n",
- data->q_order, ii);
- return TC_FAIL;
- }
- }
-
- data = nano_task_fifo_get(&timeout_order_fifo, TICKS_UNLIMITED);
- if (data->q_order == ii) {
- TC_PRINT(" got fiber (q order: %d, t/o: %d, lifo %p) as expected\n",
- data->q_order, data->timeout, data->lifo);
- } else {
- TC_ERROR(" *** fiber %d woke up, expected %d\n",
- data->timeout_order, ii);
- return TC_FAIL;
- }
-
- return TC_PASS;
-}
-
-/* try getting data on lifo with special timeout value, return result in fifo */
-static void test_fiber_ticks_special_values(int packet, int special_value)
-{
- struct reply_packet *reply_packet = (void *)packet;
-
- reply_packet->reply =
- !!nano_fiber_lifo_get(&lifo_timeout[0], special_value);
-
- nano_fiber_fifo_put(&timeout_order_fifo, reply_packet);
-}
-
-/* the timeout test entry point */
-static int test_timeout(void)
-{
- int64_t orig_ticks;
- int32_t timeout;
- int rv;
- void *packet, *scratch_packet;
- int test_data_size;
- int ii;
- struct reply_packet reply_packet;
-
- nano_lifo_init(&lifo_timeout[0]);
- nano_lifo_init(&lifo_timeout[1]);
- nano_fifo_init(&timeout_order_fifo);
- nano_fifo_init(&scratch_q_packets_fifo);
-
- for (ii = 0; ii < NUM_SCRATCH_Q_PACKETS; ii++) {
- scratch_q_packets[ii].data_if_needed = (void *)ii;
- nano_task_fifo_put(&scratch_q_packets_fifo,
- &scratch_q_packets[ii]);
- }
-
- /* test nano_task_lifo_get() with timeout */
- timeout = 10;
- orig_ticks = sys_tick_get();
- packet = nano_task_lifo_get(&lifo_timeout[0], timeout);
- if (packet) {
- TC_ERROR(" *** timeout of %d did not time out.\n", timeout);
- return TC_FAIL;
- }
- if ((sys_tick_get() - orig_ticks) < timeout) {
- TC_ERROR(" *** task did not wait long enough on timeout of %d.\n",
- timeout);
- return TC_FAIL;
- }
-
- /* test nano_task_lifo_get() with timeout of 0 */
-
- packet = nano_task_lifo_get(&lifo_timeout[0], 0);
- if (packet) {
- TC_ERROR(" *** timeout of 0 did not time out.\n");
- return TC_FAIL;
- }
-
- /* test nano_task_lifo_get() with timeout > 0 */
-
- TC_PRINT("test nano_task_lifo_get() with timeout > 0\n");
-
- timeout = 3;
- orig_ticks = sys_tick_get();
-
- packet = nano_task_lifo_get(&lifo_timeout[0], timeout);
-
- if (packet) {
- TC_ERROR(" *** timeout of %d did not time out.\n",
- timeout);
- return TC_FAIL;
- }
-
- if (!is_timeout_in_range(orig_ticks, timeout)) {
- return TC_FAIL;
- }
-
- TC_PRINT("nano_task_lifo_get() timed out as expected\n");
-
- /*
- * test nano_task_lifo_get() with a timeout and fiber that puts
- * data on the lifo on time
- */
-
- timeout = 5;
- orig_ticks = sys_tick_get();
-
- task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
- test_fiber_put_timeout, (int)&lifo_timeout[0],
- timeout,
- FIBER_PRIORITY, 0);
-
- packet = nano_task_lifo_get(&lifo_timeout[0],
- (int)(timeout + 5));
- if (!packet) {
- TC_ERROR(" *** data put in time did not return valid pointer.\n");
- return TC_FAIL;
- }
-
- put_scratch_packet(packet);
-
- if (!is_timeout_in_range(orig_ticks, timeout)) {
- return TC_FAIL;
- }
-
- TC_PRINT("nano_task_lifo_get() got lifo in time, as expected\n");
-
- /*
- * test nano_task_lifo_get() with TICKS_NONE and no data
- * unavailable.
- */
-
- if (nano_task_lifo_get(&lifo_timeout[0], TICKS_NONE)) {
- TC_ERROR("task with TICKS_NONE got data, but shouldn't have\n");
- return TC_FAIL;
- }
-
- TC_PRINT("task with TICKS_NONE did not get data, as expected\n");
-
- /*
- * test nano_task_lifo_get() with TICKS_NONE and some data
- * available.
- */
-
- scratch_packet = get_scratch_packet();
- nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
- if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_NONE)) {
- TC_ERROR("task with TICKS_NONE did not get available data\n");
- return TC_FAIL;
- }
- put_scratch_packet(scratch_packet);
-
- TC_PRINT("task with TICKS_NONE got available data, as expected\n");
-
- /*
- * test nano_task_lifo_get() with TICKS_UNLIMITED and the
- * data available.
- */
-
- TC_PRINT("Trying to take available data with TICKS_UNLIMITED:\n"
- " will hang the test if it fails.\n");
-
- scratch_packet = get_scratch_packet();
- nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
- if (!nano_task_lifo_get(&lifo_timeout[0], TICKS_UNLIMITED)) {
- TC_ERROR(" *** This will never be hit!!! .\n");
- return TC_FAIL;
- }
- put_scratch_packet(scratch_packet);
-
- TC_PRINT("task with TICKS_UNLIMITED got available data, as expected\n");
-
- /* test fiber with timeout of TICKS_NONE not getting data on empty lifo */
-
- task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
- test_fiber_ticks_special_values,
- (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);
-
- if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
- TC_ERROR(" *** fiber should have run and filled the fifo.\n");
- return TC_FAIL;
- }
-
- if (reply_packet.reply != 0) {
- TC_ERROR(" *** fiber should not have obtained the data.\n");
- return TC_FAIL;
- }
-
- TC_PRINT("fiber with TICKS_NONE did not get data, as expected\n");
-
- /* test fiber with timeout of TICKS_NONE getting data when available */
-
- scratch_packet = get_scratch_packet();
- nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
- task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
- test_fiber_ticks_special_values,
- (int)&reply_packet, TICKS_NONE, FIBER_PRIORITY, 0);
- put_scratch_packet(scratch_packet);
-
- if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
- TC_ERROR(" *** fiber should have run and filled the fifo.\n");
- return TC_FAIL;
- }
-
- if (reply_packet.reply != 1) {
- TC_ERROR(" *** fiber should have obtained the data.\n");
- return TC_FAIL;
- }
-
- TC_PRINT("fiber with TICKS_NONE got available data, as expected\n");
-
- /* test fiber with TICKS_UNLIMITED timeout getting data when availalble */
-
- scratch_packet = get_scratch_packet();
- nano_task_lifo_put(&lifo_timeout[0], scratch_packet);
- task_fiber_start(timeout_stacks[0], FIBER_STACKSIZE,
- test_fiber_ticks_special_values,
- (int)&reply_packet, TICKS_UNLIMITED, FIBER_PRIORITY, 0);
- put_scratch_packet(scratch_packet);
-
- if (!nano_task_fifo_get(&timeout_order_fifo, TICKS_NONE)) {
- TC_ERROR(" *** fiber should have run and filled the fifo.\n");
- return TC_FAIL;
- }
-
- if (reply_packet.reply != 1) {
- TC_ERROR(" *** fiber should have obtained the data.\n");
- return TC_FAIL;
- }
-
- TC_PRINT("fiber with TICKS_UNLIMITED got available data, as expected\n");
-
- /* test multiple fibers pending on the same lifo with different timeouts */
-
- test_data_size = ARRAY_SIZE(timeout_order_data);
-
- TC_PRINT("testing timeouts of %d fibers on same lifo\n", test_data_size);
-
- rv = test_multiple_fibers_pending(timeout_order_data, test_data_size);
- if (rv != TC_PASS) {
- TC_ERROR(" *** fibers did not time out in the right order\n");
- return TC_FAIL;
- }
-
- /* test mult. fibers pending on different lifos with different timeouts */
-
- test_data_size = ARRAY_SIZE(timeout_order_data_mult_lifo);
-
- TC_PRINT("testing timeouts of %d fibers on different lifos\n",
- test_data_size);
-
- rv = test_multiple_fibers_pending(timeout_order_data_mult_lifo,
- test_data_size);
- if (rv != TC_PASS) {
- TC_ERROR(" *** fibers did not time out in the right order\n");
- return TC_FAIL;
- }
-
- /*
- * test multiple fibers pending on same lifo with different timeouts, but
- * getting the data in time, except the last one.
- */
-
- test_data_size = ARRAY_SIZE(timeout_order_data);
-
- TC_PRINT("testing %d fibers timing out, but obtaining the data in time\n"
- "(except the last one, which times out)\n",
- test_data_size);
-
- rv = test_multiple_fibers_get_data(timeout_order_data, test_data_size);
- if (rv != TC_PASS) {
- TC_ERROR(" *** fibers did not get the data in the right order\n");
- return TC_FAIL;
- }
-
- return TC_PASS;
-}
-
-/**
- *
- * @brief Entry point to LIFO tests
- *
- * This is the entry point to the LIFO tests.
- *
- * @return N/A
- */
-
-void main(void)
-{
- int rv; /* return value from tests */
-
- TC_START("Test Nanokernel LIFO");
-
- initNanoObjects();
-
- /*
- * Start the fiber. The fiber will be given a higher priority than the
- * main task.
- */
-
- task_fiber_start(fiberStack, FIBER_STACKSIZE, fiberEntry,
- 0, 0, FIBER_PRIORITY, 0);
-
- rv = taskLifoWaitTest();
-
- if (rv == TC_PASS) {
- rv = taskLifoNonWaitTest();
- }
-
- if (rv == TC_PASS) {
- rv = test_multiple_waiters();
- }
-
- /* test timeouts */
- if (rv == TC_PASS) {
- rv = test_timeout();
- }
-
- TC_END_RESULT(rv);
- TC_END_REPORT(rv);
-}