source: rtems/testsuites/psxtests/psx12/init.c @ 917884c

Last change on this file since 917884c was 917884c, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 15, 2016 at 8:39:09 AM

posix: Fix poradic server initial CPU budget

Update #2738.

  • Property mode set to 100644
File size: 5.7 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_US 200000
26
27#define SS_INIT_BUDGET_US 100000
28
29#define SS_PRIO_LOW 1
30
31#define SS_PRIO_HIGH 2
32
33#define SS_SAMPLE_PERIODS 3
34
35typedef struct {
36  uint64_t start;
37  struct {
38    uint64_t high;
39    uint64_t low;
40  } samples[ SS_SAMPLE_PERIODS ];
41} test_context;
42
43static test_context test_instance;
44
45static void wait_for_prio( int prio )
46{
47  int                status;
48  int                policy;
49  struct sched_param param;
50
51  do {
52    status = pthread_getschedparam( pthread_self(), &policy, &param );
53    rtems_test_assert( status == 0 );
54  } while ( prio != param.sched_priority );
55}
56
57static uint64_t timeval_to_us( const struct timeval *tv )
58{
59  uint64_t t;
60
61  t = tv->tv_sec;
62  t *= 1000000;
63  t += tv->tv_usec;
64
65  return t;
66}
67
68static uint64_t now( void )
69{
70  struct timeval now;
71
72  gettimeofday( &now, NULL );
73
74  return timeval_to_us( &now );
75}
76
77static uint64_t delta( test_context *ctx )
78{
79  return now() - ctx->start;
80}
81
82static void *sporadic_server( void *argument )
83{
84  test_context *ctx;
85  size_t        i;
86
87  ctx = argument;
88
89  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
90    wait_for_prio( SS_PRIO_LOW );
91    ctx->samples[ i ].high = delta( ctx );
92    wait_for_prio( SS_PRIO_HIGH );
93    ctx->samples[ i ].low = delta( ctx );
94  }
95
96  puts( "Sporadic Server: exitting" );
97
98  return NULL;
99}
100
101static void *POSIX_Init( void *argument )
102{
103  test_context       *ctx;
104  int                 status;
105  pthread_attr_t      attr;
106  pthread_t           thread;
107  struct sched_param  schedparam;
108  size_t              i;
109
110  TEST_BEGIN();
111
112  ctx = &test_instance;
113
114  /* set the time of day, and print our buffer in multiple ways */
115
116  set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
117
118  /* get id of this thread */
119
120  printf( "Init's ID is 0x%08" PRIxpthread_t "\n", pthread_self() );
121
122  /* invalid scheduling policy error */
123
124  puts( "Init: pthread_attr_init - SUCCESSFUL" );
125  status = pthread_attr_init( &attr );
126  rtems_test_assert( !status );
127
128  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
129  rtems_test_assert( !status );
130  attr.schedpolicy = -1;
131
132  puts( "Init: pthread_create - EINVAL (invalid scheduling policy)" );
133  status = pthread_create( &thread, &attr, sporadic_server, NULL );
134  rtems_test_assert( status == EINVAL );
135
136  /* replenish period < budget error */
137
138  puts( "Init: pthread_attr_init - SUCCESSFUL" );
139  status = pthread_attr_init( &attr );
140  rtems_test_assert( !status );
141
142  puts( "Init: set scheduling parameter attributes for sporadic server" );
143  status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC );
144  rtems_test_assert( !status );
145
146  schedparam.sched_ss_repl_period.tv_sec = 1;
147  schedparam.sched_ss_repl_period.tv_nsec = 0;
148  schedparam.sched_ss_init_budget.tv_sec = 2;
149  schedparam.sched_ss_init_budget.tv_nsec = 0;
150
151  schedparam.sched_priority = 200;
152  schedparam.sched_ss_low_priority = 100;
153
154  status = pthread_attr_setschedparam( &attr, &schedparam );
155  rtems_test_assert( !status );
156
157  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
158  rtems_test_assert( !status );
159
160  puts( "Init: pthread_create - EINVAL (replenish < budget)" );
161  status = pthread_create( &thread, &attr, sporadic_server, NULL );
162  rtems_test_assert( status == EINVAL );
163
164  /* invalid sched_ss_low_priority error */
165
166  schedparam.sched_ss_repl_period.tv_sec = 0;
167  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
168  schedparam.sched_ss_init_budget.tv_sec = 0;
169  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;
170
171  schedparam.sched_priority = SS_PRIO_HIGH;
172  schedparam.sched_ss_low_priority = -1;
173
174  status = pthread_attr_setschedparam( &attr, &schedparam );
175  rtems_test_assert( !status );
176
177  puts( "Init: pthread_create - EINVAL (invalid sched_ss_low_priority)" );
178  status = pthread_create( &thread, &attr, sporadic_server, NULL );
179  rtems_test_assert( status == EINVAL );
180
181  /* create a thread as a sporadic server */
182
183  schedparam.sched_ss_repl_period.tv_sec = 0;
184  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
185  schedparam.sched_ss_init_budget.tv_sec = 0;
186  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;
187
188  schedparam.sched_priority = SS_PRIO_HIGH;
189  schedparam.sched_ss_low_priority = SS_PRIO_LOW;
190
191  status = pthread_attr_setschedparam( &attr, &schedparam );
192  rtems_test_assert( !status );
193
194  puts( "Init: pthread_create - SUCCESSFUL" );
195
196  /* Align with clock tick */
197  usleep( 1 );
198
199  ctx->start = now();
200
201  status = pthread_create( &thread, &attr, sporadic_server, ctx );
202  rtems_test_assert( !status );
203
204  status = pthread_join( thread, NULL );
205  rtems_test_assert( !status );
206
207  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
208    printf( "[%zu] H %6" PRIu64 "us\n", i, ctx->samples[ i ].high );
209    printf( "[%zu] L %6" PRIu64 "us\n", i, ctx->samples[ i ].low );
210    rtems_test_assert( ctx->samples[ i ].low / SS_REPL_PERIOD_US == i + 1 );
211  }
212
213  TEST_END();
214  rtems_test_exit( 0 );
215
216  return NULL; /* just so the compiler thinks we returned something */
217}
218
219#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
220#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
221
222#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
223
224#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
225
226#define CONFIGURE_POSIX_INIT_THREAD_TABLE
227
228#define CONFIGURE_INIT
229
230#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.