9 const size_t kNumThreds
= 16;
10 const size_t kNumIters
= 1 << 23;
12 inline void break_optimization(void *arg
) {
13 __asm__
__volatile__("" : : "r" (arg
) : "memory");
16 __attribute__((noinline
))
17 static void *MallocThread(void *t
) {
18 size_t total_malloced
= 0, total_freed
= 0;
19 size_t max_in_use
= 0;
20 size_t tid
= reinterpret_cast<size_t>(t
);
21 vector
<pair
<char *, size_t> > allocated
;
22 allocated
.reserve(kNumIters
);
23 for (size_t i
= 1; i
< kNumIters
; i
++) {
24 if ((i
% (kNumIters
/ 4)) == 0 && tid
== 0)
25 fprintf(stderr
, " T[%ld] iter %ld\n", tid
, i
);
26 bool allocate
= (i
% 5) <= 2; // 60% malloc, 40% free
27 if (i
> kNumIters
/ 4)
28 allocate
= i
% 2; // then switch to 50% malloc, 50% free
30 size_t size
= 1 + (i
% 200);
33 total_malloced
+= size
;
34 char *x
= new char[size
];
35 x
[0] = x
[size
- 1] = x
[size
/ 2] = 0;
36 allocated
.push_back(make_pair(x
, size
));
37 max_in_use
= max(max_in_use
, total_malloced
- total_freed
);
39 if (allocated
.empty()) continue;
40 size_t slot
= i
% allocated
.size();
41 char *p
= allocated
[slot
].first
;
42 p
[0] = 0; // emulate last user touch of the block
43 size_t size
= allocated
[slot
].second
;
45 swap(allocated
[slot
], allocated
.back());
51 fprintf(stderr
, " T[%ld] total_malloced: %ldM in use %ldM max %ldM\n",
52 tid
, total_malloced
>> 20, (total_malloced
- total_freed
) >> 20,
54 for (size_t i
= 0; i
< allocated
.size(); i
++)
55 delete [] allocated
[i
].first
;
61 __attribute__((noinline
))
62 static void *run(void *t
) {
63 break_optimization(0);
64 DeepStack
<depth
- 1>::run(t
);
65 break_optimization(0);
72 static void *run(void *t
) {
78 // Build with -Dstandalone_malloc_test=main to make it a separate program.
79 int standalone_malloc_test() {
80 pthread_t t
[kNumThreds
];
81 for (size_t i
= 0; i
< kNumThreds
; i
++)
82 pthread_create(&t
[i
], 0, DeepStack
<200>::run
, reinterpret_cast<void *>(i
));
83 for (size_t i
= 0; i
< kNumThreds
; i
++)
84 pthread_join(t
[i
], 0);