Skip to content

Commit

Permalink
[test] Remove some unnecessary usage of TOTAL_MEMORY and INITIAL_MEMO…
Browse files Browse the repository at this point in the history
…RY. NFC (#21303)
  • Loading branch information
sbc100 authored Feb 9, 2024
1 parent 833448b commit c06a2b0
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 33 deletions.
68 changes: 39 additions & 29 deletions test/pthread/test_pthread_sbrk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,28 @@
#define NUM_THREADS 8
#define NUM_ALLOCATIONS 10240
#if ABORTING_MALLOC
#define ALLOCATION_SIZE 1280 // Malloc aborts, so allocate a bit less of memory so all fits
// Malloc aborts, so allocate a bit less of memory so all fits
#define ALLOCATION_SIZE 1280
#else
#define ALLOCATION_SIZE 2560 // Malloc doesn't abort, allocate a bit more memory to test graceful allocation failures
// Malloc doesn't abort, allocate a bit more memory to test graceful allocation
// failures
#define ALLOCATION_SIZE 2560
#endif

#define RESULT_OK 0
#define RESULT_EXPECTED_FAILS 1
#define RESULT_BAD_FAIL 2

// Use barriers to make each thread synchronize their execution points, to maximize the possibility of seeing race conditions
// if those might occur.
// Use barriers to make each thread synchronize their execution points, to
// maximize the possibility of seeing race conditions if those might occur.
static pthread_barrier_t barrierWaitToAlloc;
static pthread_barrier_t barrierWaitToVerify;
static pthread_barrier_t barrierWaitToFree;

// Use a mutex for logging.
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void *thread_start(void *arg)
{
static void *thread_start(void *arg) {
#if DEBUG
pthread_mutex_lock( &mutex );
printf("thread started, will try %d allocations of size %d\n", NUM_ALLOCATIONS, ALLOCATION_SIZE);
Expand All @@ -48,47 +50,57 @@ static void *thread_start(void *arg)
int some_allocations_failed = 0;
size_t allocated = 0;

pthread_barrier_wait(&barrierWaitToAlloc); // Halt until all threads reach here, then proceed synchronously.
for(int i = 0; i < NUM_ALLOCATIONS; ++i)
{
// Halt until all threads reach here, then proceed synchronously.
pthread_barrier_wait(&barrierWaitToAlloc);
for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
allocated_buffers[i] = (uint8_t*)malloc(ALLOCATION_SIZE);
if (allocated_buffers[i]) {
memset(allocated_buffers[i], id, ALLOCATION_SIZE);
allocated += ALLOCATION_SIZE;
} else
} else {
some_allocations_failed = 1;
}
}
#if DEBUG
pthread_mutex_lock( &mutex );
printf("total allocations: %u (%d of size %d tried), some failed? %d\n", allocated, NUM_ALLOCATIONS, ALLOCATION_SIZE, some_allocations_failed);
pthread_mutex_unlock( &mutex );
#endif
pthread_barrier_wait(&barrierWaitToVerify); // Halt until all threads reach here, then proceed synchronously.
// Halt until all threads reach here, then proceed synchronously.
pthread_barrier_wait(&barrierWaitToVerify);
int reported_once = 0;
for(int i = 0; i < NUM_ALLOCATIONS; ++i)
{
for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
if (!allocated_buffers[i]) continue;
for(int j = 0; j < ALLOCATION_SIZE; ++j)
if (allocated_buffers[i][j] != id)
{
++return_code; // Failed! (but run to completion so that the barriers will all properly proceed without hanging)
for (int j = 0; j < ALLOCATION_SIZE; ++j)
if (allocated_buffers[i][j] != id) {
// Failed! (but run to completion so that the barriers will all properly
// proceed without hanging)
++return_code;
if (!reported_once) {
emscripten_errf("Memory corrupted! mem[i]: %d != %ld, i: %d, j: %d", allocated_buffers[i][j], id, i, j);
reported_once = 1; // Avoid print flood that makes debugging hard.
// Avoid print flood that makes debugging hard.
reported_once = 1;
}
}
}

pthread_barrier_wait(&barrierWaitToFree); // Halt until all threads reach here, then proceed synchronously.
for(int i = 0; i < NUM_ALLOCATIONS; ++i)
for (int i = 0; i < NUM_ALLOCATIONS; ++i) {
free(allocated_buffers[i]);
}

#if ABORTING_MALLOC
if (some_allocations_failed)
return_code = RESULT_BAD_FAIL; // We expect allocations not to fail (if they did, shouldn't reach here, but we should have aborted)
if (some_allocations_failed) {
// We expect allocations not to fail (if they did, shouldn't reach here, but
// we should have aborted)
return_code = RESULT_BAD_FAIL;
}
#else
if (some_allocations_failed)
return_code = RESULT_EXPECTED_FAILS; // We expect to be allocating so much memory that some of the allocations fail.
if (some_allocations_failed) {
// We expect to be allocating so much memory that some of the allocations
// fail.
return_code = RESULT_EXPECTED_FAILS;
}
// Otherwise, the fails might happen in another thread, that's cool.
#endif
#if DEBUG
Expand All @@ -99,8 +111,7 @@ static void *thread_start(void *arg)
pthread_exit((void*)return_code);
}

int main()
{
int main() {
printf("starting test, aborting? %d\n", ABORTING_MALLOC);

int ret = pthread_barrier_init(&barrierWaitToAlloc, NULL, NUM_THREADS);
Expand All @@ -110,9 +121,8 @@ int main()
ret = pthread_barrier_init(&barrierWaitToFree, NULL, NUM_THREADS);
assert(ret == 0);

pthread_t thr[8/*NUM_THREADS*/];
for(intptr_t i = 0; i < NUM_THREADS; ++i)
{
pthread_t thr[NUM_THREADS];
for (intptr_t i = 0; i < NUM_THREADS; ++i) {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, NUM_ALLOCATIONS*80);
Expand All @@ -122,7 +132,7 @@ int main()

int seen_expected_fails = 0;

for(int i = 0; i < NUM_THREADS; ++i) {
for (int i = 0; i < NUM_THREADS; ++i) {
int res = 0;
ret = pthread_join(thr[i], (void**)&res);
assert(ret == 0);
Expand Down
8 changes: 4 additions & 4 deletions test/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3880,17 +3880,17 @@ def prep_no_SAB(self):
@requires_threads
def test_pthread_c11_threads(self):
self.btest_exit('pthread/test_pthread_c11_threads.c',
args=['-gsource-map', '-std=gnu11', '-pthread', '-sPROXY_TO_PTHREAD', '-sTOTAL_MEMORY=64mb'])
args=['-gsource-map', '-std=gnu11', '-pthread', '-sPROXY_TO_PTHREAD'])

@requires_threads
def test_pthread_pool_size_strict(self):
# Check that it doesn't fail with sufficient number of threads in the pool.
self.btest_exit('pthread/test_pthread_c11_threads.c',
args=['-g2', '-std=gnu11', '-pthread', '-sPTHREAD_POOL_SIZE=4', '-sPTHREAD_POOL_SIZE_STRICT=2', '-sTOTAL_MEMORY=64mb'])
args=['-g2', '-std=gnu11', '-pthread', '-sPTHREAD_POOL_SIZE=4', '-sPTHREAD_POOL_SIZE_STRICT=2'])
# Check that it fails instead of deadlocking on insufficient number of threads in the pool.
self.btest('pthread/test_pthread_c11_threads.c',
expected='abort:Assertion failed: thrd_create(&t4, thread_main, NULL) == thrd_success',
args=['-g2', '-std=gnu11', '-pthread', '-sPTHREAD_POOL_SIZE=3', '-sPTHREAD_POOL_SIZE_STRICT=2', '-sTOTAL_MEMORY=64mb'])
args=['-g2', '-std=gnu11', '-pthread', '-sPTHREAD_POOL_SIZE=3', '-sPTHREAD_POOL_SIZE_STRICT=2'])

@requires_threads
def test_pthread_in_pthread_pool_size_strict(self):
Expand All @@ -3911,7 +3911,7 @@ def test_pthread_atomics(self, args):
# Test 64-bit atomics.
@requires_threads
def test_pthread_64bit_atomics(self):
self.btest_exit('pthread/test_pthread_64bit_atomics.c', args=['-sINITIAL_MEMORY=64MB', '-O3', '-pthread', '-sPTHREAD_POOL_SIZE=8'])
self.btest_exit('pthread/test_pthread_64bit_atomics.c', args=['-O3', '-pthread', '-sPTHREAD_POOL_SIZE=8'])

# Test 64-bit C++11 atomics.
@parameterized({
Expand Down

0 comments on commit c06a2b0

Please sign in to comment.