]>
Commit | Line | Data |
---|---|---|
13ba007e A |
1 | // TEST_CFLAGS -framework Foundation |
2 | // TEST_CONFIG MEM=mrc ARCH=x86_64 | |
3 | ||
4 | // Stress-test nonpointer isa's side table retain count transfers. | |
5 | ||
6 | // x86_64 only. arm64's side table limit is high enough that bugs | |
7 | // are harder to reproduce. | |
8 | ||
9 | #include "test.h" | |
10 | #import <Foundation/Foundation.h> | |
11 | ||
34d5b5e8 | 12 | #define OBJECTS 10 |
13ba007e A |
13 | #define LOOPS 256 |
14 | #define THREADS 16 | |
15 | #if __x86_64__ | |
16 | # define RC_HALF (1ULL<<7) | |
17 | #else | |
18 | # error sorry | |
19 | #endif | |
20 | #define RC_DELTA RC_HALF | |
21 | ||
22 | static bool Deallocated = false; | |
23 | @interface Deallocator : NSObject @end | |
24 | @implementation Deallocator | |
25 | -(void)dealloc { | |
26 | Deallocated = true; | |
27 | [super dealloc]; | |
28 | } | |
29 | @end | |
30 | ||
31 | // This is global to avoid extra retains by the dispatch block objects. | |
32 | static Deallocator *obj; | |
33 | ||
34 | int main() { | |
35 | dispatch_queue_t queue = | |
36 | dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); | |
37 | ||
38 | for (size_t i = 0; i < OBJECTS; i++) { | |
39 | obj = [Deallocator new]; | |
40 | ||
41 | dispatch_apply(THREADS, queue, ^(size_t i __unused) { | |
42 | for (size_t a = 0; a < LOOPS; a++) { | |
43 | for (size_t b = 0; b < RC_DELTA; b++) { | |
44 | [obj retain]; | |
45 | } | |
46 | for (size_t b = 0; b < RC_DELTA; b++) { | |
47 | [obj release]; | |
48 | } | |
49 | } | |
50 | }); | |
51 | ||
52 | testassert(!Deallocated); | |
53 | [obj release]; | |
54 | testassert(Deallocated); | |
55 | Deallocated = false; | |
56 | } | |
57 | ||
58 | succeed(__FILE__); | |
59 | } |