[rtems commit] posix: Fix poradic server initial CPU budget

Sebastian Huber sebh at rtems.org
Wed Jun 15 08:45:52 UTC 2016


Module:    rtems
Branch:    master
Commit:    917884c408708c7634e09563d7cd3ed30a4ab71a
Changeset: http://git.rtems.org/rtems/commit/?id=917884c408708c7634e09563d7cd3ed30a4ab71a

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jun 15 10:39:09 2016 +0200

posix: Fix poradic server initial CPU budget

Update #2738.

---

 cpukit/posix/include/rtems/posix/pthreadimpl.h |   4 +
 cpukit/posix/src/pthread.c                     |   5 +-
 cpukit/posix/src/pthreadcreate.c               |  12 +--
 testsuites/psxtests/psx12/init.c               | 115 ++++++++++++++++++++++---
 testsuites/psxtests/psx12/psx12.scn            |   6 ++
 5 files changed, 118 insertions(+), 24 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index 990a842..ba99392 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -54,9 +54,13 @@ extern Thread_Information _POSIX_Threads_Information;
 extern pthread_attr_t _POSIX_Threads_Default_attributes;
 
 RTEMS_INLINE_ROUTINE void _POSIX_Threads_Sporadic_timer_insert(
+  Thread_Control    *the_thread,
   POSIX_API_Control *api
 )
 {
+  the_thread->cpu_time_budget =
+    _Timespec_To_ticks( &api->Attributes.schedparam.sched_ss_init_budget );
+
   _Watchdog_Per_CPU_insert_relative(
     &api->Sporadic_timer,
     _Per_CPU_Get(),
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 622052c..432f70c 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -113,11 +113,8 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
 
   _Thread_State_acquire( the_thread, &lock_context );
 
-  the_thread->cpu_time_budget =
-    _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
-
   _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
-  _POSIX_Threads_Sporadic_timer_insert( api );
+  _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
 
   new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
 
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index af19313..a120fdd 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -229,6 +229,12 @@ int pthread_create(
   api->schedpolicy = schedpolicy;
   api->schedparam  = schedparam;
 
+  if ( schedpolicy == SCHED_SPORADIC ) {
+    _ISR_lock_ISR_disable( &lock_context );
+    _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
+    _ISR_lock_ISR_enable( &lock_context );
+  }
+
   /*
    *  POSIX threads are allocated and started in one operation.
    */
@@ -249,12 +255,6 @@ int pthread_create(
     }
   #endif
 
-  if ( schedpolicy == SCHED_SPORADIC ) {
-    _ISR_lock_ISR_disable( &lock_context );
-    _POSIX_Threads_Sporadic_timer_insert( api );
-    _ISR_lock_ISR_enable( &lock_context );
-  }
-
   /*
    *  Return the id and indicate we successfully created the thread
    */
diff --git a/testsuites/psxtests/psx12/init.c b/testsuites/psxtests/psx12/init.c
index 46be818..559cad1 100644
--- a/testsuites/psxtests/psx12/init.c
+++ b/testsuites/psxtests/psx12/init.c
@@ -11,15 +11,88 @@
 #include "config.h"
 #endif
 
-#include <sched.h>
+#include <sys/time.h>
 #include <errno.h>
+#include <inttypes.h>
+#include <sched.h>
+#include <stdint.h>
+#include <unistd.h>
 
 #include <pmacros.h>
 
 const char rtems_test_name[] = "PSX 12";
 
+#define SS_REPL_PERIOD_US 200000
+
+#define SS_INIT_BUDGET_US 100000
+
+#define SS_PRIO_LOW 1
+
+#define SS_PRIO_HIGH 2
+
+#define SS_SAMPLE_PERIODS 3
+
+typedef struct {
+  uint64_t start;
+  struct {
+    uint64_t high;
+    uint64_t low;
+  } samples[ SS_SAMPLE_PERIODS ];
+} test_context;
+
+static test_context test_instance;
+
+static void wait_for_prio( int prio )
+{
+  int                status;
+  int                policy;
+  struct sched_param param;
+
+  do {
+    status = pthread_getschedparam( pthread_self(), &policy, &param );
+    rtems_test_assert( status == 0 );
+  } while ( prio != param.sched_priority );
+}
+
+static uint64_t timeval_to_us( const struct timeval *tv )
+{
+  uint64_t t;
+
+  t = tv->tv_sec;
+  t *= 1000000;
+  t += tv->tv_usec;
+
+  return t;
+}
+
+static uint64_t now( void )
+{
+  struct timeval now;
+
+  gettimeofday( &now, NULL );
+
+  return timeval_to_us( &now );
+}
+
+static uint64_t delta( test_context *ctx )
+{
+  return now() - ctx->start;
+}
+
 static void *sporadic_server( void *argument )
 {
+  test_context *ctx;
+  size_t        i;
+
+  ctx = argument;
+
+  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
+    wait_for_prio( SS_PRIO_LOW );
+    ctx->samples[ i ].high = delta( ctx );
+    wait_for_prio( SS_PRIO_HIGH );
+    ctx->samples[ i ].low = delta( ctx );
+  }
+
   puts( "Sporadic Server: exitting" );
 
   return NULL;
@@ -27,13 +100,17 @@ static void *sporadic_server( void *argument )
 
 static void *POSIX_Init( void *argument )
 {
+  test_context       *ctx;
   int                 status;
   pthread_attr_t      attr;
   pthread_t           thread;
   struct sched_param  schedparam;
+  size_t              i;
 
   TEST_BEGIN();
 
+  ctx = &test_instance;
+
   /* set the time of day, and print our buffer in multiple ways */
 
   set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
@@ -86,12 +163,12 @@ static void *POSIX_Init( void *argument )
 
   /* invalid sched_ss_low_priority error */
 
-  schedparam.sched_ss_repl_period.tv_sec = 2;
-  schedparam.sched_ss_repl_period.tv_nsec = 0;
-  schedparam.sched_ss_init_budget.tv_sec = 1;
-  schedparam.sched_ss_init_budget.tv_nsec = 0;
+  schedparam.sched_ss_repl_period.tv_sec = 0;
+  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
+  schedparam.sched_ss_init_budget.tv_sec = 0;
+  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;
 
-  schedparam.sched_priority = 200;
+  schedparam.sched_priority = SS_PRIO_HIGH;
   schedparam.sched_ss_low_priority = -1;
 
   status = pthread_attr_setschedparam( &attr, &schedparam );
@@ -103,25 +180,35 @@ static void *POSIX_Init( void *argument )
 
   /* create a thread as a sporadic server */
 
-  schedparam.sched_ss_repl_period.tv_sec = 2;
-  schedparam.sched_ss_repl_period.tv_nsec = 0;
-  schedparam.sched_ss_init_budget.tv_sec = 1;
-  schedparam.sched_ss_init_budget.tv_nsec = 0;
+  schedparam.sched_ss_repl_period.tv_sec = 0;
+  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
+  schedparam.sched_ss_init_budget.tv_sec = 0;
+  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;
 
-  schedparam.sched_priority = sched_get_priority_max( SCHED_FIFO );
-  schedparam.sched_ss_low_priority = sched_get_priority_max( SCHED_FIFO ) - 6;
+  schedparam.sched_priority = SS_PRIO_HIGH;
+  schedparam.sched_ss_low_priority = SS_PRIO_LOW;
 
   status = pthread_attr_setschedparam( &attr, &schedparam );
   rtems_test_assert( !status );
 
   puts( "Init: pthread_create - SUCCESSFUL" );
-  status = pthread_create( &thread, &attr, sporadic_server, NULL );
+
+  /* Align with clock tick */
+  usleep( 1 );
+
+  ctx->start = now();
+
+  status = pthread_create( &thread, &attr, sporadic_server, ctx );
   rtems_test_assert( !status );
 
   status = pthread_join( thread, NULL );
   rtems_test_assert( !status );
 
-    /* switch to Task_1 */
+  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
+    printf( "[%zu] H %6" PRIu64 "us\n", i, ctx->samples[ i ].high );
+    printf( "[%zu] L %6" PRIu64 "us\n", i, ctx->samples[ i ].low );
+    rtems_test_assert( ctx->samples[ i ].low / SS_REPL_PERIOD_US == i + 1 );
+  }
 
   TEST_END();
   rtems_test_exit( 0 );
diff --git a/testsuites/psxtests/psx12/psx12.scn b/testsuites/psxtests/psx12/psx12.scn
index 1e3c046..8cdc94b 100644
--- a/testsuites/psxtests/psx12/psx12.scn
+++ b/testsuites/psxtests/psx12/psx12.scn
@@ -8,4 +8,10 @@ Init: pthread_create - EINVAL (replenish < budget)
 Init: pthread_create - EINVAL (invalid sched_ss_low_priority)
 Init: pthread_create - SUCCESSFUL
 Sporadic Server: exitting
+[0] H  99902us
+[0] L 200008us
+[1] H 289908us
+[1] L 400009us
+[2] H 489903us
+[2] L 600009us
 *** END OF TEST PSX 12 ***



More information about the vc mailing list