]> git.saurik.com Git - apple/libpthread.git/blame - tests/rdar_32848402.c
libpthread-301.1.6.tar.gz
[apple/libpthread.git] / tests / rdar_32848402.c
CommitLineData
a0619f9c
A
1#include <stdio.h>
2#include <stdlib.h>
3#include <dispatch/dispatch.h>
4#include <dispatch/private.h>
5#include <sys/time.h>
6#include <sys/sysctl.h>
7
8#include "darwintest_defaults.h"
9#include <darwintest_utils.h>
10
11static uint64_t end_spin;
12
13static uint32_t
14get_ncpu(void)
15{
16 static uint32_t activecpu;
17 if (!activecpu) {
18 uint32_t n;
19 size_t s = sizeof(activecpu);
20 sysctlbyname("hw.activecpu", &n, &s, NULL, 0);
21 activecpu = n;
22 }
23 return activecpu;
24}
25
26static void
27spin_and_pause(void *ctx)
28{
29 long i = (long)ctx;
30
31 printf("Thread %ld starts\n", i);
32
33 while (clock_gettime_nsec_np(CLOCK_MONOTONIC) < end_spin) {
34#if defined(__x86_64__) || defined(__i386__)
35 __asm__("pause");
36#elif defined(__arm__) || defined(__arm64__)
37 __asm__("wfe");
38#endif
39 }
40 printf("Thread %ld blocks\n", i);
41 pause();
42}
43
44static void
45spin(void *ctx)
46{
47 long i = (long)ctx;
48
49 printf("Thread %ld starts\n", i);
50
51 while (clock_gettime_nsec_np(CLOCK_MONOTONIC)) {
52#if defined(__x86_64__) || defined(__i386__)
53 __asm__("pause");
54#elif defined(__arm__) || defined(__arm64__)
55 __asm__("wfe");
56#endif
57 }
58}
59
60T_DECL(thread_request_32848402, "repro for rdar://32848402")
61{
62 dispatch_queue_attr_t bg_attr, in_attr;
63
64 bg_attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
65 QOS_CLASS_BACKGROUND, 0);
66 in_attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT,
67 QOS_CLASS_USER_INITIATED, 0);
68
69 dispatch_queue_t a = dispatch_queue_create_with_target("in", in_attr, NULL);
70 dispatch_queue_t b = dispatch_queue_create_with_target("bg", bg_attr, NULL);
71
72 end_spin = clock_gettime_nsec_np(CLOCK_MONOTONIC) + 2 * NSEC_PER_SEC;
73
74 dispatch_async_f(a, (void *)0, spin_and_pause);
75 for (long i = 1; i < get_ncpu(); i++) {
76 dispatch_async_f(b, (void *)i, spin);
77 }
78
79 dispatch_async(b, ^{
80 T_PASS("The NCPU+1-nth block got scheduled");
81 T_END;
82 });
83
84 sleep(10);
85 T_FAIL("The NCPU+1-nth block didn't get scheduled");
86}