source: rtems/testsuites/psxtests/psx09/init.c @ 9a4eca5

5
Last change on this file since 9a4eca5 was 48b04fc3, checked in by Sebastian Huber <sebastian.huber@…>, on 04/19/16 at 04:28:03

posix: Avoid Giant lock for mutexes

Delete _POSIX_Mutex_Get(). Use _POSIX_Mutex_Get_interrupt_disable()
instead.

Update #2555.

  • Property mode set to 100644
File size: 7.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 <sched.h>
15
16#define CONFIGURE_INIT
17#include "system.h"
18#include <errno.h>
19#include "pritime.h"
20
21const char rtems_test_name[] = "PSX 9";
22
23void print_schedparam(
24  char               *prefix,
25  struct sched_param *schedparam
26);
27
28int HIGH_PRIORITY;
29int MEDIUM_PRIORITY;
30int LOW_PRIORITY;
31
32void print_schedparam(
33  char               *prefix,
34  struct sched_param *schedparam
35)
36{
37  printf( "%ssched priority      = %d\n", prefix, schedparam->sched_priority );
38#if defined(_POSIX_SPORADIC_SERVER)
39  printf( "%ssched_ss_low_priority     = %d\n",
40      prefix, schedparam->sched_ss_low_priority );
41  printf( "%ssched_ss_repl_period = (%" PRIdtime_t ", %ld)\n", prefix,
42     schedparam->sched_ss_repl_period.tv_sec,
43     schedparam->sched_ss_repl_period.tv_nsec );
44  printf( "%ssched_ss_init_budget = (%" PRIdtime_t ", %ld)\n", prefix,
45     schedparam->sched_ss_init_budget.tv_sec,
46     schedparam->sched_ss_init_budget.tv_nsec );
47#else
48  printf( "%s_POSIX_SPORADIC_SERVER is not defined\n", prefix );
49#endif
50}
51
52static void *mutex_lock_task(void *arg)
53{
54  pthread_mutex_t *mtx;
55  int              eno;
56
57  mtx = arg;
58
59  eno = pthread_mutex_lock( mtx );
60  rtems_test_assert( eno == 0 );
61
62  sched_yield();
63
64  eno = pthread_mutex_unlock( mtx );
65  rtems_test_assert( eno == 0 );
66
67  return NULL;
68}
69
70static void test_destroy_locked_mutex(void)
71{
72  pthread_mutex_t mtx;
73  pthread_t       th;
74  int             eno;
75
76  eno = pthread_mutex_init( &mtx, NULL );
77  rtems_test_assert( eno == 0 );
78
79  eno = pthread_create( &th, NULL, mutex_lock_task, &mtx );
80  rtems_test_assert( eno == 0 );
81
82  sched_yield();
83
84  eno = pthread_mutex_destroy( &mtx );
85  rtems_test_assert( eno == EBUSY );
86
87  sched_yield();
88
89  eno = pthread_mutex_destroy( &mtx );
90  rtems_test_assert( eno == 0 );
91
92  eno = pthread_join( th, NULL );
93  rtems_test_assert( eno == 0 );
94}
95
96void *POSIX_Init(
97  void *argument
98)
99{
100  int                  status;
101  int                  passes;
102  int                  schedpolicy;
103  int                  priority;
104  struct sched_param   schedparam;
105  char                 buffer[ 80 ];
106  pthread_mutexattr_t  attr;
107  time_t               start;
108  time_t               now;
109
110  TEST_BEGIN();
111
112  test_destroy_locked_mutex();
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  Init_id = pthread_self();
121  printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id );
122
123  /* try to use this thread as a sporadic server */
124
125  puts( "Init: pthread_getschedparam - SUCCESSFUL" );
126  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
127  rtems_test_assert( !status );
128
129  priority = schedparam.sched_priority;
130  sprintf( buffer, " - current priority = %d", priority );
131  print_current_time( "Init: ", buffer );
132
133  schedparam.sched_ss_repl_period.tv_sec = 0;
134  schedparam.sched_ss_repl_period.tv_nsec = 500000000;  /* 1/2 second */
135  schedparam.sched_ss_init_budget.tv_sec = 0;
136  schedparam.sched_ss_init_budget.tv_nsec = 250000000;    /* 1/4 second */
137
138  schedparam.sched_priority = sched_get_priority_max(SCHED_SPORADIC);
139  schedparam.sched_ss_low_priority = sched_get_priority_max(SCHED_SPORADIC) - 2;
140
141  puts( "Init: pthread_setschedparam - SUCCESSFUL (sporadic server)" );
142  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
143  rtems_test_assert( !status );
144
145  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
146  rtems_test_assert( !status );
147
148  priority = schedparam.sched_priority;
149  sprintf( buffer, " - new priority = %d", priority );
150  print_current_time( "Init: ", buffer );
151
152  /* go into a loop consuming CPU time to watch our priority change */
153
154  for ( passes=0 ; passes <= 3 ; ) {
155    status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
156    rtems_test_assert( !status );
157
158    if ( priority != schedparam.sched_priority ) {
159      priority = schedparam.sched_priority;
160      sprintf( buffer, " - new priority = %d", priority );
161      print_current_time( "Init: ", buffer );
162      passes++;
163    }
164  }
165
166  /* now see if this works if we are holding a priority ceiling mutex */
167
168  empty_line();
169
170  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
171  rtems_test_assert( !status );
172
173  schedparam.sched_ss_repl_period.tv_sec = 0;
174  schedparam.sched_ss_repl_period.tv_nsec = 500000000;  /* 1/2 second */
175  schedparam.sched_ss_init_budget.tv_sec = 0;
176  schedparam.sched_ss_init_budget.tv_nsec = 250000000;    /* 1/4 second */
177
178  HIGH_PRIORITY = sched_get_priority_max( SCHED_SPORADIC );
179  MEDIUM_PRIORITY = sched_get_priority_max( SCHED_SPORADIC ) - 2;
180  LOW_PRIORITY = sched_get_priority_max( SCHED_SPORADIC ) - 4;
181
182  schedparam.sched_priority = HIGH_PRIORITY;
183  schedparam.sched_ss_low_priority = LOW_PRIORITY;
184
185  puts( "Init: pthread_setschedparam - SUCCESSFUL (sporadic server)" );
186  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
187  rtems_test_assert( !status );
188
189  puts( "Init: Initializing mutex attributes for priority ceiling" );
190  status = pthread_mutexattr_init( &attr );
191  rtems_test_assert( !status );
192
193  status = pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_INHERIT );
194  rtems_test_assert( !status );
195
196  puts( "Init: Creating a mutex" );
197  status = pthread_mutex_init( &Mutex_id, &attr );
198  if ( status )
199    printf( "status = %d\n", status );
200  rtems_test_assert( !status );
201
202  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
203  rtems_test_assert( !status );
204
205  priority = schedparam.sched_priority;
206  sprintf( buffer, " - new priority = %d", priority );
207  print_current_time( "Init: ", buffer );
208
209  /* go into a loop consuming CPU time to watch our priority NOT lower */
210
211  start = time( &start );
212
213  puts( "Init: pthread_mutex_lock acquire the lock" );
214  status = pthread_mutex_lock( &Mutex_id );
215  if ( status )
216    printf( "status = %d %s\n", status, strerror(status) );
217  rtems_test_assert( !status );
218
219  for ( ; ; ) {
220    status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
221    rtems_test_assert( !status );
222
223    if ( schedparam.sched_priority == LOW_PRIORITY ) {
224      puts( "ERROR - Init's priority lowered while holding mutex" );
225      rtems_test_exit(0);
226    }
227
228    now = time( &now );
229    if ( now - start > 3 )
230      break;
231
232    priority = schedparam.sched_priority;
233    sprintf( buffer, " - new priority = %d", priority );
234    print_current_time( "Init: ", buffer );
235
236    status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
237    rtems_test_assert( !status );
238
239    priority = schedparam.sched_priority;
240    sprintf( buffer, " - new priority = %d", priority );
241    print_current_time( "Init: ", buffer );
242
243    break;
244  }
245
246  /* with this unlock we should be able to go to low priority */
247
248  puts( "Init: unlock mutex" );
249  status = pthread_mutex_unlock( &Mutex_id );
250  if ( status )
251    printf( "status = %d\n", status );
252  rtems_test_assert( !status );
253
254  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
255  rtems_test_assert( !status );
256
257  priority = schedparam.sched_priority;
258  sprintf( buffer, " - new priority = %d", priority );
259  print_current_time( "Init: ", buffer );
260
261  for ( ; ; ) {
262    status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
263    rtems_test_assert( !status );
264
265    if ( schedparam.sched_priority == LOW_PRIORITY )
266      break;
267  }
268
269  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
270  rtems_test_assert( !status );
271
272  priority = schedparam.sched_priority;
273  sprintf( buffer, " - new priority = %d", priority );
274  print_current_time( "Init: ", buffer );
275
276  TEST_END();
277  rtems_test_exit( 0 );
278
279  return NULL; /* just so the compiler thinks we returned something */
280}
Note: See TracBrowser for help on using the repository browser.