summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-15 10:39:09 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-15 10:43:34 +0200
commit917884c408708c7634e09563d7cd3ed30a4ab71a (patch)
treea6a1daa00e36f2de88d99ee06066de802d807af4
parentpsxtests/psx12: Use one file and simplify (diff)
downloadrtems-917884c408708c7634e09563d7cd3ed30a4ab71a.tar.bz2
posix: Fix poradic server initial CPU budget
Update #2738.
-rw-r--r--cpukit/posix/include/rtems/posix/pthreadimpl.h4
-rw-r--r--cpukit/posix/src/pthread.c5
-rw-r--r--cpukit/posix/src/pthreadcreate.c12
-rw-r--r--testsuites/psxtests/psx12/init.c115
-rw-r--r--testsuites/psxtests/psx12/psx12.scn6
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 990a842168..ba99392574 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 622052c250..432f70cf1b 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 af19313689..a120fdda8d 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 46be8183e3..559cad1d7e 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 1e3c04660d..8cdc94b103 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 ***