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

5
Last change on this file since 9a4eca5 was 6efa349, checked in by Sebastian Huber <sebastian.huber@…>, on 04/14/16 at 06:56:53

posix: Run key destructors during thread restart

POSIX key destructors must be called during thread restart. Just like
the POSIX cleanup handlers. This ensures that the TLS object
destructors are called during thread restart for example. It is
important for the global construction, which uses a thread restart to
run the Init task in a clean environment.

Close #2689.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 *  Copyright (c) 2012 Zhongwei Yao.
3 *  COPYRIGHT (c) 1989-2014.
4 *  On-Line Applications Research Corporation (OAR).
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.org/license/LICENSE.
9 */
10
11#ifdef HAVE_CONFIG_H
12#include "config.h"
13#endif
14
15#include <pthread.h>
16#include <errno.h>
17#include "tmacros.h"
18#include "pmacros.h"
19
20const char rtems_test_name[] = "PSXKEY 6";
21
22static int Data_array[4] = {1, 2, 3, 4};
23
24static pthread_key_t key1, key2, key3;
25
26static rtems_id Thread_Master;
27
28static int Key3_Destructor_Counter;
29
30static void Wake_Up_Master(void)
31{
32  rtems_status_code rc;
33
34  rc = rtems_event_transient_send( Thread_Master );
35  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
36}
37
38static void Wait_For_Worker(void)
39{
40  rtems_status_code rc;
41
42  rc = rtems_event_transient_receive(
43    RTEMS_WAIT,
44    RTEMS_NO_TIMEOUT
45  );
46  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
47}
48
49static rtems_task Test_Thread1( rtems_task_argument argument )
50{
51  int sc;
52  int *value;
53  struct timespec  delay_request;
54
55  puts( "Test_Thread 1 - key1 pthread_setspecific - OK" );
56  sc = pthread_setspecific( key1, &Data_array[0] );
57  rtems_test_assert( !sc );
58
59  puts( "Test_Thread 1 - key2 pthread_setspecific - OK" );
60  sc = pthread_setspecific( key2, &Data_array[1] );
61  rtems_test_assert( !sc );
62
63  puts( "Test_Thread 1 - sleep - let thread2 run - OK" );
64  delay_request.tv_sec = 0;
65  delay_request.tv_nsec = 4 * 100000000;
66  sc = nanosleep( &delay_request, NULL );
67  rtems_test_assert( !sc );
68
69  puts( "Test_Thread 1 - key1 pthread_getspecific - OK" );
70  value = pthread_getspecific( key1 );
71  rtems_test_assert( *value == Data_array[0] );
72
73  puts( "Test_Thread 1 - key2 pthread_getspecific - OK" );
74  value = pthread_getspecific( key2 );
75  rtems_test_assert( *value == Data_array[1] );
76
77  rtems_task_delete( RTEMS_SELF );
78}
79
80static rtems_task Test_Thread2( rtems_task_argument argument )
81{
82  int sc;
83  int *value;
84
85  puts( "Test_Thread 2 - key1 pthread_setspecific - OK" );
86  sc = pthread_setspecific( key1, &Data_array[2] );
87  rtems_test_assert( !sc );
88
89  puts( "Test_Thread 2 - key2 pthread_setspecific - OK" );
90  sc = pthread_setspecific( key2, &Data_array[3] );
91  rtems_test_assert( !sc );
92
93  puts( "Test_Thread 2 - key1 pthread_getspecific - OK" );
94  value = pthread_getspecific( key1 );
95  rtems_test_assert( *value == Data_array[2] );
96
97  puts( "Test_Thread 2 - key2 pthread_getspecific - OK" );
98  value = pthread_getspecific( key2 );
99  rtems_test_assert( *value == Data_array[3] );
100
101  rtems_task_delete( RTEMS_SELF );
102}
103
104static void Key3_Destructor( void *value )
105{
106  rtems_test_assert( value == &Thread_Master );
107  ++Key3_Destructor_Counter;
108}
109
110static rtems_task Test_Thread3( rtems_task_argument argument )
111{
112  int   sc;
113  void *value;
114
115  puts( "Test_Thread 3 - key3 pthread_getspecific - OK" );
116  value = pthread_getspecific( key3 );
117  rtems_test_assert( value == NULL );
118
119  puts( "Test_Thread 3 - key3 pthread_setspecific - OK" );
120  sc = pthread_setspecific( key3, &Thread_Master );
121  rtems_test_assert( sc == 0 );
122
123  if ( argument == 0 ) {
124    puts( "Test_Thread 3 - restart self - OK" );
125    rtems_task_restart( RTEMS_SELF, 1 );
126  } else if ( argument == 1 ) {
127    Wake_Up_Master();
128    rtems_task_delete( RTEMS_SELF );
129  }
130
131  rtems_test_assert( false );
132}
133
134static rtems_task Init( rtems_task_argument ignored )
135{
136  rtems_id          thread1;
137  rtems_id          thread2;
138  rtems_id          thread3;
139  rtems_status_code rc;
140  int               sc;
141  struct timespec   delay_request;
142
143  TEST_BEGIN();
144
145  Thread_Master = rtems_task_self();
146
147  puts( "Init - pthread key1 create - OK" );
148  sc = pthread_key_create( &key1, NULL );
149  rtems_test_assert( !sc );
150
151  puts( "Init - pthread key2 create - OK" );
152  sc = pthread_key_create( &key2, NULL );
153  rtems_test_assert( !sc );
154
155  puts( "Init - thread1 create - OK" );
156  rc = rtems_task_create(
157    rtems_build_name( 'T', 'E', 'S', 'T' ),
158    1,
159    RTEMS_MINIMUM_STACK_SIZE,
160    RTEMS_DEFAULT_MODES,
161    RTEMS_DEFAULT_ATTRIBUTES,
162    &thread1
163  );
164  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
165
166  rc = rtems_task_start( thread1, Test_Thread1, 0 );
167  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
168
169  puts( "Init - thread2 create - OK" );
170  rc = rtems_task_create(
171    rtems_build_name( 'T', 'E', 'S', 'T' ),
172    1,
173    RTEMS_MINIMUM_STACK_SIZE,
174    RTEMS_DEFAULT_MODES,
175    RTEMS_DEFAULT_ATTRIBUTES,
176    &thread2
177  );
178  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
179
180  rc = rtems_task_start( thread2, Test_Thread2, 0 );
181  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
182
183  puts( "Init - sleep - let thread run - OK" );
184  delay_request.tv_sec = 0;
185  delay_request.tv_nsec = 8 * 100000000;
186  sc = nanosleep( &delay_request, NULL );
187  rtems_test_assert( !sc );
188
189  puts( "Init - pthread key1 delete - OK" );
190  sc = pthread_key_delete( key1 );
191  rtems_test_assert( sc == 0 );
192
193  puts( "Init - pthread key2 delete - OK" );
194  sc = pthread_key_delete( key2 );
195  rtems_test_assert( sc == 0 );
196
197  puts( "Init - pthread key3 create - OK" );
198  sc = pthread_key_create( &key3, Key3_Destructor );
199  rtems_test_assert( sc == 0 );
200
201  puts( "Init - thread3 create - OK" );
202  rc = rtems_task_create(
203    rtems_build_name( 'R', 'E', 'S', 'T' ),
204    1,
205    RTEMS_MINIMUM_STACK_SIZE,
206    RTEMS_DEFAULT_MODES,
207    RTEMS_DEFAULT_ATTRIBUTES,
208    &thread3
209  );
210  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
211
212  puts( "Init - thread3 start - OK" );
213  rc = rtems_task_start( thread3, Test_Thread3, 0 );
214  rtems_test_assert( rc == RTEMS_SUCCESSFUL );
215
216  Wait_For_Worker();
217
218  rtems_test_assert( Key3_Destructor_Counter == 2 );
219
220  puts( "Init - pthread key3 delete - OK" );
221  sc = pthread_key_delete( key3 );
222  rtems_test_assert( sc == 0 );
223
224  TEST_END();
225  rtems_test_exit(0);
226}
227
228/* configuration information */
229
230#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
231#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
232
233#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
234
235#define CONFIGURE_MAXIMUM_TASKS          3
236#define CONFIGURE_MAXIMUM_POSIX_KEYS     2
237
238#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
239
240#define CONFIGURE_INIT
241#include <rtems/confdefs.h>
242
243/* global variables */
Note: See TracBrowser for help on using the repository browser.