source: rtems/testsuites/psxtests/psxsem01/init.c @ 1f0e652a

5
Last change on this file since 1f0e652a was fc0756e, checked in by Joel Sherrill <joel.sherrill@…>, on 04/14/15 at 15:01:05

Add test assertion for allocator mutex being unlocked

The Allocator Mutex should not be locked outside a tested
service call. In an SMP test or heavily multithreaded test,
this is possible since another thread could have the lock
for an extended period of time but this is not the norm
for the tests.

updates 2319.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
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#include <semaphore.h>
16#include <errno.h>
17#include <fcntl.h>
18#include <time.h>
19#include <tmacros.h>
20#include <pmacros.h>
21#include "test_support.h"
22
23const char rtems_test_name[] = "PSXSEM 1";
24
25/* forward declarations to avoid warnings */
26void *POSIX_Init(void *argument);
27
28#define MAX_SEMS  10
29
30void *POSIX_Init(
31  void *argument
32)
33{
34  int             status;
35  int             value;
36  int             i;
37  sem_t           sems[MAX_SEMS];
38  sem_t           sem2;
39  sem_t           *n_sem1;
40  sem_t           *n_sem2;
41  struct timespec waittime;
42  char            failure_msg[80];
43
44  TEST_BEGIN();
45
46  puts( "Init: sem_init - UNSUCCESSFUL (EINVAL)" );
47  status = sem_init(NULL, 0, 1);
48  fatal_posix_service_status( status, -1, "sem_init error return status");
49  fatal_posix_service_status( errno, EINVAL, "sem_init errorno EINVAL" );
50
51  puts( "Init: sem_init - SUCCESSFUL" );
52  for (i = 0; i < MAX_SEMS; i++) {
53    status = sem_init(&sems[i], 0, i);
54    sprintf(failure_msg, "sem_init %d", i );
55    fatal_posix_service_status( status, 0, failure_msg);
56  }
57  puts( "Init: sem_init - UNSUCCESSFUL (ENOSPC)" );
58  status = sem_init(&sem2, 0, 1);
59  fatal_posix_service_status( status, -1, "sem_init error return status");
60  fatal_posix_service_status( errno, ENOSPC, "sem_init errorno ENOSPC" );
61
62  puts( "Init: sem_init - UNSUCCESSFUL (ENOSYS -- pshared not supported)" );
63  status = sem_init(&sem2, 1, 1);
64  fatal_posix_service_status( status, -1, "sem_init error return status");
65  fatal_posix_service_status( errno, ENOSYS, "sem_init errno set to ENOSYS");
66
67  puts( "Init: sem_getvalue - SUCCESSFUL ");
68  for (i = 0; i < MAX_SEMS; i++) {
69    status = sem_getvalue(&sems[i], &value);
70    sprintf( failure_msg, "sem_getvalue %d", i );
71    fatal_posix_service_status( status, 0, failure_msg );
72    fatal_posix_service_status( value, i, "sem_getvalue correct value" );
73  }
74  puts( "Init: sem_getvalue - UNSUCCESSFUL ");
75  status = sem_getvalue(&sem2, &value);
76  fatal_posix_service_status( status, -1, "sem_getvalue error return status");
77  fatal_posix_service_status( errno, EINVAL, "sem_getvalue errno EINVAL");
78
79  puts( "Init: sem_destroy - SUCCESSFUL" );
80  status = sem_destroy(&sems[0]);
81  fatal_posix_service_status( status, 0, "sem_destroy semaphore 0");
82
83  puts( "Init: sem_destroy - UNSUCCESSFUL (EINVAL)" );
84  status = sem_destroy(&sem2);
85  fatal_posix_service_status( status, -1, "sem_destroy error return status");
86  fatal_posix_service_status( errno, EINVAL, "sem_destroy errno EINVAL");
87
88  puts( "Init: sem_wait - SUCCESSFUL" );
89  status = sem_wait(&sems[1]);
90  fatal_posix_service_status( status, 0, "sem_wait semaphore 1");
91  /* sem[1].count = 0 */
92
93  puts( "Init: sem_wait - UNSUCCESSFUL (EINVAL)" );
94  status = sem_wait(&sem2);
95  fatal_posix_service_status( status, -1, "sem_wait error return status");
96  fatal_posix_service_status( errno, EINVAL, "sem_wait errno EINVAL");
97
98  puts( "Init: sem_post - SUCCESSFUL" );
99  status = sem_post(&sems[1]);
100  fatal_posix_service_status( status, 0, "sem_post semaphore 1");
101  /* sem[1].count = 1 */
102
103  puts( "Init: sem_wait - SUCCESSFUL (after a sem_post)" );
104  status = sem_wait(&sems[1]);
105  fatal_posix_service_status( status, 0, "sem_wait semaphore 1");
106  /* sem[1].count = 0 */
107
108  puts( "Init: sem_trywait - SUCCESSFUL" );
109  status = sem_trywait(&sems[2]);
110  fatal_posix_service_status( status, 0, "sem_trywait semaphore 2");
111  /* sem[2].count = 1 */
112
113  puts( "Init: sem_trywait - UNSUCCESSFUL (EAGAIN)" );
114  status = sem_trywait(&sems[1]);
115  fatal_posix_service_status( status, -1, "sem_trywait error return status");
116  fatal_posix_service_status( errno, EAGAIN, "sem_trywait errno EAGAIN");
117  /* sem[1].count = 0 */
118
119  puts( "Init: sem_trywait - UNSUCCESSFUL (EINVAL)" );
120  status = sem_trywait(&sem2);
121  fatal_posix_service_status( status, -1, "sem_trywait error return status");
122  fatal_posix_service_status( errno, EINVAL, "sem_trywait errno EINVAL");
123
124#if 0
125  status = sem_post(&sems[2]);
126  fatal_posix_service_status( status, 0, "sem_post semaphore 2");
127  /* sem[2].count = 2 */
128#else
129  /* sem[2].count = 1 */
130#endif
131
132  puts( "Init: sem_timedwait - SUCCESSFUL" );
133  waittime.tv_sec = time(NULL) + 1;
134  waittime.tv_nsec = 100;
135  status = sem_timedwait(&sems[2], &waittime);
136  fatal_posix_service_status( status, 0, "sem_timedwait semaphore 2");
137  /* sem[2].count = 0 */
138
139  puts( "Init: sem_timedwait - UNSUCCESSFUL (ETIMEDOUT)" );
140  status = sem_timedwait(&sems[2], &waittime);
141  fatal_posix_service_status( status, -1, "sem_timedwait error return status");
142  fatal_posix_service_status(
143    errno, ETIMEDOUT, "sem_timedwait errno ETIMEDOUT");
144
145  /*
146   * To do this case, we must be blocking when we want the semaphore.
147   * POSIX doesn't want you to check the error if you can get the resource.
148   */
149
150#if 1
151  puts( "Init: sem_timedwait - UNSUCCESSFUL (EINVAL) -- skipping" );
152#else
153  puts( "Init: sem_timedwait - UNSUCCESSFUL (EINVAL)" );
154  waittime.tv_sec = 0;
155  waittime.tv_nsec = 0x7FFFFFFF;
156  status = sem_timedwait(&sems[2], &waittime);
157  fatal_posix_service_status( status, -1, "sem_timedwait error return status");
158  fatal_posix_service_status( errno, EINVAL, "sem_init errno EINVAL");
159#endif
160
161  puts( "Init: sem_post - UNSUCCESSFUL (EINVAL)" );
162  status = sem_post(&sem2);
163  fatal_posix_service_status( status, -1, "sem_post error return status");
164  fatal_posix_service_status( errno, EINVAL, "sem_post errno EINVAL");
165
166  puts( "Init: sem_destroy - SUCCESSFUL" );
167  for (i = 1; i < MAX_SEMS; i++) {
168    status = sem_destroy(&sems[i]);
169    sprintf( failure_msg, "sem_destroy %d", i );
170    fatal_posix_service_status( status, 0, failure_msg );
171  }
172
173  /* Modes are currently unsupported */
174
175  /*
176   * Validate all sem_open return paths.
177   */
178
179  puts( "Init: sem_open - UNSUCCESSFUL (ENAMETOOLONG)" );
180  n_sem1 = sem_open(Get_Too_Long_Name(), O_CREAT, 0777, 1 );
181  fatal_posix_sem( n_sem1, "sem_open error return status" );
182  fatal_posix_service_status(
183    errno, ENAMETOOLONG, "sem_open errorno ENAMETOOLONG" );
184
185  puts( "Init: sem_open - sem1 SUCCESSFUL" );
186  n_sem1 = sem_open( "sem1",O_CREAT, 0777, 1 );
187  rtems_test_assert( n_sem1 != SEM_FAILED );
188
189  puts( "Init: sem_destroy - named sem1 - EINVAL" );
190  status = sem_destroy(n_sem1);
191  fatal_posix_service_status( status, -1, "sem_destroy named semaphore");
192  fatal_posix_service_status( errno, EINVAL,  "sem_destroy named semaphore");
193
194  puts( "Init: sem_open - Create an Existing sem (EEXIST)" );
195  n_sem2 = sem_open("sem1", O_CREAT | O_EXCL, 0777, 1);
196  fatal_posix_sem( n_sem2, "sem_open error return status" );
197  fatal_posix_service_status( errno, EEXIST,  "sem_open errno EEXIST");
198
199  puts( "Init: sem_open - Open new sem without create flag (ENOENT)" );
200  n_sem2 = sem_open("sem3", O_EXCL, 0777, 1);
201  fatal_posix_sem( n_sem2, "sem_open error return status" );
202  fatal_posix_service_status( errno, ENOENT,  "sem_open errno EEXIST");
203
204  /*
205   * XXX - Could not hit the following errors:
206   *   E_POSIX_Semaphore_Create_support only fails if
207   *     ENOSYS - When semaphore is shared between processes.
208   *     ENOSPC - When out of memory.
209   */
210
211  /*
212   * Validate we can wait on a semaphore opened with sem_open.
213   */
214
215  puts( "Init: sem_wait on sem1" );
216  status = sem_wait(n_sem1);
217  fatal_posix_service_status( status, 0, "sem_wait opened semaphore");
218
219  /*
220   * Validate a second open returns the same semaphore.
221   */
222
223  puts( "Init: sem_open - Open an existing sem ( same id )" );
224  n_sem2 = sem_open("sem1", 0 );
225  rtems_test_assert( n_sem2 == n_sem1 );
226
227  /*
228   * Unlink the semaphore, then verify an open of the same name produces a
229   * different semaphore.
230   */
231
232  puts( "Init: sem_unlink - sem1 SUCCESSFUL" );
233  status = sem_unlink( "sem1" );
234  fatal_posix_service_status( status, 0, "sem_unlink locked semaphore");
235
236  puts( "Init: sem_open - Reopen sem1 SUCCESSFUL with a different id" );
237  n_sem2 = sem_open( "sem1", O_CREAT | O_EXCL, 0777, 1);
238  rtems_test_assert( n_sem2 != SEM_FAILED );
239  rtems_test_assert( n_sem2 != n_sem1 );
240
241  /*
242   * Validate we can call close on a semaphore opened with sem_open.
243   */
244
245  puts( "Init: sem_close (1) - SUCCESSFUL" );
246  status = sem_close( n_sem1 );
247  fatal_posix_service_status( status, 0, "sem_close semaphore");
248
249  /*
250   * Validate it n_sem2 (the last open for sem1 name can be
251   * correctly closed and unlinked.
252   */
253
254  puts( "Init: sem_close (2) - SUCCESSFUL" );
255  status = sem_close( n_sem2 );
256  fatal_posix_service_status( status, 0, "sem_close semaphore");
257
258  puts( "Init: sem_unlink - sem1 (2) SUCCESSFUL" );
259  status = sem_unlink( "sem1" );
260  fatal_posix_service_status( status, 0, "sem_unlink locked semaphore");
261
262  puts( "Init: sem_close - UNSUCCESSFUL (EINVAL)" );
263  status = sem_close(n_sem2);
264  fatal_posix_service_status( status, -1, "sem_close error return status");
265  fatal_posix_service_status( errno, EINVAL, "sem_close errno EINVAL");
266
267  puts( "Init: sem_unlink - UNSUCCESSFUL (ENOENT)" );
268  status = sem_unlink("sem1");
269  fatal_posix_service_status( status, -1, "sem_unlink error return status");
270  fatal_posix_service_status( errno, ENOENT, "sem_close errno EINVAL");
271
272
273  /*
274   * Validate we can unlink (2)
275   */
276
277  puts( "Init: sem_unlink (NULL) - EINVAL" );
278  status = sem_unlink( NULL );
279  fatal_posix_service_status( status, -1, "sem_unlink error return status");
280  fatal_posix_service_status( errno, EINVAL, "sem_unlink errno value");
281
282  puts( "Init: sem_unlink (\"\") - EINVAL" );
283  status = sem_unlink( "" );
284  fatal_posix_service_status( status, -1, "sem_unlink error return status");
285  fatal_posix_service_status( errno, EINVAL, "sem_unlink errno value");
286
287  /*
288   * XXX - Cant' create location OBJECTS_ERROR or OBJECTS_REMOTE.
289   *       sem_close and sem_unlink.
290   */
291
292  puts( "Init: sem_unlink - UNSUCCESSFUL (ENOENT)" );
293  status = sem_unlink("sem2");
294  fatal_posix_service_status( status, -1, "sem_unlink error return status");
295  fatal_posix_service_status( errno, ENOENT, "sem_unlink errno ENOENT");
296  rtems_test_assert( (status == -1) && (errno == ENOENT) );
297
298
299  /* Try adding in unlinking before closing... (can we still open?) */
300
301  TEST_END();
302  rtems_test_exit(0);
303
304  return NULL; /* just so the compiler thinks we returned something */
305}
306
307/* configuration information */
308#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
309#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
310
311#define CONFIGURE_POSIX_INIT_THREAD_TABLE
312
313#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
314
315#define CONFIGURE_MAXIMUM_POSIX_THREADS     1
316#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES  MAX_SEMS
317
318#define CONFIGURE_POSIX_INIT_THREAD_TABLE
319#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE \
320        (RTEMS_MINIMUM_STACK_SIZE * 4)
321
322#define CONFIGURE_INIT
323#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.