forked from Imagelibrary/rtems
@@ -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(),
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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, ¶m );
|
||||
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 );
|
||||
|
||||
@@ -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 ***
|
||||
|
||||
Reference in New Issue
Block a user