Skip to content

Commit f53a022

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 f53a022

File tree

1 file changed

+178
-2
lines changed

1 file changed

+178
-2
lines changed

Diff for: testing/ostest/mutex.c

+178-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,164 @@ 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 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+
106176
/****************************************************************************
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+
*
108188
****************************************************************************/
109189

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)
111277
{
112278
pthread_t thread1;
113279
pthread_t thread2;
@@ -164,3 +330,13 @@ void mutex_test(void)
164330
printf("\tLoops\t%lu\t%lu\n", nloops[0], nloops[1]);
165331
printf("\tErrors\t%lu\t%lu\n", nerrors[0], nerrors[1]);
166332
}
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

Comments
 (0)