Skip to content

Commit f87805b

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 f87805b

File tree

1 file changed

+167
-55
lines changed

1 file changed

+167
-55
lines changed

testing/ostest/mutex.c

+167-55
Original file line numberDiff line numberDiff line change
@@ -35,132 +35,244 @@
3535
****************************************************************************/
3636

3737
#define NLOOPS 32
38+
#define NYIELDS 10
3839

3940
/****************************************************************************
40-
* Private Data
41+
* Private Types
4142
****************************************************************************/
4243

43-
static pthread_mutex_t mut;
44-
static volatile int my_mutex = 0;
45-
static unsigned long nloops[2] =
46-
{
47-
0,
48-
0
49-
};
50-
static unsigned long nerrors[2] =
51-
{
52-
0,
53-
0
54-
};
44+
typedef struct
45+
{
46+
pthread_mutex_t *mutex_ptr;
47+
volatile int *mutex_value;
48+
int *nloops;
49+
int *nerrors;
50+
int thread_id;
51+
} mutex_thread_args_t;
5552

5653
/****************************************************************************
5754
* Private Functions
5855
****************************************************************************/
5956

60-
static void *thread_func(FAR void *parameter)
57+
static void *mutex_thread_func(FAR void *parameter)
6158
{
62-
int id = (int)((intptr_t)parameter);
59+
FAR mutex_thread_args_t *args = (FAR mutex_thread_args_t *)parameter;
60+
61+
int id = args->thread_id;
6362
int ndx = id - 1;
6463
int i;
64+
int local_loops = 0;
6565

66-
for (nloops[ndx] = 0; nloops[ndx] < NLOOPS; nloops[ndx]++)
66+
for (local_loops = 0; local_loops < NLOOPS; local_loops++)
6767
{
68-
int status = pthread_mutex_lock(&mut);
68+
int status = pthread_mutex_lock(args->mutex_ptr);
6969
if (status != 0)
7070
{
71-
printf("ERROR thread %d: pthread_mutex_lock failed, status=%d\n",
72-
id, status);
71+
printf("ERROR thread %d: pthread_mutex_lock failed, "
72+
"status=%d\n", id, status);
7373
ASSERT(false);
7474
}
7575

76-
if (my_mutex == 1)
76+
if (*(args->mutex_value) == 1)
7777
{
7878
printf("ERROR thread=%d: "
79-
"my_mutex should be zero, instead my_mutex=%d\n",
80-
id, my_mutex);
79+
"mutex value should be zero, "
80+
"instead mutex value=%d\n",
81+
id, *(args->mutex_value));
8182
ASSERT(false);
82-
nerrors[ndx]++;
83+
args->nerrors[ndx]++;
8384
}
8485

85-
my_mutex = 1;
86-
for (i = 0; i < 10; i++)
86+
*(args->mutex_value) = 1;
87+
for (i = 0; i < NYIELDS; i++)
8788
{
8889
pthread_yield();
8990
}
9091

91-
my_mutex = 0;
92+
*(args->mutex_value) = 0;
9293

93-
status = pthread_mutex_unlock(&mut);
94+
status = pthread_mutex_unlock(args->mutex_ptr);
9495
if (status != 0)
9596
{
96-
printf("ERROR thread %d: pthread_mutex_unlock failed, status=%d\n",
97-
id, status);
97+
printf("ERROR thread %d: pthread_mutex_unlock failed, "
98+
"status=%d\n", id, status);
9899
ASSERT(false);
99100
}
100101
}
101102

103+
args->nloops[ndx] = local_loops;
102104
pthread_exit(NULL);
103-
return NULL; /* Non-reachable -- needed for some compilers */
105+
return NULL;
104106
}
105107

106108
/****************************************************************************
107-
* Public Functions
109+
* Name: mutex_move_test
110+
*
111+
* Description:
112+
* Test the mutex move functionality. This test creates a mutex, moves
113+
* it to a new location, and then starts two threads that use the moved
114+
* mutex.
115+
* POSIX specification does not define the behavior of a mutex that is
116+
* moved. This test is intended to verify that the mutex can be moved,
117+
* which is useful for some cases, see the discussion in
118+
* https://github.com/rust-lang/rust/pull/138400
119+
*
108120
****************************************************************************/
109121

110-
void mutex_test(void)
122+
static void mutex_move_test(void)
111123
{
112124
pthread_t thread1;
113125
pthread_t thread2;
114-
#ifdef SDCC
115-
pthread_addr_t result1;
116-
pthread_addr_t result2;
117-
pthread_attr_t attr;
118-
#endif
119126
int status;
127+
pthread_mutex_t initial_mutex;
128+
pthread_mutex_t moved_mutex;
129+
volatile int moved_mutex_value = 0;
130+
int moved_nloops[2] =
131+
{
132+
0,
133+
0
134+
};
135+
136+
int moved_nerrors[2] =
137+
{
138+
0,
139+
0
140+
};
141+
142+
printf("\nTesting moved mutex\n");
143+
144+
/* Allocate and initialize first mutex */
145+
146+
pthread_mutex_init(&initial_mutex, NULL);
147+
148+
/* Copy the mutex to new location */
149+
150+
memcpy(&moved_mutex, &initial_mutex, sizeof(pthread_mutex_t));
151+
152+
/* Destroy the original mutex */
153+
154+
pthread_mutex_destroy(&initial_mutex);
155+
156+
mutex_thread_args_t thread1_args;
157+
mutex_thread_args_t thread2_args;
158+
159+
thread1_args.mutex_ptr = &moved_mutex;
160+
thread1_args.mutex_value = &moved_mutex_value;
161+
thread1_args.nloops = moved_nloops;
162+
thread1_args.nerrors = moved_nerrors;
163+
thread1_args.thread_id = 1;
164+
165+
thread2_args.mutex_ptr = &moved_mutex;
166+
thread2_args.mutex_value = &moved_mutex_value;
167+
thread2_args.nloops = moved_nloops;
168+
thread2_args.nerrors = moved_nerrors;
169+
thread2_args.thread_id = 2;
170+
171+
/* Start two threads using the moved mutex */
172+
173+
printf("Starting moved mutex thread 1\n");
174+
status = pthread_create(&thread1, NULL, mutex_thread_func,
175+
&thread1_args);
176+
if (status != 0)
177+
{
178+
printf("ERROR in moved mutex thread#1 creation\n");
179+
ASSERT(false);
180+
}
181+
182+
printf("Starting moved mutex thread 2\n");
183+
status = pthread_create(&thread2, NULL, mutex_thread_func,
184+
&thread2_args);
185+
if (status != 0)
186+
{
187+
printf("ERROR in moved mutex thread#2 creation\n");
188+
ASSERT(false);
189+
}
190+
191+
pthread_join(thread1, NULL);
192+
pthread_join(thread2, NULL);
193+
194+
pthread_mutex_destroy(&moved_mutex);
195+
196+
printf("\t\tThread1\tThread2\n");
197+
printf("\tMoved Loops\t%u\t%u\n", moved_nloops[0], moved_nloops[1]);
198+
printf("\tMoved Errors\t%u\t%u\n", moved_nerrors[0], moved_nerrors[1]);
199+
}
200+
201+
void mutex_simple_test(void)
202+
{
203+
pthread_t thread1;
204+
pthread_t thread2;
205+
int status;
206+
mutex_thread_args_t thread1_args;
207+
mutex_thread_args_t thread2_args;
208+
209+
pthread_mutex_t mut;
210+
volatile int my_mutex = 0;
211+
int nloops[2] =
212+
{
213+
0,
214+
0
215+
};
216+
217+
int nerrors[2] =
218+
{
219+
0,
220+
0
221+
};
120222

121223
/* Initialize the mutex */
122224

123225
printf("Initializing mutex\n");
124226
pthread_mutex_init(&mut, NULL);
125227

228+
/* Set up thread arguments */
229+
230+
thread1_args.mutex_ptr = &mut;
231+
thread1_args.mutex_value = &my_mutex;
232+
thread1_args.nloops = nloops;
233+
thread1_args.nerrors = nerrors;
234+
thread1_args.thread_id = 1;
235+
236+
thread2_args.mutex_ptr = &mut;
237+
thread2_args.mutex_value = &my_mutex;
238+
thread2_args.nloops = nloops;
239+
thread2_args.nerrors = nerrors;
240+
thread2_args.thread_id = 2;
241+
126242
/* Start two thread instances */
127243

128244
printf("Starting thread 1\n");
129-
#ifdef SDCC
130-
pthread_attr_init(&attr);
131-
status = pthread_create(&thread1, &attr, thread_func, (pthread_addr_t)1);
132-
#else
133-
status = pthread_create(&thread1, NULL, thread_func, (pthread_addr_t)1);
134-
#endif
245+
status = pthread_create(&thread1, NULL, mutex_thread_func, &thread1_args);
135246
if (status != 0)
136247
{
137248
printf("ERROR in thread#1 creation\n");
138249
ASSERT(false);
139250
}
140251

141252
printf("Starting thread 2\n");
142-
#ifdef SDCC
143-
status = pthread_create(&thread2, &attr, thread_func, (pthread_addr_t)2);
144-
#else
145-
status = pthread_create(&thread2, NULL, thread_func, (pthread_addr_t)2);
146-
#endif
253+
status = pthread_create(&thread2, NULL, mutex_thread_func, &thread2_args);
147254
if (status != 0)
148255
{
149256
printf("ERROR in thread#2 creation\n");
150257
ASSERT(false);
151258
}
152259

153-
#ifdef SDCC
154-
pthread_join(thread1, &result1);
155-
pthread_join(thread2, &result2);
156-
#else
157260
pthread_join(thread1, NULL);
158261
pthread_join(thread2, NULL);
159-
#endif
160262

161263
pthread_mutex_destroy(&mut);
162264

163265
printf("\t\tThread1\tThread2\n");
164-
printf("\tLoops\t%lu\t%lu\n", nloops[0], nloops[1]);
165-
printf("\tErrors\t%lu\t%lu\n", nerrors[0], nerrors[1]);
266+
printf("\tLoops\t%u\t%u\n", nloops[0], nloops[1]);
267+
printf("\tErrors\t%u\t%u\n", nerrors[0], nerrors[1]);
268+
}
269+
270+
/****************************************************************************
271+
* Public Functions
272+
****************************************************************************/
273+
274+
void mutex_test(void)
275+
{
276+
mutex_simple_test();
277+
mutex_move_test();
166278
}

0 commit comments

Comments
 (0)