From 82d137ae2109b6ee6e363084044eecaafb09a002 Mon Sep 17 00:00:00 2001 From: Jennifer Averett Date: Wed, 23 Apr 2014 15:08:26 -0500 Subject: capture01: New non-interactive test for capture engine. --- testsuites/libtests/Makefile.am | 1 + testsuites/libtests/capture01/Makefile.am | 20 +++ testsuites/libtests/capture01/capture01.doc | 19 +++ testsuites/libtests/capture01/capture01.scn | 35 ++++ testsuites/libtests/capture01/init.c | 253 ++++++++++++++++++++++++++++ testsuites/libtests/capture01/system.h | 42 +++++ testsuites/libtests/capture01/test1.c | 250 +++++++++++++++++++++++++++ testsuites/libtests/configure.ac | 1 + 8 files changed, 621 insertions(+) create mode 100644 testsuites/libtests/capture01/Makefile.am create mode 100644 testsuites/libtests/capture01/capture01.doc create mode 100644 testsuites/libtests/capture01/capture01.scn create mode 100644 testsuites/libtests/capture01/init.c create mode 100644 testsuites/libtests/capture01/system.h create mode 100644 testsuites/libtests/capture01/test1.c diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am index f3987b36ac..f6a27780a4 100644 --- a/testsuites/libtests/Makefile.am +++ b/testsuites/libtests/Makefile.am @@ -14,6 +14,7 @@ _SUBDIRS += block14 _SUBDIRS += block13 _SUBDIRS += rbheap01 _SUBDIRS += flashdisk01 +_SUBDIRS += capture01 _SUBDIRS += bspcmdline01 cpuuse devfs01 devfs02 devfs03 devfs04 \ deviceio01 devnullfatal01 dumpbuf01 gxx01 \ diff --git a/testsuites/libtests/capture01/Makefile.am b/testsuites/libtests/capture01/Makefile.am new file mode 100644 index 0000000000..6c0d80af0c --- /dev/null +++ b/testsuites/libtests/capture01/Makefile.am @@ -0,0 +1,20 @@ + +rtems_tests_PROGRAMS = capture01 +capture01_SOURCES = init.c test1.c system.h + +dist_rtems_tests_DATA = capture01.scn +dist_rtems_tests_DATA += capture01.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + + +LINK_OBJS = $(capture01_OBJECTS) +LINK_LIBS = $(capture01_LDLIBS) + +capture01$(EXEEXT): $(capture01_OBJECTS) $(capture01_DEPENDENCIES) + @rm -f capture01$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/libtests/capture01/capture01.doc b/testsuites/libtests/capture01/capture01.doc new file mode 100644 index 0000000000..c3d2e566d8 --- /dev/null +++ b/testsuites/libtests/capture01/capture01.doc @@ -0,0 +1,19 @@ +# COPYRIGHT (c) 1989-1999. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. +# + +This is a non-ineractive test of the capture engine. This test is based +on the methods that would be called through the monitor capture commands: + + copen 10000 + cwceil 98 + cwfloor 105 + cwglob on + ctset RMON + cwlist + cenable + ctrace diff --git a/testsuites/libtests/capture01/capture01.scn b/testsuites/libtests/capture01/capture01.scn new file mode 100644 index 0000000000..e6d9cb1726 --- /dev/null +++ b/testsuites/libtests/capture01/capture01.scn @@ -0,0 +1,35 @@ +*** BEGIN OF TEST CAPTURE ENGINE *** +watch priority ceiling is 100 +watch priority floor is 102 +global watch is enabled +total 1 + 00000000 ???? g- T:S------ F:----- +0a010002 CT1a 102 102 SWITCHED_OUT +0a010003 CT1b 101 101 CREATED +0a010003 CT1b 101 101 STARTED +0a010003 CT1b 101 101 SWITCHED_IN +0a010003 CT1b 101 101 BEGIN +0a010003 CT1b 101 101 SWITCHED_OUT +0a010004 CT1c 100 100 CREATED +0a010004 CT1c 100 100 STARTED +0a010004 CT1c 100 100 SWITCHED_IN +0a010004 CT1c 100 100 BEGIN +0a010004 CT1c 100 100 SWITCHED_OUT +0a010003 CT1b 101 101 SWITCHED_IN +0a010003 CT1b 101 101 SWITCHED_OUT +0a010002 CT1a 102 100 SWITCHED_IN +0a010002 CT1a 102 102 SWITCHED_OUT +0a010004 CT1c 100 100 SWITCHED_IN +0a010004 CT1c 100 100 SWITCHED_OUT +0a010003 CT1b 101 101 SWITCHED_IN +0a010003 CT1b 101 101 SWITCHED_OUT +0a010004 CT1c 100 100 SWITCHED_IN +0a010004 CT1c 100 100 TERMINATED +0a010004 CT1c 100 100 SWITCHED_OUT +0a010003 CT1b 101 101 SWITCHED_IN +0a010003 CT1b 101 101 TERMINATED +0a010003 CT1b 101 101 SWITCHED_OUT +0a010002 CT1a 102 102 SWITCHED_IN +0a010002 CT1a 102 102 TERMINATED +0a010002 CT1a 102 102 SWITCHED_OUT +*** END OF TEST CAPTURE ENGINE *** diff --git a/testsuites/libtests/capture01/init.c b/testsuites/libtests/capture01/init.c new file mode 100644 index 0000000000..dcffc4cc00 --- /dev/null +++ b/testsuites/libtests/capture01/init.c @@ -0,0 +1,253 @@ +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define CONFIGURE_INIT + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ASSERT_SC(sc) assert((sc) == RTEMS_SUCCESSFUL) + +/* forward declarations to avoid warnings */ +rtems_task Init(rtems_task_argument argument); + +const char rtems_test_name[] = "CAPTURE ENGINE"; + +static void cwlist(void); +static void ctrace(void); + +static void cwlist () +{ + rtems_capture_control_t* control = rtems_capture_get_control_list (); + rtems_task_priority ceiling = rtems_capture_watch_get_ceiling (); + rtems_task_priority floor = rtems_capture_watch_get_floor (); + + fprintf (stdout, "watch priority ceiling is %" PRId32 "\n", ceiling); + fprintf (stdout, "watch priority floor is %" PRId32 "\n", floor); + fprintf (stdout, "global watch is %s\n", + rtems_capture_watch_global_on () ? "enabled" : "disabled"); + fprintf (stdout, "total %" PRId32 "\n", rtems_capture_control_count ()); + + while (control) + { + uint32_t flags; + int f; + int fshowed; + int lf; + + fprintf (stdout, " "); + rtems_monitor_dump_id (rtems_capture_control_id (control)); + fprintf (stdout, " "); + rtems_monitor_dump_name (rtems_capture_control_name (control)); + flags = rtems_capture_control_flags (control); + fprintf (stdout, " %c%c ", + rtems_capture_watch_global_on () ? 'g' : '-', + flags & RTEMS_CAPTURE_WATCH ? 'w' : '-'); + flags = rtems_capture_control_to_triggers (control); + fprintf (stdout, " T:%c%c%c%c%c%c%c", + flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-', + flags & RTEMS_CAPTURE_CREATE ? 'C' : '-', + flags & RTEMS_CAPTURE_START ? 'S' : '-', + flags & RTEMS_CAPTURE_RESTART ? 'R' : '-', + flags & RTEMS_CAPTURE_DELETE ? 'D' : '-', + flags & RTEMS_CAPTURE_BEGIN ? 'B' : '-', + flags & RTEMS_CAPTURE_EXITTED ? 'E' : '-'); + flags = rtems_capture_control_from_triggers (control); + fprintf (stdout, " F:%c%c%c%c%c", + flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-', + flags & RTEMS_CAPTURE_CREATE ? 'C' : '-', + flags & RTEMS_CAPTURE_START ? 'S' : '-', + flags & RTEMS_CAPTURE_RESTART ? 'R' : '-', + flags & RTEMS_CAPTURE_DELETE ? 'D' : '-'); + + for (f = 0, fshowed = 0, lf = 1; f < RTEMS_CAPTURE_TRIGGER_TASKS; f++) + { + if (rtems_capture_control_by_valid (control, f)) + { + if (lf && ((fshowed % 3) == 0)) + { + fprintf (stdout, "\n"); + lf = 0; + } + + fprintf (stdout, " %2i:", f); + rtems_monitor_dump_name (rtems_capture_control_by_name (control, f)); + fprintf (stdout, "/"); + rtems_monitor_dump_id (rtems_capture_control_by_id (control, f)); + flags = rtems_capture_control_by_triggers (control, f); + fprintf (stdout, ":%c%c%c%c%c", + flags & RTEMS_CAPTURE_SWITCH ? 'S' : '-', + flags & RTEMS_CAPTURE_CREATE ? 'C' : '-', + flags & RTEMS_CAPTURE_START ? 'S' : '-', + flags & RTEMS_CAPTURE_RESTART ? 'R' : '-', + flags & RTEMS_CAPTURE_DELETE ? 'D' : '-'); + fshowed++; + lf = 1; + } + } + + if (lf) + fprintf (stdout, "\n"); + + control = rtems_capture_next_control (control); + } +} + +static void ctrace() +{ + rtems_status_code sc; + bool csv = false; + static int dump_total = 22; + int total; + int count; + uint32_t read; + rtems_capture_record_t* rec; + + total = dump_total; + + while (total) + { + sc = rtems_capture_read (0, 0, &read, &rec); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: trace read failed: %s\n", rtems_status_text (sc)); + rtems_capture_flush (0); + return; + } + + /* + * If we have no records then just exist. We still need to release + * the reader lock. + */ + + if (read == 0) + { + rtems_capture_release (read); + break; + } + + count = total < read ? total : read; + + while (count--) + { + if (csv) + fprintf (stdout, "%08" PRIxPTR ",%03" PRIu32 + ",%03" PRIu32 ",%04" PRIx32 ",%" PRId64 "\n", + (uintptr_t) rec->task, + (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff, + (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff, + (rec->events >> RTEMS_CAPTURE_EVENT_START), + (uint64_t) rec->time); + else + { + uint32_t event; + int e; + + event = rec->events >> RTEMS_CAPTURE_EVENT_START; + + for (e = RTEMS_CAPTURE_EVENT_START; e <= RTEMS_CAPTURE_EVENT_END; e++) + { + if (event & 1) + { + rtems_monitor_dump_id (rtems_capture_task_id (rec->task)); + fprintf (stdout, " %c%c%c%c", + (char) (rec->task->name >> 24) & 0xff, + (char) (rec->task->name >> 16) & 0xff, + (char) (rec->task->name >> 8) & 0xff, + (char) (rec->task->name >> 0) & 0xff); + fprintf (stdout, " %3" PRId32 " %3" PRId32 " %s\n", + (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff, + (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff, + rtems_capture_event_text (e)); + } + event >>= 1; + } + } + rec++; + } + + count = total < read ? total : read; + + if (count < total) + total -= count; + else + total = 0; + + rtems_capture_release (count); + } +} + +rtems_task Init( + rtems_task_argument ignored +) +{ +#if BSP_SMALL_MEMORY + printf("NO Capture Engine. MEMORY TOO SMALL"); +#else + rtems_status_code sc; + rtems_task_priority old_priority; + rtems_mode old_mode; + rtems_name to_name = rtems_build_name('I', 'D', 'L', 'E');; + + rtems_test_begin(); + + rtems_task_set_priority(RTEMS_SELF, 20, &old_priority); + rtems_task_mode(RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &old_mode); + + sc = rtems_capture_open (5000, NULL); + ASSERT_SC(sc); + + sc = rtems_capture_watch_ceiling (100); + ASSERT_SC(sc); + + sc = rtems_capture_watch_floor (102); + ASSERT_SC(sc); + + sc = rtems_capture_watch_global (true); + ASSERT_SC(sc); + + sc = rtems_capture_set_trigger ( + 0, + 0, + to_name, + 0, + rtems_capture_from_any, + rtems_capture_switch + ); + ASSERT_SC(sc); + + cwlist(); + + sc = rtems_capture_control (true); + ASSERT_SC(sc); + + capture_test_1(); + + ctrace(); + ctrace(); + + rtems_test_end(); + exit( 0 ); + +#endif +} diff --git a/testsuites/libtests/capture01/system.h b/testsuites/libtests/capture01/system.h new file mode 100644 index 0000000000..62c221f6f5 --- /dev/null +++ b/testsuites/libtests/capture01/system.h @@ -0,0 +1,42 @@ +/* system.h + * + * This include file contains information that is included in every + * function in the test set. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include + +/* functions */ + +rtems_task Init( + rtems_task_argument argument +); + +void capture_test_1(void); + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define TASK_ALLOCATION_SIZE (5) +#define CONFIGURE_MAXIMUM_TASKS rtems_resource_unlimited(TASK_ALLOCATION_SIZE) +#define CONFIGURE_EXTRA_TASK_STACKS (75 * RTEMS_MINIMUM_STACK_SIZE) + +#define CONFIGURE_MAXIMUM_USER_EXTENSIONS (5) + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#include + +/* end of include file */ diff --git a/testsuites/libtests/capture01/test1.c b/testsuites/libtests/capture01/test1.c new file mode 100644 index 0000000000..5e334fc9f5 --- /dev/null +++ b/testsuites/libtests/capture01/test1.c @@ -0,0 +1,250 @@ +/* Test1 + * + * This test uses creates a number of tasks so the capture engine + * can show a trace. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "system.h" +#include +#include + +#include + +#if !BSP_SMALL_MEMORY +static volatile int capture_CT1a_deleted; +static volatile int capture_CT1b_deleted; +static volatile int capture_CT1c_deleted; + +static void +capture_wait (uint32_t period) +{ + rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (period * 1000)); +} + +/* + * CT1a: Claim the mutex and then wait a while then wake + * up and release the mutex. While this task waits with + * the mutex another higher priority task is started that + * just loops using all the processing time. It is not until + * another even higher priority thread blocks on the mutex + * does this task get raised to that priority and so + * releases the mutex. This will allow us to capture the + * action of priority inversion. + */ +static void +capture_CT1a (rtems_task_argument arg) +{ + rtems_id mutex = (rtems_id) arg; + rtems_status_code sc; + + sc = rtems_semaphore_obtain (mutex, RTEMS_WAIT, 0); + + if (sc != RTEMS_SUCCESSFUL) + fprintf (stdout, "error: CT1a: mutex obtain: %s\n", + rtems_status_text (sc)); + + capture_wait (2500); + + sc = rtems_semaphore_release (mutex); + + if (sc != RTEMS_SUCCESSFUL) + fprintf (stdout, "error: CT1a: mutex release: %s\n", + rtems_status_text (sc)); + + capture_CT1a_deleted = 1; + + rtems_task_delete (RTEMS_SELF); +} + +static void +capture_CT1b (rtems_task_argument arg) +{ + volatile int i; + + while (!capture_CT1c_deleted) + i++; + + capture_CT1b_deleted = 1; + + rtems_task_delete (RTEMS_SELF); +} + +static void +capture_CT1c (rtems_task_argument arg) +{ + rtems_id mutex = (rtems_id) arg; + rtems_status_code sc; + + sc = rtems_semaphore_obtain (mutex, RTEMS_WAIT, 0); + + if (sc != RTEMS_SUCCESSFUL) + fprintf (stdout, "error: CT1c: mutex obtain: %s\n", + rtems_status_text (sc)); + + capture_wait (500); + + sc = rtems_semaphore_release (mutex); + + if (sc != RTEMS_SUCCESSFUL) + fprintf (stdout, "error: CT1c: mutex release: %s\n", + rtems_status_text (sc)); + + capture_CT1c_deleted = 1; + + rtems_task_delete (RTEMS_SELF); +} + +void capture_test_1 () +{ + rtems_status_code sc; + rtems_name name; + rtems_id id[3]; + rtems_id mutex; + int loops; + + capture_CT1a_deleted = 0; + capture_CT1b_deleted = 0; + capture_CT1c_deleted = 0; + + name = rtems_build_name('C', 'T', 'm', '1'); + + sc = rtems_semaphore_create (name, 1, + RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | + RTEMS_INHERIT_PRIORITY, + 0, &mutex); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot mutex: %s\n", + rtems_status_text (sc)); + return; + } + + name = rtems_build_name('C', 'T', '1', 'a'); + + sc = rtems_task_create (name, 102, 2 * 1024, + RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, + RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, + &id[0]); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot create CT1a: %s\n", + rtems_status_text (sc)); + rtems_semaphore_delete (mutex); + return; + } + + sc = rtems_task_start (id[0], capture_CT1a, (rtems_task_argument) mutex); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot start CT1a: %s\n", + rtems_status_text (sc)); + rtems_task_delete (id[0]); + rtems_semaphore_delete (mutex); + return; + } + + capture_wait (1000); + + name = rtems_build_name('C', 'T', '1', 'b'); + + sc = rtems_task_create (name, 101, 2 * 1024, + RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, + RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, + &id[1]); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot create CT1b: %s\n", + rtems_status_text (sc)); + rtems_task_delete (id[0]); + rtems_semaphore_delete (mutex); + return; + } + + sc = rtems_task_start (id[1], capture_CT1b, 0); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot start CT1b: %s\n", + rtems_status_text (sc)); + rtems_task_delete (id[1]); + rtems_task_delete (id[0]); + rtems_semaphore_delete (mutex); + return; + } + + capture_wait (1000); + + name = rtems_build_name('C', 'T', '1', 'c'); + + sc = rtems_task_create (name, 100, 2 * 1024, + RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL, + RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR, + &id[2]); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot create CT1c: %s\n", + rtems_status_text (sc)); + rtems_task_delete (id[1]); + rtems_task_delete (id[0]); + rtems_semaphore_delete (mutex); + return; + } + + sc = rtems_task_start (id[2], capture_CT1c, (rtems_task_argument) mutex); + + if (sc != RTEMS_SUCCESSFUL) + { + fprintf (stdout, "error: Test 1: cannot start CT1c: %s\n", + rtems_status_text (sc)); + rtems_task_delete (id[2]); + rtems_task_delete (id[1]); + rtems_task_delete (id[0]); + rtems_semaphore_delete (mutex); + return; + } + + loops = 15; + + while (!(capture_CT1a_deleted || capture_CT1b_deleted || + capture_CT1c_deleted) && loops) + { + loops--; + capture_wait (1000); + } + + if (!loops) + { + fprintf (stdout, "error: Test 1: test tasks did not delete\n"); + rtems_task_delete (id[2]); + rtems_task_delete (id[1]); + rtems_task_delete (id[0]); + } + + sc = rtems_semaphore_delete (mutex); + if (sc != RTEMS_SUCCESSFUL) + fprintf (stdout, "error: Test 1: deleting the mutex: %s\n", + rtems_status_text (sc)); + +} + +#endif /* BSP_SMALL_MEMORY */ diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac index 81dd1fd662..e246680374 100644 --- a/testsuites/libtests/configure.ac +++ b/testsuites/libtests/configure.ac @@ -110,6 +110,7 @@ termios06/Makefile termios07/Makefile termios08/Makefile tztest/Makefile +capture01/Makefile POSIX/Makefile math/Makefile mathf/Makefile -- cgit v1.2.3