[PATCH v4] rtems: Fix _Rate_monotonic_Renew_deadline()

Kuan-Hsun Chen c0066c at gmail.com
Fri Jan 27 22:15:50 UTC 2017


Prepare a precondition to prevent the potential integer overflow.

Remove one redundant parameter in _Rate_monotonic_Renew_deadline().

sptests/sp78: Create
A test case for checking the overflow condition of postponed_jobs
in rtems_rate_monotonic_period_status.

Close #2885.
---
 cpukit/rtems/src/ratemontimeout.c   |  11 ++--
 testsuites/sptests/Makefile.am      |   2 +-
 testsuites/sptests/configure.ac     |   1 +
 testsuites/sptests/sp78/Makefile.am |  22 +++++++
 testsuites/sptests/sp78/init.c      | 120 ++++++++++++++++++++++++++++++++++++
 testsuites/sptests/sp78/sp78.doc    |  18 ++++++
 testsuites/sptests/sp78/sp78.scn    |   9 +++
 7 files changed, 178 insertions(+), 5 deletions(-)
 create mode 100644 testsuites/sptests/sp78/Makefile.am
 create mode 100644 testsuites/sptests/sp78/init.c
 create mode 100644 testsuites/sptests/sp78/sp78.doc
 create mode 100644 testsuites/sptests/sp78/sp78.scn

diff --git a/cpukit/rtems/src/ratemontimeout.c b/cpukit/rtems/src/ratemontimeout.c
index bcc4ccf..5a838fd 100644
--- a/cpukit/rtems/src/ratemontimeout.c
+++ b/cpukit/rtems/src/ratemontimeout.c
@@ -9,7 +9,7 @@
  *  COPYRIGHT (c) 1989-2009.
  *  On-Line Applications Research Corporation (OAR).
  *
- *  COPYRIGHT (c) 2016 Kuan-Hsun Chen.
+ *  COPYRIGHT (c) 2016-2017 Kuan-Hsun Chen.
  *
  *  The license and distribution terms for this file may be
  *  found in the file LICENSE in this distribution or at
@@ -24,13 +24,16 @@
 
 static void _Rate_monotonic_Renew_deadline(
   Rate_monotonic_Control *the_period,
-  Thread_Control         *owner,
   ISR_lock_Context       *lock_context
 )
 {
   uint64_t deadline;
 
-  ++the_period->postponed_jobs;
+  /* stay at 0xffffffff if postponed_jobs is going to overflow */
+  if ( the_period->postponed_jobs != UINT32_MAX ) {
+    ++the_period->postponed_jobs;
+  }
+
   the_period->state = RATE_MONOTONIC_EXPIRED;
 
   deadline = _Watchdog_Per_CPU_insert_relative(
@@ -85,6 +88,6 @@ void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
       _Thread_Unblock( owner );
     }
   } else {
-    _Rate_monotonic_Renew_deadline( the_period, owner, &lock_context );
+    _Rate_monotonic_Renew_deadline( the_period, &lock_context );
   }
 }
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index 5ef87a0..11e9bcd 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -10,7 +10,7 @@ _SUBDIRS = \
     sp40 sp41 sp42 sp43 sp44 sp45 sp46 sp47 sp48 sp49 \
     sp50 sp51 sp52 sp53 sp54 sp55 sp56 sp57 sp58 sp59 \
     sp60      sp62 sp63 sp64 sp65 sp66 sp67 sp68 sp69 \
-    sp70 sp71 sp72 sp73 sp74 sp75 sp76 sp77 sp2038 \
+    sp70 sp71 sp72 sp73 sp74 sp75 sp76 sp77 sp78 sp2038 \
     spassoc01 spchain spcoverage spobjgetnext \
     spprintk spprivenv01 sprbtree01 spsize spstkalloc \
     spstkalloc02 spthreadq01 spwatchdog spwkspace \
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 77ec512..a2af200 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -144,6 +144,7 @@ sp74/Makefile
 sp75/Makefile
 sp76/Makefile
 sp77/Makefile
+sp78/Makefile
 sp2038/Makefile
 spassoc01/Makefile
 spcbssched01/Makefile
diff --git a/testsuites/sptests/sp78/Makefile.am b/testsuites/sptests/sp78/Makefile.am
new file mode 100644
index 0000000..e814104
--- /dev/null
+++ b/testsuites/sptests/sp78/Makefile.am
@@ -0,0 +1,22 @@
+
+rtems_tests_PROGRAMS = sp78
+sp78_SOURCES = init.c ../../support/src/spin.c
+
+dist_rtems_tests_DATA = sp78.scn
+dist_rtems_tests_DATA += sp78.doc
+
+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 = $(sp78_OBJECTS)
+LINK_LIBS = $(sp78_LDLIBS)
+
+sp78$(EXEEXT): $(sp78_OBJECTS) $(sp78_DEPENDENCIES)
+	@rm -f sp78$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/sp78/init.c b/testsuites/sptests/sp78/init.c
new file mode 100644
index 0000000..4d3f534
--- /dev/null
+++ b/testsuites/sptests/sp78/init.c
@@ -0,0 +1,120 @@
+/*
+ *  COPYRIGHT (c) 2017 Kuan-Hsun Chen.
+ *
+ *  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
+
+#include <rtems/cpuuse.h>
+#include <tmacros.h>
+#include <rtems/rtems/ratemonimpl.h>
+#include "test_support.h"
+
+const char rtems_test_name[] = "SP 78";
+
+/* forward declarations to avoid warnings */
+rtems_task Init( rtems_task_argument argument );
+static void modify_count( rtems_id id );
+
+static void modify_count(
+  rtems_id            id
+)
+{
+  Rate_monotonic_Control                  *the_period;
+  ISR_lock_Context                        lock_context;
+
+  the_period = _Rate_monotonic_Get( id, &lock_context );
+  _Rate_monotonic_Acquire_critical( the_period, &lock_context );
+  the_period->postponed_jobs = UINT32_MAX;
+  _Rate_monotonic_Release( the_period, &lock_context );
+}
+
+rtems_task Init(
+  rtems_task_argument argument
+)
+{
+  rtems_id                                period_id;
+  rtems_name                              period_name;
+  rtems_rate_monotonic_period_status      period_status;
+  rtems_status_code                       status;
+  int                                     i;
+
+  period_name = rtems_build_name('P','E','R','1');
+
+  TEST_BEGIN();
+
+  /* create period */
+  status = rtems_rate_monotonic_create(
+      period_name,
+      &period_id
+  );
+  directive_failed( status, "rate_monotonic_create" );
+
+  /* modify the count to UINT32_MAX and attempt to miss deadline*/
+  puts( "Testing overflow condition" );
+  rtems_test_spin_until_next_tick();
+  status = rtems_rate_monotonic_period( period_id, 50 );
+  directive_failed( status, "rate_monotonic_period above loop" );
+
+  puts( "Modify the count of postponed_job manually" );
+  modify_count( period_id );
+
+  /* Check the status */
+  status = rtems_rate_monotonic_get_status( period_id, &period_status );
+  directive_failed( status, "rate_monotonic_get_status" );
+  printf( "Init Postponed jobs = %"PRIu32", and expected %"PRIu32"\n", period_status.postponed_jobs_count, UINT32_MAX );
+  rtems_test_assert( period_status.postponed_jobs_count == UINT32_MAX ); 
+
+  for ( i=1 ; i <= 2 ; i++ ) {
+    status = rtems_task_wake_after( 100 );
+    directive_failed( status, "rtems_task_wake_after(100)" );
+    puts( "Task misses its deadline." );
+
+    /* Check the status */
+    status = rtems_rate_monotonic_get_status( period_id, &period_status );
+    directive_failed( status, "rate_monotonic_get_status" );
+
+    /* print out the count which should keep in UINT32_MAX, since the period still misses its deadline */
+    printf( "Count = %"PRIu32", and expected %"PRIu32"\n", period_status.postponed_jobs_count, UINT32_MAX);
+    rtems_test_assert( period_status.postponed_jobs_count == UINT32_MAX); 
+
+    rtems_test_spin_until_next_tick();
+    status = rtems_rate_monotonic_period( period_id, 50 );
+    fatal_directive_status(
+      status,
+      RTEMS_TIMEOUT,
+      "rtems_rate_monotonic_period 2-n"
+    );
+    
+
+  }
+  
+  TEST_END();
+
+  rtems_test_exit(0);
+}
+
+/* configuration information */
+
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MILLISECONDS_PER_TICK 1
+
+#define CONFIGURE_MAXIMUM_TASKS             1
+#define CONFIGURE_MAXIMUM_PERIODS           1
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+/* end of file */
diff --git a/testsuites/sptests/sp78/sp78.doc b/testsuites/sptests/sp78/sp78.doc
new file mode 100644
index 0000000..ad64e4b
--- /dev/null
+++ b/testsuites/sptests/sp78/sp78.doc
@@ -0,0 +1,18 @@
+#  COPYRIGHT (c) 2017 Kuan-Hsun Chen.
+#
+#  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 file describes the directives and concepts tested by this test set.
+
+test set name:  sp78
+
+directives:
+
+  rtems_rate_monotonic_get_status
+
+concepts:
+
++ Test the overflow condition for postponed_jobs. 
diff --git a/testsuites/sptests/sp78/sp78.scn b/testsuites/sptests/sp78/sp78.scn
new file mode 100644
index 0000000..4cb71db
--- /dev/null
+++ b/testsuites/sptests/sp78/sp78.scn
@@ -0,0 +1,9 @@
+*** BEGIN OF TEST SP 78 ***
+Testing overflow condition
+Modify the count of postponed_job manually
+Init Postponed jobs = 4294967295, and expected 4294967295
+Task misses its deadline.
+Count = 4294967295, and expected 4294967295
+Task misses its deadline.
+Count = 4294967295, and expected 4294967295
+*** END OF TEST SP 78 ***
-- 
1.9.1



More information about the devel mailing list