14
14
#define NUM_THREADS 8
15
15
#define NUM_ALLOCATIONS 10240
16
16
#if ABORTING_MALLOC
17
- #define ALLOCATION_SIZE 1280 // Malloc aborts, so allocate a bit less of memory so all fits
17
+ // Malloc aborts, so allocate a bit less of memory so all fits
18
+ #define ALLOCATION_SIZE 1280
18
19
#else
19
- #define ALLOCATION_SIZE 2560 // Malloc doesn't abort, allocate a bit more memory to test graceful allocation failures
20
+ // Malloc doesn't abort, allocate a bit more memory to test graceful allocation
21
+ // failures
22
+ #define ALLOCATION_SIZE 2560
20
23
#endif
21
24
22
25
#define RESULT_OK 0
23
26
#define RESULT_EXPECTED_FAILS 1
24
27
#define RESULT_BAD_FAIL 2
25
28
26
- // Use barriers to make each thread synchronize their execution points, to maximize the possibility of seeing race conditions
27
- // if those might occur.
29
+ // Use barriers to make each thread synchronize their execution points, to
30
+ // maximize the possibility of seeing race conditions if those might occur.
28
31
static pthread_barrier_t barrierWaitToAlloc;
29
32
static pthread_barrier_t barrierWaitToVerify;
30
33
static pthread_barrier_t barrierWaitToFree;
31
34
32
35
// Use a mutex for logging.
33
36
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
34
37
35
- static void *thread_start (void *arg)
36
- {
38
+ static void *thread_start (void *arg) {
37
39
#if DEBUG
38
40
pthread_mutex_lock ( &mutex );
39
41
printf (" thread started, will try %d allocations of size %d\n " , NUM_ALLOCATIONS, ALLOCATION_SIZE);
@@ -48,47 +50,57 @@ static void *thread_start(void *arg)
48
50
int some_allocations_failed = 0 ;
49
51
size_t allocated = 0 ;
50
52
51
- pthread_barrier_wait (&barrierWaitToAlloc); // Halt until all threads reach here, then proceed synchronously.
52
- for ( int i = 0 ; i < NUM_ALLOCATIONS; ++i)
53
- {
53
+ // Halt until all threads reach here, then proceed synchronously.
54
+ pthread_barrier_wait (&barrierWaitToAlloc);
55
+ for ( int i = 0 ; i < NUM_ALLOCATIONS; ++i) {
54
56
allocated_buffers[i] = (uint8_t *)malloc (ALLOCATION_SIZE);
55
57
if (allocated_buffers[i]) {
56
58
memset (allocated_buffers[i], id, ALLOCATION_SIZE);
57
59
allocated += ALLOCATION_SIZE;
58
- } else
60
+ } else {
59
61
some_allocations_failed = 1 ;
62
+ }
60
63
}
61
64
#if DEBUG
62
65
pthread_mutex_lock ( &mutex );
63
66
printf (" total allocations: %u (%d of size %d tried), some failed? %d\n " , allocated, NUM_ALLOCATIONS, ALLOCATION_SIZE, some_allocations_failed);
64
67
pthread_mutex_unlock ( &mutex );
65
68
#endif
66
- pthread_barrier_wait (&barrierWaitToVerify); // Halt until all threads reach here, then proceed synchronously.
69
+ // Halt until all threads reach here, then proceed synchronously.
70
+ pthread_barrier_wait (&barrierWaitToVerify);
67
71
int reported_once = 0 ;
68
- for (int i = 0 ; i < NUM_ALLOCATIONS; ++i)
69
- {
72
+ for (int i = 0 ; i < NUM_ALLOCATIONS; ++i) {
70
73
if (!allocated_buffers[i]) continue ;
71
- for (int j = 0 ; j < ALLOCATION_SIZE; ++j)
72
- if (allocated_buffers[i][j] != id)
73
- {
74
- ++return_code; // Failed! (but run to completion so that the barriers will all properly proceed without hanging)
74
+ for (int j = 0 ; j < ALLOCATION_SIZE; ++j)
75
+ if (allocated_buffers[i][j] != id) {
76
+ // Failed! (but run to completion so that the barriers will all properly
77
+ // proceed without hanging)
78
+ ++return_code;
75
79
if (!reported_once) {
76
80
emscripten_errf (" Memory corrupted! mem[i]: %d != %ld, i: %d, j: %d" , allocated_buffers[i][j], id, i, j);
77
- reported_once = 1 ; // Avoid print flood that makes debugging hard.
81
+ // Avoid print flood that makes debugging hard.
82
+ reported_once = 1 ;
78
83
}
79
84
}
80
85
}
81
86
82
87
pthread_barrier_wait (&barrierWaitToFree); // Halt until all threads reach here, then proceed synchronously.
83
- for (int i = 0 ; i < NUM_ALLOCATIONS; ++i)
88
+ for (int i = 0 ; i < NUM_ALLOCATIONS; ++i) {
84
89
free (allocated_buffers[i]);
90
+ }
85
91
86
92
#if ABORTING_MALLOC
87
- if (some_allocations_failed)
88
- return_code = RESULT_BAD_FAIL; // We expect allocations not to fail (if they did, shouldn't reach here, but we should have aborted)
93
+ if (some_allocations_failed) {
94
+ // We expect allocations not to fail (if they did, shouldn't reach here, but
95
+ // we should have aborted)
96
+ return_code = RESULT_BAD_FAIL;
97
+ }
89
98
#else
90
- if (some_allocations_failed)
91
- return_code = RESULT_EXPECTED_FAILS; // We expect to be allocating so much memory that some of the allocations fail.
99
+ if (some_allocations_failed) {
100
+ // We expect to be allocating so much memory that some of the allocations
101
+ // fail.
102
+ return_code = RESULT_EXPECTED_FAILS;
103
+ }
92
104
// Otherwise, the fails might happen in another thread, that's cool.
93
105
#endif
94
106
#if DEBUG
@@ -99,8 +111,7 @@ static void *thread_start(void *arg)
99
111
pthread_exit ((void *)return_code);
100
112
}
101
113
102
- int main ()
103
- {
114
+ int main () {
104
115
printf (" starting test, aborting? %d\n " , ABORTING_MALLOC);
105
116
106
117
int ret = pthread_barrier_init (&barrierWaitToAlloc, NULL , NUM_THREADS);
@@ -110,9 +121,8 @@ int main()
110
121
ret = pthread_barrier_init (&barrierWaitToFree, NULL , NUM_THREADS);
111
122
assert (ret == 0 );
112
123
113
- pthread_t thr[8 /* NUM_THREADS*/ ];
114
- for (intptr_t i = 0 ; i < NUM_THREADS; ++i)
115
- {
124
+ pthread_t thr[NUM_THREADS];
125
+ for (intptr_t i = 0 ; i < NUM_THREADS; ++i) {
116
126
pthread_attr_t attr;
117
127
pthread_attr_init (&attr);
118
128
pthread_attr_setstacksize (&attr, NUM_ALLOCATIONS*80 );
@@ -122,7 +132,7 @@ int main()
122
132
123
133
int seen_expected_fails = 0 ;
124
134
125
- for (int i = 0 ; i < NUM_THREADS; ++i) {
135
+ for (int i = 0 ; i < NUM_THREADS; ++i) {
126
136
int res = 0 ;
127
137
ret = pthread_join (thr[i], (void **)&res);
128
138
assert (ret == 0 );
0 commit comments