source: rtems/testsuites/psxtests/psxspin01/test.c @ 9a4eca5

5
Last change on this file since 9a4eca5 was 9ec7d492, checked in by Sebastian Huber <sebastian.huber@…>, on 05/25/16 at 06:37:28

posix: Fix pthread_spin_unlock() error status

Close #2719.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/**
2 *  @file
3 *
4 *  This test exercises the POSIX Spinlock manager.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2012.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#ifdef HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include "tmacros.h"
21#include <stdio.h>
22#include <errno.h>
23#include <stdlib.h>
24
25#include <pthread.h>
26
27#include <rtems.h>  /* for task creation */
28
29const char rtems_test_name[] = "PSXSPIN 1";
30
31/* forward declarations to avoid warnings */
32int test_main(void);
33rtems_task SpinlockThread(rtems_task_argument arg);
34
35pthread_spinlock_t Spinlock;
36
37volatile int mainThreadSpinning;
38
39rtems_task SpinlockThread(rtems_task_argument arg)
40{
41  int  status;
42
43  if ( mainThreadSpinning ) {
44    puts( "main thread is not supposed to be spinning yet" );
45    exit(0);
46  }
47  puts( "pthread_spin_lock( &Spinlock ) from Thread -- OK" );
48  status = pthread_spin_lock( &Spinlock );
49  rtems_test_assert( status == 0 );
50
51  puts( "sleep to allow main thread to run" );
52  sleep( 1 );
53
54  if ( !mainThreadSpinning ) {
55    puts( "main thread is not spinning on lock" );
56    exit(0);
57  }
58
59  puts( "pthread_spin_unlock( &Spinlock ) from Thread -- OK" );
60  status = pthread_spin_unlock( &Spinlock );
61  rtems_test_assert( status == 0 );
62
63  rtems_task_delete( RTEMS_SELF );
64}
65
66/*
67 *  main entry point to the test
68 */
69
70#if defined(__rtems__)
71int test_main(void)
72#else
73int main(
74  int    argc,
75  char **argv
76)
77#endif
78{
79  pthread_spinlock_t    spinlock;
80  int                   status;
81  rtems_status_code     rstatus;
82  rtems_id              taskid;
83
84  TEST_BEGIN();
85
86  puts( "pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE ) -- EINVAL" );
87  status = pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE );
88  rtems_test_assert( status == EINVAL );
89
90  puts( "pthread_spin_init( NULL, PTHREAD_PROCESS_SHARED ) -- EINVAL" );
91  status = pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE );
92  rtems_test_assert( status == EINVAL );
93
94  puts( "pthread_spin_init( &spinlock, 0x1234 ) -- EINVAL" );
95  status = pthread_spin_init( &spinlock, 0x1234 );
96  rtems_test_assert( status == EINVAL );
97
98  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_SHARED ) -- EINVAL" );
99  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_SHARED );
100  rtems_test_assert( status == EINVAL );
101
102  /* This successfully creates one */
103  puts( "pthread_spin_init( &Spinlock, PTHREAD_PROCESS_PRIVATE ) -- OK" );
104  status = pthread_spin_init( &Spinlock, PTHREAD_PROCESS_PRIVATE );
105  rtems_test_assert( status == 0 );
106
107  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE ) -- EAGAIN" );
108  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE );
109  rtems_test_assert( status == EAGAIN );
110
111  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE ) -- EAGAIN" );
112  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE );
113  rtems_test_assert( status == EAGAIN );
114
115  puts( "pthread_spin_lock( NULL ) -- EINVAL" );
116  status = pthread_spin_lock( NULL );
117  rtems_test_assert( status == EINVAL );
118
119  puts( "pthread_spin_trylock( NULL ) -- EINVAL" );
120  status = pthread_spin_trylock( NULL );
121  rtems_test_assert( status == EINVAL );
122
123  puts( "pthread_spin_unlock( NULL ) -- EINVAL" );
124  status = pthread_spin_unlock( NULL );
125  rtems_test_assert( status == EINVAL );
126
127  puts( "pthread_spin_destroy( NULL ) -- EINVAL" );
128  status = pthread_spin_destroy( NULL );
129  rtems_test_assert( status == EINVAL );
130
131  spinlock = 0;
132
133  puts( "pthread_spin_lock( &spinlock ) -- EINVAL" );
134  status = pthread_spin_lock( &spinlock );
135  rtems_test_assert( status == EINVAL );
136
137  puts( "pthread_spin_trylock( &spinlock ) -- EINVAL" );
138  status = pthread_spin_trylock( &spinlock );
139  rtems_test_assert( status == EINVAL );
140
141  puts( "pthread_spin_unlock( &spinlock ) -- EINVAL" );
142  status = pthread_spin_unlock( &spinlock );
143  rtems_test_assert( status == EINVAL );
144
145  puts( "pthread_spin_destroy( &spinlock ) -- EINVAL" );
146  status = pthread_spin_destroy( &spinlock );
147  rtems_test_assert( status == EINVAL );
148
149  puts( "pthread_spin_unlock( &Spinlock ) -- EPERM" );
150  status = pthread_spin_unlock( &Spinlock );
151  rtems_test_assert( status == EPERM );
152
153  /* Now some basic locking and unlocking with a deadlock verification */
154  puts( "pthread_spin_lock( &Spinlock ) -- OK" );
155  status = pthread_spin_lock( &Spinlock );
156  rtems_test_assert( status == 0 );
157
158  puts( "pthread_spin_lock( &Spinlock ) -- EDEADLK" );
159  status = pthread_spin_lock( &Spinlock );
160  rtems_test_assert( status == EDEADLK );
161
162  puts( "pthread_spin_trylock( &Spinlock ) -- EDEADLK" );
163  status = pthread_spin_trylock( &Spinlock );
164  rtems_test_assert( status == EDEADLK );
165
166  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
167  status = pthread_spin_unlock( &Spinlock );
168  rtems_test_assert( status == 0 );
169
170  /* Try lock/unlock pair */
171  puts( "pthread_spin_trylock( &Spinlock ) -- OK" );
172  status = pthread_spin_trylock( &Spinlock );
173  rtems_test_assert( status == 0 );
174
175  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
176  status = pthread_spin_unlock( &Spinlock );
177  rtems_test_assert( status == 0 );
178
179  /* Let another thread lock a spinlock and we contend with it */
180
181  mainThreadSpinning = 0;
182
183  /*  Create a helper task */
184  rstatus = rtems_task_create(
185     rtems_build_name( 'S', 'P', 'I', 'N' ),
186     1,
187     RTEMS_MINIMUM_STACK_SIZE,
188     RTEMS_DEFAULT_MODES,
189     RTEMS_DEFAULT_ATTRIBUTES,
190     &taskid
191  );
192  rtems_test_assert( rstatus == RTEMS_SUCCESSFUL );
193
194  rstatus = rtems_task_start( taskid, SpinlockThread, 0 );
195  rtems_test_assert( rstatus == RTEMS_SUCCESSFUL );
196  /* We should be preempted immediately.  The thread is expected to:
197   *    + verify we haven't set the main thread spinning flag
198   *    + lock the spinlock
199   *    + delay
200   */
201
202  mainThreadSpinning = 1;
203
204  puts( "pthread_spin_unlock( &Spinlock ) -- EPERM" );
205  status = pthread_spin_unlock( &Spinlock );
206  rtems_test_assert( status == EPERM );
207
208  puts( "pthread_spin_lock( &Spinlock ) -- OK" );
209  status = pthread_spin_lock( &Spinlock );
210  rtems_test_assert( status == 0 );
211
212  /* The thread wakes up, unlocks spin lock, and deletes itself.
213   * So when we get back here, about a second has passed and we now
214   * have the spinlock locked.
215   */
216
217  /* spin lock should be locked when we return so destroying it gives busy */
218  puts( "pthread_spin_destroy( &Spinlock ) -- EBUSY" );
219  status = pthread_spin_destroy( &Spinlock );
220  rtems_test_assert( status == EBUSY );
221
222  /* Unlock it for a normal destroy */
223  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
224  status = pthread_spin_unlock( &Spinlock );
225  rtems_test_assert( status == 0 );
226
227  puts( "pthread_spin_destroy( &Spinlock ) -- OK" );
228  status = pthread_spin_destroy( &Spinlock );
229  rtems_test_assert( status == 0 );
230
231  /*************** END OF TEST *****************/
232  TEST_END();
233  exit(0);
234}
Note: See TracBrowser for help on using the repository browser.