From 6e51c4c9f7212bd696ee7aa777c9ca4ac1ad6d3b Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Mon, 30 Nov 2009 09:08:35 +0000 Subject: Added timer server control block Removed _Timer_Server thread pointer Added _Timer_server pointer to the default timer server control block Rework of the timer server implementation. --- testsuites/sptests/sp68/init.c | 467 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 testsuites/sptests/sp68/init.c (limited to 'testsuites/sptests/sp68/init.c') diff --git a/testsuites/sptests/sp68/init.c b/testsuites/sptests/sp68/init.c new file mode 100644 index 0000000000..cdfcccce59 --- /dev/null +++ b/testsuites/sptests/sp68/init.c @@ -0,0 +1,467 @@ +/** + * @file + * + * @ingroup sptests + * + * @brief Test for timer server with blocking calls. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include + +#define TIMER_COUNT 6 + +#define OBTAIN 0 +#define RELEASE 1 +#define INTERRUPT 2 +#define DELAYED 3 +#define SERVER_TRIGGERED 4 +#define INTERRUPT_TRIGGERED 5 + +#define T0 0 +#define T1 1 +#define T2 2 +#define T3 3 +#define T4 4 +#define T5 5 +#define T6 6 + +static volatile bool obtain_try; +static volatile bool obtain_done; +static volatile bool release_happend; +static volatile bool interrupt_happend; +static volatile bool delayed_happend; +static volatile bool server_triggered_happend; +static volatile bool interrupt_triggered_happend; + +static rtems_id timer [TIMER_COUNT]; + +static rtems_id semaphore; +static rtems_id mutex; +static rtems_id message_queue; +static rtems_id region; +static rtems_id barrier; + +static void *region_item; + +static rtems_interval start; + +static volatile enum resource_type { + SEMAPHORE = 0, + MUTEX, + MESSAGE_QUEUE, + REGION, + EVENT, + BARRIER, + TASK_WAKE_AFTER +} resource_type; + +static const char *resource_type_desc [] = { + "SEMAPHORE", + "MUTEX", + "MESSAGE QUEUE", + "REGION", + "EVENT", + "BARRIER", + "TASK WAKE AFTER" +}; + +static void assert_time(rtems_interval expected) +{ + rtems_test_assert((rtems_clock_get_ticks_since_boot() - start) == expected); +} + +static void obtain_callback(rtems_id timer_id, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + char buf [1]; + size_t size = sizeof(buf); + void *new_region_item = NULL; + rtems_event_set events = 0; + + assert_time(T1); + + rtems_test_assert( + !release_happend + && !interrupt_happend + && !delayed_happend + && !interrupt_triggered_happend + && !server_triggered_happend + ); + + obtain_try = true; + + switch (resource_type) { + case SEMAPHORE: + sc = rtems_semaphore_obtain(semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + break; + case MUTEX: + sc = rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + break; + case MESSAGE_QUEUE: + sc = rtems_message_queue_receive(message_queue, buf, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT); + break; + case REGION: + sc = rtems_region_get_segment(region, 1, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &new_region_item); + break; + case EVENT: + sc = rtems_event_receive(RTEMS_EVENT_0, RTEMS_EVENT_ALL | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events); + break; + case BARRIER: + sc = rtems_barrier_wait(barrier, RTEMS_NO_TIMEOUT); + break; + case TASK_WAKE_AFTER: + sc = rtems_task_wake_after(T4 - T1); + break; + default: + rtems_test_assert(false); + break; + } + directive_failed(sc, "obtain"); + + obtain_done = true; +} + +static void release_callback(rtems_id timer_id, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + char buf [1]; + size_t size = sizeof(buf); + uint32_t released = 0; + + assert_time(T4); + + rtems_test_assert( + obtain_try + && interrupt_happend + && !delayed_happend + && !interrupt_triggered_happend + && !server_triggered_happend + ); + + switch (resource_type) { + case SEMAPHORE: + sc = rtems_semaphore_release(semaphore); + break; + case MUTEX: + sc = rtems_semaphore_release(mutex); + break; + case MESSAGE_QUEUE: + sc = rtems_message_queue_send(message_queue, buf, size); + break; + case EVENT: + sc = rtems_event_send(_Timer_server->thread->Object.id, RTEMS_EVENT_0); + break; + case BARRIER: + sc = rtems_barrier_release(barrier, &released); + break; + case TASK_WAKE_AFTER: + sc = RTEMS_SUCCESSFUL; + break; + default: + rtems_test_assert(false); + break; + } + directive_failed_with_level(sc, "release", 1); + + release_happend = true; +} + +static void interrupt_triggered_callback(rtems_id timer_id, void *arg) +{ + /* + * This callback is scheduled to fire at T3, but is delayed due to the + * blocked obtain callback. + */ + assert_time(T4); + + rtems_test_assert( + obtain_done + && release_happend + && interrupt_happend + && !server_triggered_happend + ); + + interrupt_triggered_happend = true; +} + +static void interrupt_callback(rtems_id timer_id, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + assert_time(T2); + + rtems_test_assert( + obtain_try + && !obtain_done + && !release_happend + && !delayed_happend + && !interrupt_triggered_happend + && !server_triggered_happend + ); + + sc = rtems_timer_server_fire_after( + timer [INTERRUPT_TRIGGERED], + T3 - T2, + interrupt_triggered_callback, + NULL + ); + directive_failed_with_level(sc, "rtems_timer_server_fire_after", -1); + + interrupt_happend = true; +} + +static void server_triggered_callback(rtems_id timer_id, void *arg) +{ + assert_time(T5); + + rtems_test_assert( + obtain_done + && release_happend + && interrupt_happend + && delayed_happend + && interrupt_triggered_happend + ); + + server_triggered_happend = true; +} + +static void delayed_callback(rtems_id timer_id, void *arg) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + assert_time(T4); + + rtems_test_assert( + obtain_done + && release_happend + && interrupt_happend + && !server_triggered_happend + ); + + sc = rtems_timer_server_fire_after( + timer [SERVER_TRIGGERED], + T5 - T4, + server_triggered_callback, + NULL + ); + directive_failed(sc, "rtems_timer_server_fire_after"); + + delayed_happend = true; +} + +static void test_reset(void) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + obtain_try = false; + obtain_done = false; + release_happend = false; + interrupt_happend = false; + delayed_happend = false; + interrupt_triggered_happend = false; + server_triggered_happend = false; + + /* Synchronize with tick */ + sc = rtems_task_wake_after(1); + directive_failed(sc, "rtems_task_wake_after"); + + start = rtems_clock_get_ticks_since_boot(); +} + +static void test_case(enum resource_type rt) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + printf("test case: %s\n", resource_type_desc [rt]); + + resource_type = rt; + + test_reset(); + + sc = rtems_timer_server_fire_after( + timer [OBTAIN], + T1 - T0, + obtain_callback, + NULL + ); + directive_failed(sc, "rtems_timer_server_fire_after"); + + sc = rtems_timer_fire_after( + timer [INTERRUPT], + T2 - T0, + interrupt_callback, + NULL + ); + directive_failed(sc, "rtems_timer_fire_after"); + + sc = rtems_timer_server_fire_after( + timer [DELAYED], + T3 - T0, + delayed_callback, + NULL + ); + directive_failed(sc, "rtems_timer_server_fire_after"); + + if (resource_type != REGION) { + sc = rtems_timer_fire_after( + timer [RELEASE], + T4 - T0, + release_callback, + NULL + ); + directive_failed(sc, "rtems_timer_fire_after"); + + assert_time(T0); + + sc = rtems_task_wake_after(T6 - T0); + directive_failed(sc, "task_wake_after"); + } else { + sc = rtems_task_wake_after(T4 - T0); + directive_failed(sc, "task_wake_after"); + + assert_time(T4); + + rtems_test_assert( + obtain_try + && interrupt_happend + && !delayed_happend + && !interrupt_triggered_happend + && !server_triggered_happend + ); + + sc = rtems_region_return_segment(region, region_item); + directive_failed(sc, "rtems_region_return_segment"); + + release_happend = true; + + sc = rtems_task_wake_after(T6 - T4); + directive_failed(sc, "task_wake_after"); + } + + assert_time(T6); + + rtems_test_assert( + obtain_done + && interrupt_happend + && release_happend + && delayed_happend + && interrupt_triggered_happend + && server_triggered_happend + ); +} + +rtems_task Init(rtems_task_argument argument) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + char region_area [128]; + enum resource_type rt = SEMAPHORE; + void *new_region_item = NULL; + size_t i = 0; + + puts("\n\n*** TEST 68 ***"); + + for (i = 0; i < TIMER_COUNT; ++i) { + sc = rtems_timer_create( + rtems_build_name('T', 'I', 'M', '0' + i), + &timer [i] + ); + directive_failed(sc, "rtems_timer_create"); + } + + sc = rtems_timer_initiate_server( + RTEMS_MINIMUM_PRIORITY, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_ATTRIBUTES + ); + directive_failed(sc, "rtems_timer_initiate_server"); + + sc = rtems_semaphore_create( + rtems_build_name('S', 'E', 'M', 'A'), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE, + 0, + &semaphore + ); + directive_failed(sc, "rtems_semaphore_create"); + + sc = rtems_semaphore_create( + rtems_build_name('M', 'U', 'T', 'X'), + 0, + RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &mutex + ); + directive_failed(sc, "rtems_semaphore_create"); + + sc = rtems_message_queue_create( + rtems_build_name('M', 'S', 'G', 'Q'), + 1, + 1, + RTEMS_LOCAL | RTEMS_FIFO, + &message_queue + ); + directive_failed(sc, "rtems_message_queue_create"); + + sc = rtems_region_create( + rtems_build_name('R', 'E', 'G', 'I'), + region_area, + sizeof(region_area), + 1, + RTEMS_LOCAL | RTEMS_FIFO, + ®ion + ); + directive_failed(sc, "rtems_region_create"); + + do { + region_item = new_region_item; + sc = rtems_region_get_segment(region, 1, RTEMS_NO_WAIT, 0, &new_region_item); + } while (sc == RTEMS_SUCCESSFUL); + + sc = rtems_barrier_create( + rtems_build_name('B', 'A', 'R', 'R'), + RTEMS_LOCAL | RTEMS_FIFO, + 2, + &barrier + ); + directive_failed(sc, "rtems_barrier_create"); + + while (rt <= TASK_WAKE_AFTER) { + test_case(rt); + ++rt; + } + + puts("*** END OF TEST 68 ***"); + + rtems_test_exit(0); +} + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 2 +#define CONFIGURE_MAXIMUM_TIMERS TIMER_COUNT +#define CONFIGURE_MAXIMUM_SEMAPHORES 2 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1 +#define CONFIGURE_MAXIMUM_REGIONS 1 +#define CONFIGURE_MAXIMUM_BARRIERS 1 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include -- cgit v1.2.3