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

5
Last change on this file since 9a4eca5 was 9d8ee11, checked in by Sebastian Huber <sebastian.huber@…>, on 05/17/16 at 07:47:53

psxtests/psxcancel: Add pthread_detach() tests

Update #2714.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 *  The license and distribution terms for this file may be
3 *  found in the file LICENSE in this distribution or at
4 *  http://www.rtems.org/license/LICENSE.
5 */
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <pthread.h>
14#include <sys/time.h>
15#include <unistd.h>
16#include <errno.h>
17#include <sched.h>
18#include <semaphore.h>
19
20#if defined(__rtems__)
21  #include <rtems.h>
22  #include <rtems/libcsupport.h>
23  #include <pmacros.h>
24#endif
25
26const char rtems_test_name[] = "PSXCANCEL";
27
28/* forward declarations to avoid warnings */
29void *POSIX_Init(void *argument);
30
31#if defined(__rtems__)
32static rtems_resource_snapshot initialSnapshot;
33#endif
34
35static volatile bool countTask_handler;
36
37static sem_t masterSem;
38
39static sem_t workerSem;
40
41static void countTask_cancel_handler(void *ignored)
42{
43  countTask_handler = true;
44}
45
46static void *countTaskDeferred(void *ignored)
47{
48  int i=0;
49  int type,state;
50  int sc;
51
52  sc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &type);
53  fatal_posix_service_status( sc, 0, "cancel state deferred" );
54  rtems_test_assert( type == PTHREAD_CANCEL_ENABLE );
55  sc = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &state);
56  fatal_posix_service_status( sc, 0, "cancel type deferred" );
57  rtems_test_assert( state == PTHREAD_CANCEL_DEFERRED );
58  while (1) {
59    printf("countTaskDeferred: elapsed time (second): %2d\n", i++ );
60    sleep(1);
61    pthread_testcancel();
62  }
63}
64
65static void *countTaskAsync(void *ignored)
66{
67  int i=0;
68  int type,state;
69  int sc;
70
71  sc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &type);
72  fatal_posix_service_status( sc, 0, "cancel state async" );
73  rtems_test_assert( type == PTHREAD_CANCEL_ENABLE );
74  sc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &state);
75  fatal_posix_service_status( sc, 0, "cancel type async" );
76  rtems_test_assert( state == PTHREAD_CANCEL_DEFERRED );
77  pthread_cleanup_push(countTask_cancel_handler, NULL);
78  while (1) {
79    printf("countTaskAsync: elapsed time (second): %2d\n", i++ );
80    sleep(1);
81  }
82  countTask_handler = false;
83  pthread_cleanup_pop(1);
84  if ( countTask_handler == false ){
85    puts("countTask_cancel_handler not executed");
86    rtems_test_exit(0);
87  }
88}
89
90static void *taskAsyncAndDetached(void *ignored)
91{
92  int sc;
93
94  sc = pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
95  fatal_posix_service_status( sc, 0, "cancel type taskAsyncAndDetached" );
96
97  sc = sem_post( &workerSem );
98  rtems_test_assert( sc == 0 );
99
100  sc = sem_wait( &masterSem );
101  rtems_test_assert( sc == 0 );
102
103  rtems_test_assert( 0 );
104}
105
106static void *taskSelfDetach(void *ignored)
107{
108  int sc;
109
110  sc = sem_post( &workerSem );
111  rtems_test_assert( sc == 0 );
112
113  sleep( 1 );
114
115  sc = pthread_detach( pthread_self() );
116  fatal_posix_service_status( sc, 0, "detach taskSelfDetach" );
117
118  pthread_exit( (void *) 123 );
119}
120
121static void resourceSnapshotInit( void )
122{
123#if defined(__rtems__)
124  rtems_resource_snapshot_take( &initialSnapshot );
125#endif
126}
127
128static void resourceSnapshotCheck( void )
129{
130#if defined(__rtems__)
131  rtems_test_assert( rtems_resource_snapshot_check( &initialSnapshot ) );
132#endif
133}
134
135#if defined(__rtems__)
136  void *POSIX_Init(void *ignored)
137#else
138  int main(int argc, char **argv)
139#endif
140{
141  pthread_t task;
142  int       taskparameter = 0;
143  int       sc;
144  int       old;
145  void     *exit_value;
146
147  TEST_BEGIN();
148
149  sc = sem_init( &masterSem, 0, 0 );
150  rtems_test_assert( sc == 0 );
151
152  sc = sem_init( &workerSem, 0, 0 );
153  rtems_test_assert( sc == 0 );
154
155  resourceSnapshotInit();
156
157  /* generate some error conditions */
158  puts( "Init - pthread_setcancelstate - NULL oldstate" );
159  sc = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
160  fatal_posix_service_status( sc, 0, "cancel state NULL" );
161
162  puts( "Init - pthread_setcancelstate - bad state - EINVAL" );
163  sc = pthread_setcancelstate(12, &old);
164  fatal_posix_service_status( sc, EINVAL, "cancel state EINVAL" );
165
166  puts( "Init - pthread_setcanceltype - NULL oldtype" );
167  sc = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
168  fatal_posix_service_status( sc, 0, "cancel type NULL" );
169
170  puts( "Init - pthread_setcanceltype - bad type - EINVAL" );
171  sc = pthread_setcanceltype(12, &old);
172  fatal_posix_service_status( sc, EINVAL, "cancel type EINVAL" );
173
174  puts( "Init - pthread_cancel - bad ID - ESRCH" );
175  sc = pthread_cancel(0x100);
176  fatal_posix_service_status( sc, ESRCH, "cancel bad Id" );
177
178  resourceSnapshotCheck();
179
180  /* Test resource reclamation due to pthread_detach() */
181
182  sc = pthread_create( &task, NULL, taskAsyncAndDetached, NULL );
183  fatal_posix_service_status( sc, 0, "create taskAsyncAndDetached" );
184
185  sc = sem_wait( &workerSem );
186  rtems_test_assert( sc == 0 );
187
188  sc = pthread_cancel( task );
189  fatal_posix_service_status( sc, 0, "cancel taskAsyncAndDetached" );
190
191  sc = pthread_detach( task );
192  fatal_posix_service_status( sc, 0, "detach taskAsyncAndDetached" );
193
194  sched_yield();
195
196  sc = pthread_join( task, &exit_value );
197  fatal_posix_service_status( sc, ESRCH, "join taskAsyncAndDetached" );
198
199  resourceSnapshotCheck();
200
201  /* Test pthread_detach() after pthread_join() */
202
203  sc = pthread_create( &task, NULL, taskSelfDetach, NULL );
204  fatal_posix_service_status( sc, 0, "create taskSelfDetach" );
205
206  sc = sem_wait( &workerSem );
207  rtems_test_assert( sc == 0 );
208
209  sc = pthread_join( task, &exit_value );
210  fatal_posix_service_status( sc, 0, "join taskSelfDetach" );
211  rtems_test_assert( exit_value == (void *) 123 );
212
213  resourceSnapshotCheck();
214
215  /* Start countTask deferred */
216  {
217    sc = pthread_create(&task, NULL, countTaskDeferred, &taskparameter);
218    if (sc) {
219      perror("pthread_create: countTask");
220      rtems_test_exit(EXIT_FAILURE);
221    }
222    /* sleep for 5 seconds, then cancel it */
223    sleep(5);
224    sc = pthread_cancel(task);
225    fatal_posix_service_status( sc, 0, "cancel deferred" );
226    sc = pthread_join(task, NULL);
227    fatal_posix_service_status( sc, 0, "join deferred" );
228  }
229
230  /* Start countTask asynchronous */
231  {
232    sc = pthread_create(&task, NULL, countTaskAsync, &taskparameter);
233    if (sc) {
234      perror("pthread_create: countTask");
235      rtems_test_exit(EXIT_FAILURE);
236    }
237    /* sleep for 5 seconds, then cancel it */
238    sleep(5);
239    sc = pthread_cancel(task);
240    fatal_posix_service_status( sc, 0, "cancel async" );
241    sc = pthread_join(task, NULL);
242    fatal_posix_service_status( sc, 0, "join async" );
243  }
244
245  resourceSnapshotCheck();
246
247  TEST_END();
248
249  #if defined(__rtems__)
250    rtems_test_exit(EXIT_SUCCESS);
251    return NULL;
252  #else
253    return 0;
254  #endif
255}
256
257/* configuration information */
258#if defined(__rtems__)
259
260#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
261#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
262
263#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
264
265#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
266#define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 2
267
268#define CONFIGURE_POSIX_INIT_THREAD_TABLE
269
270#define CONFIGURE_INIT
271#include <rtems/confdefs.h>
272
273#endif /* __rtems__ */
274
Note: See TracBrowser for help on using the repository browser.