Skip to content

Commit 8406989

Browse files
committed
ostest: Implement mutex move test functionality
Add a new test for moving mutexes to verify behavior when a mutex is relocated. * Introduced mutex_thread_args_t structure for thread arguments * Created moved_mutex_thread_func to handle mutex operations in threads * Updated mutex_test to include mutex_move_test for comprehensive testing Signed-off-by: Huang Qi <[email protected]>
1 parent 3b03636 commit 8406989

File tree

1 file changed

+186
-2
lines changed

1 file changed

+186
-2
lines changed

testing/ostest/mutex.c

+186-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ static unsigned long nerrors[2] =
5353
0
5454
};
5555

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+
5669
/****************************************************************************
5770
* Private Functions
5871
****************************************************************************/
@@ -103,11 +116,172 @@ static void *thread_func(FAR void *parameter)
103116
return NULL; /* Non-reachable -- needed for some compilers */
104117
}
105118

119+
static void *moved_mutex_thread_func(FAR void *parameter)
120+
{
121+
FAR mutex_thread_args_t *args = (FAR mutex_thread_args_t *)parameter;
122+
123+
int id = args->thread_id;
124+
int ndx = id - 1;
125+
int i;
126+
unsigned long local_loops = 0;
127+
128+
for (local_loops = 0; local_loops < NLOOPS; local_loops++)
129+
{
130+
int status = pthread_mutex_lock(args->mutex_ptr);
131+
if (status != 0)
132+
{
133+
printf("ERROR moved mutex thread %d: pthread_mutex_lock failed, "
134+
"status=%d\n", id, status);
135+
ASSERT(false);
136+
}
137+
138+
if (*(args->mutex_value) == 1)
139+
{
140+
printf("ERROR moved mutex thread=%d: "
141+
"moved_mutex_value should be zero, "
142+
"instead moved_mutex_value=%d\n",
143+
id, *(args->mutex_value));
144+
ASSERT(false);
145+
args->nerrors[ndx]++;
146+
}
147+
148+
*(args->mutex_value) = 1;
149+
for (i = 0; i < 10; i++)
150+
{
151+
pthread_yield();
152+
}
153+
154+
*(args->mutex_value) = 0;
155+
156+
status = pthread_mutex_unlock(args->mutex_ptr);
157+
if (status != 0)
158+
{
159+
printf("ERROR moved mutex thread %d: pthread_mutex_unlock failed, "
160+
"status=%d\n", id, status);
161+
ASSERT(false);
162+
}
163+
}
164+
165+
args->nloops[ndx] = local_loops;
166+
pthread_exit(NULL);
167+
return NULL;
168+
}
169+
106170
/****************************************************************************
107-
* Public Functions
171+
* Name: mutex_move_test
172+
*
173+
* Description:
174+
* Test the mutex move functionality. This test creates a mutex, moves
175+
* it to a new location, and then starts two threads that use the moved
176+
* mutex.
177+
* POSIX specification does not define the behavior of a mutex that is
178+
* moved. This test is intended to verify that the mutex can be moved,
179+
* it's useful for some cases, see the discussion in
180+
* https://github.com/rust-lang/rust/pull/138400
181+
*
108182
****************************************************************************/
109183

110-
void mutex_test(void)
184+
static void mutex_move_test(void)
185+
{
186+
pthread_t thread1;
187+
pthread_t thread2;
188+
#ifdef SDCC
189+
pthread_addr_t result1;
190+
pthread_addr_t result2;
191+
pthread_attr_t attr;
192+
#endif
193+
int status;
194+
pthread_mutex_t initial_mutex;
195+
pthread_mutex_t moved_mutex;
196+
volatile int moved_mutex_value = 0;
197+
unsigned long moved_nloops[2] =
198+
{
199+
0,
200+
0
201+
};
202+
203+
unsigned long moved_nerrors[2] =
204+
{
205+
0,
206+
0
207+
};
208+
209+
printf("\nTesting moved mutex\n");
210+
211+
/* Allocate and initialize first mutex */
212+
213+
pthread_mutex_init(&initial_mutex, NULL);
214+
215+
/* Copy the mutex to new location */
216+
217+
memcpy(&moved_mutex, &initial_mutex, sizeof(pthread_mutex_t));
218+
219+
/* Destroy the original mutex */
220+
221+
pthread_mutex_destroy(&initial_mutex);
222+
223+
mutex_thread_args_t thread1_args;
224+
mutex_thread_args_t thread2_args;
225+
226+
thread1_args.mutex_ptr = &moved_mutex;
227+
thread1_args.mutex_value = &moved_mutex_value;
228+
thread1_args.nloops = moved_nloops;
229+
thread1_args.nerrors = moved_nerrors;
230+
thread1_args.thread_id = 1;
231+
232+
thread2_args.mutex_ptr = &moved_mutex;
233+
thread2_args.mutex_value = &moved_mutex_value;
234+
thread2_args.nloops = moved_nloops;
235+
thread2_args.nerrors = moved_nerrors;
236+
thread2_args.thread_id = 2;
237+
238+
/* Start two threads using the moved mutex */
239+
240+
printf("Starting moved mutex thread 1\n");
241+
#ifdef SDCC
242+
pthread_attr_init(&attr);
243+
status = pthread_create(&thread1, &attr, moved_mutex_thread_func,
244+
&thread1_args);
245+
#else
246+
status = pthread_create(&thread1, NULL, moved_mutex_thread_func,
247+
&thread1_args);
248+
#endif
249+
if (status != 0)
250+
{
251+
printf("ERROR in moved mutex thread#1 creation\n");
252+
ASSERT(false);
253+
}
254+
255+
printf("Starting moved mutex thread 2\n");
256+
#ifdef SDCC
257+
status = pthread_create(&thread2, &attr, moved_mutex_thread_func,
258+
&thread2_args);
259+
#else
260+
status = pthread_create(&thread2, NULL, moved_mutex_thread_func,
261+
&thread2_args);
262+
#endif
263+
if (status != 0)
264+
{
265+
printf("ERROR in moved mutex thread#2 creation\n");
266+
ASSERT(false);
267+
}
268+
269+
#ifdef SDCC
270+
pthread_join(thread1, &result1);
271+
pthread_join(thread2, &result2);
272+
#else
273+
pthread_join(thread1, NULL);
274+
pthread_join(thread2, NULL);
275+
#endif
276+
277+
pthread_mutex_destroy(&moved_mutex);
278+
279+
printf("\t\tThread1\tThread2\n");
280+
printf("\tMoved Loops\t%lu\t%lu\n", moved_nloops[0], moved_nloops[1]);
281+
printf("\tMoved Errors\t%lu\t%lu\n", moved_nerrors[0], moved_nerrors[1]);
282+
}
283+
284+
void mutex_simple_test(void)
111285
{
112286
pthread_t thread1;
113287
pthread_t thread2;
@@ -164,3 +338,13 @@ void mutex_test(void)
164338
printf("\tLoops\t%lu\t%lu\n", nloops[0], nloops[1]);
165339
printf("\tErrors\t%lu\t%lu\n", nerrors[0], nerrors[1]);
166340
}
341+
342+
/****************************************************************************
343+
* Public Functions
344+
****************************************************************************/
345+
346+
void mutex_test(void)
347+
{
348+
mutex_simple_test();
349+
mutex_move_test();
350+
}

0 commit comments

Comments
 (0)