source: rtems/testsuites/psxtests/psx12/init.c @ 5d1fc66

5
Last change on this file since 5d1fc66 was 5d1fc66, checked in by Sebastian Huber <sebastian.huber@…>, on 08/12/16 at 13:54:46

psxtests: Adjust sporadic server tests

According to POSIX priority value returned from pthread_getschedparam()
shall be the value specified by the most recent pthread_setschedparam(),
pthread_setschedprio(), or pthread_create() call affecting the target
thread. Read this as though a temporary lower priority due to the
sporadic server policy shall not be visible through
pthread_getschedparam(). Thus, use rtems_task_set_priority() to get the
current priority of the threads.

Use a priority ceiling mutex to prevent sporadic server priority
adjustments.

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2009.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <sys/time.h>
15#include <errno.h>
16#include <inttypes.h>
17#include <sched.h>
18#include <stdint.h>
19#include <unistd.h>
20
21#include <pmacros.h>
22
23const char rtems_test_name[] = "PSX 12";
24
25#define SS_REPL_PERIOD_NS 200000000
26
27#define SS_INIT_BUDGET_NS 100000000
28
29#define SS_REPL_PERIOD_MS ( SS_REPL_PERIOD_NS / 1000000 )
30
31#define SS_PRIO_LOW 1
32
33#define SS_PRIO_HIGH 2
34
35#define SS_SAMPLE_PERIODS 3
36
37typedef struct {
38  uint64_t start;
39  struct {
40    uint32_t high;
41    uint32_t low;
42  } samples[ SS_SAMPLE_PERIODS ];
43} test_context;
44
45static test_context test_instance;
46
47static int get_current_prio( pthread_t thread )
48{
49  rtems_status_code sc;
50  rtems_task_priority prio;
51  int max;
52
53  sc = rtems_task_set_priority( thread, RTEMS_CURRENT_PRIORITY, &prio );
54  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
55
56  max = sched_get_priority_max( SCHED_FIFO );
57
58  return max + 1 - (int) prio;
59}
60
61static void wait_for_prio( int prio )
62{
63  while ( prio != get_current_prio( pthread_self() ) ) {
64    /* Wait */
65  }
66}
67
68static uint64_t timeval_to_us( const struct timeval *tv )
69{
70  uint64_t t;
71
72  t = tv->tv_sec;
73  t *= 1000000;
74  t += tv->tv_usec;
75
76  return t;
77}
78
79static uint64_t now( void )
80{
81  struct timeval now;
82
83  gettimeofday( &now, NULL );
84
85  return timeval_to_us( &now );
86}
87
88static uint32_t delta_in_ms( test_context *ctx )
89{
90  uint32_t d;
91
92  d = (uint32_t) ( now() - ctx->start );
93  return ( d + 499 ) / 1000;
94}
95
96static void *sporadic_server( void *argument )
97{
98  test_context *ctx;
99  size_t        i;
100
101  ctx = argument;
102
103  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
104    wait_for_prio( SS_PRIO_LOW );
105    ctx->samples[ i ].high = delta_in_ms( ctx );
106    wait_for_prio( SS_PRIO_HIGH );
107    ctx->samples[ i ].low = delta_in_ms( ctx );
108  }
109
110  puts( "Sporadic Server: exitting" );
111
112  return NULL;
113}
114
115static void *POSIX_Init( void *argument )
116{
117  test_context       *ctx;
118  int                 status;
119  pthread_attr_t      attr;
120  pthread_t           thread;
121  struct sched_param  schedparam;
122  size_t              i;
123
124  TEST_BEGIN();
125
126  ctx = &test_instance;
127
128  /* set the time of day, and print our buffer in multiple ways */
129
130  set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
131
132  /* get id of this thread */
133
134  printf( "Init's ID is 0x%08" PRIxpthread_t "\n", pthread_self() );
135
136  /* invalid scheduling policy error */
137
138  puts( "Init: pthread_attr_init - SUCCESSFUL" );
139  status = pthread_attr_init( &attr );
140  rtems_test_assert( !status );
141
142  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
143  rtems_test_assert( !status );
144  attr.schedpolicy = -1;
145
146  puts( "Init: pthread_create - EINVAL (invalid scheduling policy)" );
147  status = pthread_create( &thread, &attr, sporadic_server, NULL );
148  rtems_test_assert( status == EINVAL );
149
150  /* replenish period < budget error */
151
152  puts( "Init: pthread_attr_init - SUCCESSFUL" );
153  status = pthread_attr_init( &attr );
154  rtems_test_assert( !status );
155
156  puts( "Init: set scheduling parameter attributes for sporadic server" );
157  status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC );
158  rtems_test_assert( !status );
159
160  schedparam.sched_ss_repl_period.tv_sec = 1;
161  schedparam.sched_ss_repl_period.tv_nsec = 0;
162  schedparam.sched_ss_init_budget.tv_sec = 2;
163  schedparam.sched_ss_init_budget.tv_nsec = 0;
164
165  schedparam.sched_priority = 200;
166  schedparam.sched_ss_low_priority = 100;
167
168  status = pthread_attr_setschedparam( &attr, &schedparam );
169  rtems_test_assert( !status );
170
171  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
172  rtems_test_assert( !status );
173
174  puts( "Init: pthread_create - EINVAL (replenish < budget)" );
175  status = pthread_create( &thread, &attr, sporadic_server, NULL );
176  rtems_test_assert( status == EINVAL );
177
178  /* invalid sched_ss_low_priority error */
179
180  schedparam.sched_ss_repl_period.tv_sec = 0;
181  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_NS;
182  schedparam.sched_ss_init_budget.tv_sec = 0;
183  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_NS;
184
185  schedparam.sched_priority = SS_PRIO_HIGH;
186  schedparam.sched_ss_low_priority = -1;
187
188  status = pthread_attr_setschedparam( &attr, &schedparam );
189  rtems_test_assert( !status );
190
191  puts( "Init: pthread_create - EINVAL (invalid sched_ss_low_priority)" );
192  status = pthread_create( &thread, &attr, sporadic_server, NULL );
193  rtems_test_assert( status == EINVAL );
194
195  /* create a thread as a sporadic server */
196
197  schedparam.sched_ss_repl_period.tv_sec = 0;
198  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_NS;
199  schedparam.sched_ss_init_budget.tv_sec = 0;
200  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_NS;
201
202  schedparam.sched_priority = SS_PRIO_HIGH;
203  schedparam.sched_ss_low_priority = SS_PRIO_LOW;
204
205  status = pthread_attr_setschedparam( &attr, &schedparam );
206  rtems_test_assert( !status );
207
208  puts( "Init: pthread_create - SUCCESSFUL" );
209
210  /* Align with clock tick */
211  usleep( 1 );
212
213  ctx->start = now();
214
215  status = pthread_create( &thread, &attr, sporadic_server, ctx );
216  rtems_test_assert( !status );
217
218  status = pthread_join( thread, NULL );
219  rtems_test_assert( !status );
220
221  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
222    printf( "[%zu] H %3" PRIu32 "ms\n", i, ctx->samples[ i ].high );
223    printf( "[%zu] L %3" PRIu32 "ms\n", i, ctx->samples[ i ].low );
224    rtems_test_assert( ctx->samples[ i ].low / SS_REPL_PERIOD_MS == i + 1 );
225  }
226
227  TEST_END();
228  rtems_test_exit( 0 );
229
230  return NULL; /* just so the compiler thinks we returned something */
231}
232
233#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
234#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
235
236#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
237
238#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
239
240#define CONFIGURE_POSIX_INIT_THREAD_TABLE
241
242#define CONFIGURE_INIT
243
244#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.