Skip to content

Commit f9f5cd3

Browse files
author
Chun Chen Hsu
committed
Use a condition variable to control busy threads in dispatch_apply test
The dispatch_apply test sometimes fails in multicore machines. The failed function is test_apply_contended which tests if dispatch_apply can make progress and finish with N concurrent busy threads running, where N is the number of CPUs. According to the testing log, it fails because some busy threads already finish before dispatch_apply() is invoked. This happens because the test uses the ITERS_PER_SECOND variable to control the number of iteration of the loop in the busy thread and optimistically __hope__ the execution time is long enough to complete the test. But sometimes this hope fails when the testing machine has greater computing power and more CPU cores. Instead of using ITERS_PER_SECOND, which makes an assumption about the computing power of the test machine, a condition variable is used to control execution of busy threads. It makes sure the busy thread can only finish after dispatch_apply completes.
1 parent e922531 commit f9f5cd3

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

tests/dispatch_apply.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,7 @@ static volatile int32_t busy_threads_started, busy_threads_finished;
3737
/*
3838
* Keep a thread busy, spinning on the CPU.
3939
*/
40-
#if TARGET_OS_EMBEDDED
41-
// iPhone 4
42-
#define ITERS_PER_SECOND 50000000UL
43-
#elif __s390x__
44-
#define ITERS_PER_SECOND 15000000000UL
45-
#else
46-
// On a 2.7 4-core i5 iMac12,2, one thread of this loop runs at ROUGHLY:
47-
#define ITERS_PER_SECOND 1000000000UL
48-
#endif
40+
static volatile int all_done = 0;
4941

5042
/* Fiddling with j in the middle and hitting this global will hopefully keep
5143
* the optimizer from cutting the whole thing out as dead code.
@@ -54,14 +46,16 @@ static volatile unsigned int busythread_useless;
5446
void busythread(void *ignored)
5547
{
5648
(void)ignored;
57-
uint64_t i = 0, j = 0;
49+
/* prevent i and j been optimized out */
50+
volatile uint64_t i = 0, j = 0;
5851

5952
OSAtomicIncrement32(&busy_threads_started);
6053

61-
for(i = 0; i < 2*ITERS_PER_SECOND; i++)
54+
while(!all_done)
6255
{
6356
if(i == 500000) { j -= busythread_useless; }
6457
j += i;
58+
i += 1;
6559
}
6660

6761
OSAtomicIncrement32(&busy_threads_finished);
@@ -109,6 +103,9 @@ void test_apply_contended(dispatch_queue_t dq)
109103
test_long("contended: count", count, final);
110104
test_long("contended: threads finished before apply", after, 0);
111105

106+
/* Release busy threads by setting all_done to 1 */
107+
all_done = 1;
108+
112109
dispatch_group_wait(grp, DISPATCH_TIME_FOREVER);
113110
dispatch_release(grp);
114111

0 commit comments

Comments
 (0)