lockup in delta chain using signal timers
Martin Werner
martin.werner at aacmicrotec.com
Mon Feb 15 15:53:11 UTC 2016
Hi,
We're seeing an issue in RTEMS where heavy use of signal timers causes
the internal RTEMS delta chain (_Watchdog_Ticks_chain) to end up with a
self-referencing node, which subsequently blocks insertion and locks the
application.
I've cobbled together a testcase[1] based on samples/ticker, and have
seen the issue when running on qemu/i386.
Is this testcase valid, or is the usage of the signal timers here
incorrect?
If it is valid, does anyone have a suggestion as to what may be the core
issue, assuming that the delta chain behaviour is only a symptom?
We originally saw this issue on our custom or1k hardware, where due to
various circumstances it seems much more easy to provoke (there with
only 3 threads), and from there have tracked it back to something which
seems to be non-or1k-specific.
[1] (Also attached since I don't trust our mail server not to mangle
this)
commit e12d669456ebe74a7dee970d1e0e987bdce4c179
Author: Martin Erik Werner <martin.werner at aacmicrotec.com>
Date: Mon Feb 15 13:49:41 2016 +0100
Create sigwaitticker sample from ticker template
Create a sample using sigwait often with many threads, attempting to
reproduce an issue where the Watchdog_Ticks_Chain, ends up with a
self-referencing node, and thus locks the application.
Compared to ticker:
* Only print time from first thread
* Switch to POSIX threading
* Use sigtimedwait instead of normal timed wait
* Add print statement on each alarm
* Set amount of threads to 300
diff --git a/testsuites/samples/Makefile.am b/testsuites/samples/Makefile.am
index 08455d3..fc9ad3c 100644
--- a/testsuites/samples/Makefile.am
+++ b/testsuites/samples/Makefile.am
@@ -1,6 +1,6 @@
ACLOCAL_AMFLAGS = -I ../aclocal
-_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio
+_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio sigwaitticker
if MPTESTS
## base_mp is a sample multiprocessing test
diff --git a/testsuites/samples/configure.ac b/testsuites/samples/configure.ac
index 3089e3f..ffff624 100644
--- a/testsuites/samples/configure.ac
+++ b/testsuites/samples/configure.ac
@@ -74,5 +74,6 @@ iostream/Makefile
cdtest/Makefile
pppd/Makefile
capture/Makefile
+sigwaitticker/Makefile
])
AC_OUTPUT
diff --git a/testsuites/samples/sigwaitticker/Makefile.am b/testsuites/samples/sigwaitticker/Makefile.am
new file mode 100644
index 0000000..798e318
--- /dev/null
+++ b/testsuites/samples/sigwaitticker/Makefile.am
@@ -0,0 +1,19 @@
+
+rtems_tests_PROGRAMS = sigwaitticker
+sigwaitticker_SOURCES = init.c tasks.c system.h
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(sigwaitticker_OBJECTS)
+LINK_LIBS = $(sigwaitticker_LDLIBS)
+
+sigwaitticker$(EXEEXT): $(sigwaitticker_OBJECTS) $(sigwaitticker_DEPENDENCIES)
+ @rm -f sigwaitticker$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/samples/sigwaitticker/init.c b/testsuites/samples/sigwaitticker/init.c
new file mode 100644
index 0000000..ae56b55
--- /dev/null
+++ b/testsuites/samples/sigwaitticker/init.c
@@ -0,0 +1,55 @@
+/*
+ * COPYRIGHT (c) 1989-2012.
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define CONFIGURE_INIT
+#include "system.h"
+
+const char rtems_test_name[] = "CLOCK TICK";
+
+/*
+ * Keep the names and IDs in global variables so another task can use them.
+ */
+
+char Task_name[ NUM_TASKS ][ 10 ];
+pthread_t Task_id[ NUM_TASKS ];
+
+void *POSIX_Init(
+ void *argument
+)
+{
+ rtems_status_code status;
+ rtems_time_of_day time;
+ uint32_t i;
+
+ TEST_BEGIN();
+
+ time.year = 1988;
+ time.month = 12;
+ time.day = 31;
+ time.hour = 9;
+ time.minute = 0;
+ time.second = 0;
+ time.ticks = 0;
+
+ status = rtems_clock_set( &time );
+ directive_failed( status, "clock get" );
+
+ for ( i = 0; i < NUM_TASKS; i++ ) {
+ sprintf(Task_name[ i ], "TA%zu", i);
+ }
+
+ for ( i = 0; i < NUM_TASKS; i++ ) {
+ if (pthread_create(Task_id + i, NULL, Test_task, NULL))
+ perror("Error creating pthread");
+ }
+}
diff --git a/testsuites/samples/sigwaitticker/system.h b/testsuites/samples/sigwaitticker/system.h
new file mode 100644
index 0000000..4bd9bd0
--- /dev/null
+++ b/testsuites/samples/sigwaitticker/system.h
@@ -0,0 +1,72 @@
+/* system.h
+ *
+ * This include file contains information that is included in every
+ * function in the test set.
+ *
+ * COPYRIGHT (c) 1989-2009.
+ * 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.
+ */
+
+#include <rtems.h>
+#include <rtems/test.h>
+#include <inttypes.h>
+#include "tmacros.h"
+
+/* functions */
+
+void *POSIX_Init(
+ void *argument
+);
+
+void *Test_task(
+ void *argument
+);
+
+/* global variables */
+
+/*
+ * Keep the names and IDs in global variables so another task can use them.
+ */
+
+#define NUM_TASKS 300
+
+extern pthread_t Task_id[ NUM_TASKS ];
+extern char Task_name[ NUM_TASKS ][ 10 ];
+
+
+/* configuration information */
+
+#include <bsp.h> /* for device driver prototypes */
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 + NUM_TASKS
+#define CONFIGURE_MAXIMUM_POSIX_TIMERS NUM_TASKS
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#include <rtems/confdefs.h>
+
+/*
+ * This allows us to view the "Test_task" instantiations as a set
+ * of numbered tasks by eliminating the number of application
+ * tasks created.
+ *
+ * In reality, this is too complex for the purposes of this
+ * example. It would have been easier to pass a task argument. :)
+ * But it shows how rtems_id's can sometimes be used.
+ */
+
+#define task_number( tid ) \
+ ( rtems_object_id_get_index( tid ) - \
+ rtems_configuration_get_rtems_api_configuration()-> \
+ number_of_initialization_tasks )
+
+/* end of include file */
diff --git a/testsuites/samples/sigwaitticker/tasks.c b/testsuites/samples/sigwaitticker/tasks.c
new file mode 100644
index 0000000..6749594
--- /dev/null
+++ b/testsuites/samples/sigwaitticker/tasks.c
@@ -0,0 +1,96 @@
+/* Test_task
+ *
+ * This routine serves as a test task. It verifies the basic task
+ * switching capabilities of the executive.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989-2009.
+ * 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.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "system.h"
+
+void *Test_task(
+ void *unused
+)
+{
+ pthread_t tid;
+ rtems_time_of_day time;
+ uint32_t task_index;
+ rtems_status_code status;
+ rtems_interval sse_time;
+ rtems_interval last_print_sse_time;
+
+ /* signal timer */
+ int result;
+ sigset_t maskset;
+ struct sigevent event;
+ timer_t timerid;
+ struct itimerspec its;
+ struct timespec timeout;
+
+ /* Blocking alarms until sigtimedwait handles them */
+ sigemptyset(&maskset);
+ sigaddset(&maskset, SIGALRM);
+ pthread_sigmask(SIG_BLOCK, &maskset, NULL);
+
+ /* Create timer to generate alarms */
+ event.sigev_signo = SIGALRM;
+ event.sigev_notify = SIGEV_SIGNAL;
+ result = timer_create(CLOCK_REALTIME, &event, &timerid);
+ if (result)
+ fprintf(stderr, "Could not create timer: %d\n", errno);
+
+ /* Set timer initial and subsequent wait, plus timeout */
+ its.it_value.tv_sec = 1;
+ its.it_value.tv_nsec = 0;
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = rtems_configuration_get_microseconds_per_tick() * 1000;
+ timeout.tv_sec = 3;
+ timeout.tv_nsec = 0;
+
+ /* Start timer generating alarms */
+ timer_settime(timerid, 0, &its, NULL);
+
+ tid = pthread_self();
+ task_index = 0;
+ while (Task_id[task_index] != tid && task_index < NUM_TASKS)
+ task_index++;
+ if (task_index >= NUM_TASKS)
+ perror("Error finding own thread id");
+
+ for ( ; ; ) {
+ status = rtems_clock_get_tod( &time );
+ if ( time.second >= 350 ) {
+ TEST_END();
+ rtems_test_exit( 0 );
+ }
+ rtems_clock_get_seconds_since_epoch(&sse_time);
+ if ( ( sse_time - last_print_sse_time >= 5 ) && task_index == 1 ) {
+ printf("%s", Task_name[task_index]);
+ print_time( " - rtems_clock_get_tod - ", &time, "\n" );
+ last_print_sse_time = sse_time;
+ }
+
+ if (sigtimedwait(&maskset, NULL, &timeout) != SIGALRM) {
+ perror("Timeout or error on sigtimedwait");
+ } else {
+ printf("got alarm\n"); /* Disabling this makes the error go away (wat?) */
+ }
+
+ }
+}
--
Martin Erik Werner <martin.werner at aacmicrotec.com>
ÅAC Microtec AB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Create-sigwaitticker-sample-from-ticker-template.patch
Type: text/x-patch
Size: 9096 bytes
Desc: 0001-Create-sigwaitticker-sample-from-ticker-template.patch
URL: <http://lists.rtems.org/pipermail/users/attachments/20160215/b7842a5d/attachment.bin>
More information about the users
mailing list