Add another wamr test (#2411)
Follows up #2364 where we discussed that we might want to have a test which has really short thread function and creates many threads.
This commit is contained in:
@ -34,7 +34,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
# Stress tests names
|
||||
thread_start_file_exclusions=("spawn_stress_test.wasm" "linear_memory_size_update.wasm")
|
||||
thread_start_file_exclusions=("spawn_stress_test.wasm" "linear_memory_size_update.wasm" "stress_test_threads_creation.wasm")
|
||||
|
||||
for test_c in *.c; do
|
||||
test_wasm="$(basename $test_c .c).wasm"
|
||||
@ -56,6 +56,7 @@ for test_c in *.c; do
|
||||
echo "Compiling $test_c to $test_wasm"
|
||||
$CC \
|
||||
-target wasm32-wasi-threads \
|
||||
-O2 \
|
||||
-pthread -ftls-model=local-exec \
|
||||
-z stack-size=32768 \
|
||||
-Wl,--export=__heap_base \
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
{
|
||||
"lib-wasi-threads tests": {
|
||||
"spawn_stress_test": "Stress tests are incompatible with the other part and executed differently"
|
||||
"spawn_stress_test": "Stress tests are incompatible with the other part and executed differently",
|
||||
"stress_test_threads_creation": "Stress tests are incompatible with the other part and executed differently"
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,8 +18,9 @@
|
||||
|
||||
enum CONSTANTS {
|
||||
NUM_ITER = 100000,
|
||||
NUM_RETRY = 5,
|
||||
NUM_RETRY = 8,
|
||||
MAX_NUM_THREADS = 8,
|
||||
RETRY_SLEEP_TIME_US = 2000,
|
||||
};
|
||||
|
||||
unsigned prime_numbers_count = 0;
|
||||
@ -62,11 +63,13 @@ void
|
||||
spawn_thread(pthread_t *thread, unsigned int *arg)
|
||||
{
|
||||
int status_code = -1;
|
||||
int timeout_us = RETRY_SLEEP_TIME_US;
|
||||
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
|
||||
status_code = pthread_create(thread, NULL, &check_if_prime, arg);
|
||||
assert(status_code == 0 || status_code == EAGAIN);
|
||||
if (status_code == EAGAIN) {
|
||||
usleep(2000);
|
||||
usleep(timeout_us);
|
||||
timeout_us *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +98,7 @@ main(int argc, char **argv)
|
||||
|
||||
args[thread_num] = factorised_number;
|
||||
|
||||
usleep(2000);
|
||||
usleep(RETRY_SLEEP_TIME_US);
|
||||
spawn_thread(&threads[thread_num], &args[thread_num]);
|
||||
assert(threads[thread_num] != 0);
|
||||
}
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
enum CONSTANTS {
|
||||
NUM_ITER = 200000,
|
||||
NUM_RETRY = 8,
|
||||
MAX_NUM_THREADS = 8,
|
||||
RETRY_SLEEP_TIME_US = 4000,
|
||||
SECOND = 1000 * 1000 * 1000
|
||||
};
|
||||
|
||||
int threads_executed = 0;
|
||||
unsigned int threads_creation_tried = 0;
|
||||
unsigned int threads_in_use = 0;
|
||||
|
||||
void *
|
||||
thread_func(void *arg)
|
||||
{
|
||||
(void)(arg);
|
||||
__atomic_fetch_add(&threads_executed, 1, __ATOMIC_RELAXED);
|
||||
__atomic_fetch_sub(&threads_in_use, 1, __ATOMIC_SEQ_CST);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
spawn_thread(pthread_t *thread)
|
||||
{
|
||||
int status_code = -1;
|
||||
int timeout_us = RETRY_SLEEP_TIME_US;
|
||||
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
|
||||
status_code = pthread_create(thread, NULL, &thread_func, NULL);
|
||||
__atomic_fetch_add(&threads_creation_tried, 1, __ATOMIC_RELAXED);
|
||||
|
||||
assert(status_code == 0 || status_code == EAGAIN);
|
||||
if (status_code == EAGAIN) {
|
||||
usleep(timeout_us);
|
||||
timeout_us *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
assert(status_code == 0 && "Thread creation should succeed");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
double percentage = 0.1;
|
||||
|
||||
for (int iter = 0; iter < NUM_ITER; ++iter) {
|
||||
if (iter > NUM_ITER * percentage) {
|
||||
fprintf(stderr, "Spawning stress test is %d%% finished\n",
|
||||
(unsigned int)(percentage * 100));
|
||||
percentage += 0.1;
|
||||
}
|
||||
while (__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST)
|
||||
== MAX_NUM_THREADS) {
|
||||
usleep(100);
|
||||
}
|
||||
|
||||
__atomic_fetch_add(&threads_in_use, 1, __ATOMIC_SEQ_CST);
|
||||
pthread_t tmp;
|
||||
spawn_thread(&tmp);
|
||||
pthread_detach(tmp);
|
||||
}
|
||||
|
||||
while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) {
|
||||
__builtin_wasm_memory_atomic_wait32(&threads_in_use, 0, SECOND);
|
||||
}
|
||||
|
||||
assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0);
|
||||
|
||||
// Validation
|
||||
assert(threads_creation_tried >= threads_executed
|
||||
&& "Test executed more threads than were created");
|
||||
assert((1. * threads_creation_tried) / threads_executed < 2.5
|
||||
&& "Ensuring that we're retrying thread creation less than 2.5 "
|
||||
"times on average ");
|
||||
|
||||
fprintf(stderr,
|
||||
"Spawning stress test finished successfully executed %d threads "
|
||||
"with retry ratio %f\n",
|
||||
threads_creation_tried,
|
||||
(1. * threads_creation_tried) / threads_executed);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user