@@ -53,6 +53,19 @@ static unsigned long nerrors[2] =
53
53
0
54
54
};
55
55
56
+ /****************************************************************************
57
+ * Private Types
58
+ ****************************************************************************/
59
+
60
+ typedef struct
61
+ {
62
+ pthread_mutex_t * mutex_ptr ;
63
+ volatile int * mutex_value ;
64
+ unsigned long * nloops ;
65
+ unsigned long * nerrors ;
66
+ int thread_id ;
67
+ } mutex_thread_args_t ;
68
+
56
69
/****************************************************************************
57
70
* Private Functions
58
71
****************************************************************************/
@@ -103,11 +116,164 @@ static void *thread_func(FAR void *parameter)
103
116
return NULL ; /* Non-reachable -- needed for some compilers */
104
117
}
105
118
119
+ static void * moved_mutex_thread_func (FAR void * parameter )
120
+ {
121
+ FAR struct
122
+ {
123
+ pthread_mutex_t * mutex_ptr ;
124
+ volatile int * mutex_value ;
125
+ unsigned long * nloops ;
126
+ unsigned long * nerrors ;
127
+ int thread_id ;
128
+ } * args = (FAR void * )parameter ;
129
+
130
+ int id = args -> thread_id ;
131
+ int ndx = id - 1 ;
132
+ int i ;
133
+ unsigned long local_loops = 0 ;
134
+
135
+ for (local_loops = 0 ; local_loops < NLOOPS ; local_loops ++ )
136
+ {
137
+ int status = pthread_mutex_lock (args -> mutex_ptr );
138
+ if (status != 0 )
139
+ {
140
+ printf ("ERROR moved mutex thread %d: pthread_mutex_lock failed, status=%d\n" ,
141
+ id , status );
142
+ ASSERT (false);
143
+ }
144
+
145
+ if (* (args -> mutex_value ) == 1 )
146
+ {
147
+ printf ("ERROR moved mutex thread=%d: "
148
+ "moved_mutex_value should be zero, instead moved_mutex_value=%d\n" ,
149
+ id , * (args -> mutex_value ));
150
+ ASSERT (false);
151
+ args -> nerrors [ndx ]++ ;
152
+ }
153
+
154
+ * (args -> mutex_value ) = 1 ;
155
+ for (i = 0 ; i < 10 ; i ++ )
156
+ {
157
+ pthread_yield ();
158
+ }
159
+
160
+ * (args -> mutex_value ) = 0 ;
161
+
162
+ status = pthread_mutex_unlock (args -> mutex_ptr );
163
+ if (status != 0 )
164
+ {
165
+ printf ("ERROR moved mutex thread %d: pthread_mutex_unlock failed, status=%d\n" ,
166
+ id , status );
167
+ ASSERT (false);
168
+ }
169
+ }
170
+
171
+ args -> nloops [ndx ] = local_loops ;
172
+ pthread_exit (NULL );
173
+ return NULL ;
174
+ }
175
+
106
176
/****************************************************************************
107
- * Public Functions
177
+ * Name: mutex_move_test
178
+ *
179
+ * Description:
180
+ * Test the mutex move functionality. This test creates a mutex, moves
181
+ * it to a new location, and then starts two threads that use the moved
182
+ * mutex.
183
+ * POSIX specification does not define the behavior of a mutex that is
184
+ * moved. This test is intended to verify that the mutex can be moved,
185
+ * it's useful for some cases, see the discussion in
186
+ * https://github.com/rust-lang/rust/pull/138400
187
+ *
108
188
****************************************************************************/
109
189
110
- void mutex_test (void )
190
+ static void mutex_move_test (void )
191
+ {
192
+ pthread_t thread1 ;
193
+ pthread_t thread2 ;
194
+ #ifdef SDCC
195
+ pthread_addr_t result1 ;
196
+ pthread_addr_t result2 ;
197
+ pthread_attr_t attr ;
198
+ #endif
199
+ int status ;
200
+ pthread_mutex_t initial_mutex ;
201
+ pthread_mutex_t moved_mutex ;
202
+ volatile int moved_mutex_value = 0 ;
203
+ unsigned long moved_nloops [2 ] = {0 , 0 };
204
+ unsigned long moved_nerrors [2 ] = {0 , 0 };
205
+
206
+ printf ("\nTesting moved mutex\n" );
207
+
208
+ /* Allocate and initialize first mutex */
209
+
210
+ pthread_mutex_init (& initial_mutex , NULL );
211
+
212
+ /* Copy the mutex to new location */
213
+
214
+ memcpy (& moved_mutex , & initial_mutex , sizeof (pthread_mutex_t ));
215
+
216
+ /* Destroy the original mutex */
217
+
218
+ pthread_mutex_destroy (& initial_mutex );
219
+
220
+ mutex_thread_args_t thread1_args , thread2_args ;
221
+
222
+ thread1_args .mutex_ptr = & moved_mutex ;
223
+ thread1_args .mutex_value = & moved_mutex_value ;
224
+ thread1_args .nloops = moved_nloops ;
225
+ thread1_args .nerrors = moved_nerrors ;
226
+ thread1_args .thread_id = 1 ;
227
+
228
+ thread2_args .mutex_ptr = & moved_mutex ;
229
+ thread2_args .mutex_value = & moved_mutex_value ;
230
+ thread2_args .nloops = moved_nloops ;
231
+ thread2_args .nerrors = moved_nerrors ;
232
+ thread2_args .thread_id = 2 ;
233
+
234
+ /* Start two threads using the moved mutex */
235
+
236
+ printf ("Starting moved mutex thread 1\n" );
237
+ #ifdef SDCC
238
+ pthread_attr_init (& attr );
239
+ status = pthread_create (& thread1 , & attr , moved_mutex_thread_func , & thread1_args );
240
+ #else
241
+ status = pthread_create (& thread1 , NULL , moved_mutex_thread_func , & thread1_args );
242
+ #endif
243
+ if (status != 0 )
244
+ {
245
+ printf ("ERROR in moved mutex thread#1 creation\n" );
246
+ ASSERT (false);
247
+ }
248
+
249
+ printf ("Starting moved mutex thread 2\n" );
250
+ #ifdef SDCC
251
+ status = pthread_create (& thread2 , & attr , moved_mutex_thread_func , & thread2_args );
252
+ #else
253
+ status = pthread_create (& thread2 , NULL , moved_mutex_thread_func , & thread2_args );
254
+ #endif
255
+ if (status != 0 )
256
+ {
257
+ printf ("ERROR in moved mutex thread#2 creation\n" );
258
+ ASSERT (false);
259
+ }
260
+
261
+ #ifdef SDCC
262
+ pthread_join (thread1 , & result1 );
263
+ pthread_join (thread2 , & result2 );
264
+ #else
265
+ pthread_join (thread1 , NULL );
266
+ pthread_join (thread2 , NULL );
267
+ #endif
268
+
269
+ pthread_mutex_destroy (& moved_mutex );
270
+
271
+ printf ("\t\tThread1\tThread2\n" );
272
+ printf ("\tMoved Loops\t%lu\t%lu\n" , moved_nloops [0 ], moved_nloops [1 ]);
273
+ printf ("\tMoved Errors\t%lu\t%lu\n" , moved_nerrors [0 ], moved_nerrors [1 ]);
274
+ }
275
+
276
+ void mutex_simple_test (void )
111
277
{
112
278
pthread_t thread1 ;
113
279
pthread_t thread2 ;
@@ -164,3 +330,13 @@ void mutex_test(void)
164
330
printf ("\tLoops\t%lu\t%lu\n" , nloops [0 ], nloops [1 ]);
165
331
printf ("\tErrors\t%lu\t%lu\n" , nerrors [0 ], nerrors [1 ]);
166
332
}
333
+
334
+ /****************************************************************************
335
+ * Public Functions
336
+ ****************************************************************************/
337
+
338
+ void mutex_test (void )
339
+ {
340
+ mutex_simple_test ();
341
+ mutex_move_test ();
342
+ }
0 commit comments