summaryrefslogtreecommitdiffstats
path: root/testsuites/psxtests/psxonce01
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-02-12 12:19:38 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-02-18 07:25:58 +0100
commite4ad14cc789090290550e3aa9640e4969037e8b7 (patch)
tree94d366cf331ee1f5dc10fc4e4298a41ed878acfd /testsuites/psxtests/psxonce01
parentlibdl/rap: Add the section alloc call after section load was split (diff)
downloadrtems-e4ad14cc789090290550e3aa9640e4969037e8b7.tar.bz2
score: Avoid some deadlocks in _Once()
Recursive usage of the same pthread_once_t results now in a deadlock. Previously, an error of EINVAL was returned. This usage scenario is invalid according to the POSIX pthread_once() specification. Close #3334.
Diffstat (limited to 'testsuites/psxtests/psxonce01')
-rw-r--r--testsuites/psxtests/psxonce01/init.c82
-rw-r--r--testsuites/psxtests/psxonce01/psxonce01.scn15
-rw-r--r--testsuites/psxtests/psxonce01/system.h2
3 files changed, 80 insertions, 19 deletions
diff --git a/testsuites/psxtests/psxonce01/init.c b/testsuites/psxtests/psxonce01/init.c
index 1c90769d38..41ff5b146b 100644
--- a/testsuites/psxtests/psxonce01/init.c
+++ b/testsuites/psxtests/psxonce01/init.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2019 embedded brains GmbH
+ * Copyright (C) 2019 Sebastian Huber
+ *
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
@@ -16,16 +19,11 @@
const char rtems_test_name[] = "PSXONCE 1";
-static pthread_once_t nesting_once = PTHREAD_ONCE_INIT;
+static pthread_once_t once_a = PTHREAD_ONCE_INIT;
-static void Test_init_routine_nesting( void )
-{
- int status;
- puts( "Test_init_routine_nesting: invoked" );
- puts( "Test_init_routine_nesting: pthread_once - EINVAL (init_routine_nesting does not execute)" );
- status = pthread_once( &nesting_once, Test_init_routine_nesting );
- rtems_test_assert( status == EINVAL );
-}
+static pthread_once_t once_b = PTHREAD_ONCE_INIT;
+
+static rtems_id master;
static int test_init_routine_call_counter = 0;
@@ -35,6 +33,66 @@ static void Test_init_routine( void )
++test_init_routine_call_counter;
}
+static void routine_b( void )
+{
+ rtems_status_code sc;
+
+ rtems_test_assert( test_init_routine_call_counter == 2 );
+ ++test_init_routine_call_counter;
+
+ sc = rtems_event_send( master, RTEMS_EVENT_0 );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+}
+
+static void use_b( rtems_task_argument arg )
+{
+ int status;
+
+ (void) arg;
+
+ status = pthread_once( &once_b, routine_b );
+ rtems_test_assert( status == 0 );
+
+ rtems_task_exit();
+}
+
+static void routine_a( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+ rtems_event_set events;
+
+ rtems_test_assert( test_init_routine_call_counter == 1 );
+ ++test_init_routine_call_counter;
+
+ master = rtems_task_self();
+
+ sc = rtems_task_create(
+ rtems_build_name( 'T', 'A', 'S', 'K' ),
+ RTEMS_MINIMUM_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start( id, use_b, 0 );
+ assert( sc == RTEMS_SUCCESSFUL );
+
+ events = 0;
+ sc = rtems_event_receive(
+ RTEMS_EVENT_0,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+ rtems_test_assert( events == RTEMS_EVENT_0 );
+
+ rtems_test_assert( test_init_routine_call_counter == 3 );
+}
+
rtems_task Init(rtems_task_argument argument)
{
int status;
@@ -62,9 +120,9 @@ rtems_task Init(rtems_task_argument argument)
printf( "Init: call counter: %d\n", test_init_routine_call_counter );
rtems_test_assert( test_init_routine_call_counter == 1 );
- puts( "Init: pthread_once - SUCCESSFUL (init_routine_nesting executes)" );
- status = pthread_once( &nesting_once, Test_init_routine_nesting );
- rtems_test_assert( !status );
+ status = pthread_once( &once_a, routine_a );
+ rtems_test_assert( status == 0 );
+ rtems_test_assert( test_init_routine_call_counter == 3 );
TEST_END();
rtems_test_exit( 0 );
diff --git a/testsuites/psxtests/psxonce01/psxonce01.scn b/testsuites/psxtests/psxonce01/psxonce01.scn
index 2c5d47d2d1..a7afa154cb 100644
--- a/testsuites/psxtests/psxonce01/psxonce01.scn
+++ b/testsuites/psxtests/psxonce01/psxonce01.scn
@@ -1,11 +1,14 @@
-
-
-*** TEST POSIX ONCE 01 ***
-Init: pthread_once - SUCCESSFUL (init_routine_nesting executes)
-Test_init_routine_nesting: invoked
+*** BEGIN OF TEST PSXONCE 1 ***
+*** TEST VERSION: 5.0.0.e214ff4b636011bd149e3683c89aa982e361fd1c
+*** TEST STATE: EXPECTED-PASS
+*** TEST BUILD:
+*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB c41b9d0df7e5b4a5056ca50c2534380a44e92769, Newlib 3e24fbf6f)
Init: pthread_once - EINVAL (NULL once_control)
Init: pthread_once - EINVAL (NULL init_routine)
Init: pthread_once - SUCCESSFUL (init_routine executes)
Test_init_routine: invoked
+Init: call counter: 1
Init: pthread_once - SUCCESSFUL (init_routine does not execute)
-*** END OF TEST POSIX ONCE 01 ***
+Init: call counter: 1
+
+*** END OF TEST PSXONCE 1 ***
diff --git a/testsuites/psxtests/psxonce01/system.h b/testsuites/psxtests/psxonce01/system.h
index 10d611b86d..fe95285d5f 100644
--- a/testsuites/psxtests/psxonce01/system.h
+++ b/testsuites/psxtests/psxonce01/system.h
@@ -21,7 +21,7 @@
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
-#define CONFIGURE_MAXIMUM_TASKS 1
+#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE