Refactor stress tests to make them runnable in reactor mode (#2614)

This commit is contained in:
Maks Litskevich 2023-10-04 01:10:10 +01:00 committed by GitHub
parent 64baf54d88
commit 28ebd57400
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 86 additions and 48 deletions

View File

@ -8,9 +8,11 @@ on:
types:
- opened
- synchronize
#running nightly pipeline if you're changing it
# running nightly pipeline if you're changing it
# stress tests are run only in nightly at the moment, so running them in they are changed
paths:
- ".github/workflows/nightly_run.yml"
- "core/iwasm/libraries/lib-wasi-threads/stress-test/**"
# midnight UTC
schedule:

View File

@ -60,6 +60,7 @@ for test_c in *.c; do
-Wl,--export=wasi_thread_start \
-Wl,--export=malloc \
-Wl,--export=free \
-Wl,--export=test \
$sysroot_command \
$test_c -o $test_wasm
done

View File

@ -7,8 +7,8 @@
#include <errno.h>
#include "mutex_common.h"
int
main()
void
test()
{
pthread_mutex_t mutex;
@ -25,3 +25,10 @@ main()
fprintf(stderr, "Errorcheck mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -7,8 +7,8 @@
#include <errno.h>
#include "mutex_common.h"
int
main()
void
test()
{
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
@ -18,3 +18,10 @@ main()
fprintf(stderr, "Normal mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -31,8 +31,8 @@ same_thread_multiple_rec_mutex_lock(void *mutex)
return NULL;
}
int
main()
void
test()
{
pthread_mutex_t mutex;
@ -63,3 +63,10 @@ main()
fprintf(stderr, "Recursive mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -16,13 +16,6 @@
#include <stdlib.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 100000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 12,
RETRY_SLEEP_TIME_US = 2000,
};
unsigned prime_numbers_count = 0;
bool
@ -49,10 +42,10 @@ check_if_prime(void *value)
}
unsigned int
validate()
validate(int iter_num)
{
unsigned int counter = 0;
for (unsigned int i = 2; i <= NUM_ITER; ++i) {
for (unsigned int i = 2; i <= iter_num; ++i) {
counter += is_prime(i);
}
@ -60,11 +53,12 @@ validate()
}
void
spawn_thread(pthread_t *thread, unsigned int *arg)
spawn_thread(pthread_t *thread, int retry_time_us, int retry_num,
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) {
int timeout_us = retry_time_us;
for (int tries = 0; status_code != 0 && tries < retry_num; ++tries) {
status_code = pthread_create(thread, NULL, &check_if_prime, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
@ -76,42 +70,56 @@ spawn_thread(pthread_t *thread, unsigned int *arg)
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
void
test(int iter_num, int retry_num, int max_threads_num, int retry_time_us)
{
pthread_t threads[MAX_NUM_THREADS];
unsigned int args[MAX_NUM_THREADS];
pthread_t threads[max_threads_num];
unsigned int args[max_threads_num];
double percentage = 0.1;
for (unsigned int factorised_number = 2; factorised_number < NUM_ITER;
for (unsigned int factorised_number = 2; factorised_number < iter_num;
++factorised_number) {
if (factorised_number > NUM_ITER * percentage) {
if (factorised_number > iter_num * percentage) {
fprintf(stderr, "Stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
unsigned int thread_num = factorised_number % MAX_NUM_THREADS;
unsigned int thread_num = factorised_number % max_threads_num;
if (threads[thread_num] != 0) {
assert(pthread_join(threads[thread_num], NULL) == 0);
}
args[thread_num] = factorised_number;
usleep(RETRY_SLEEP_TIME_US);
spawn_thread(&threads[thread_num], &args[thread_num]);
usleep(retry_time_us);
spawn_thread(&threads[thread_num], retry_time_us, retry_num,
&args[thread_num]);
assert(threads[thread_num] != 0);
}
for (int i = 0; i < MAX_NUM_THREADS; ++i) {
for (int i = 0; i < max_threads_num; ++i) {
assert(threads[i] == 0 || pthread_join(threads[i], NULL) == 0);
}
// Check the test results
assert(
prime_numbers_count == validate()
prime_numbers_count == validate(iter_num)
&& "Answer mismatch between tested code and reference implementation");
fprintf(stderr, "Stress test finished successfully\n");
}
enum DEFAULT_PARAMETERS {
ITER_NUM = 20000,
RETRY_NUM = 8,
MAX_THREADS_NUM = 12,
RETRY_SLEEP_TIME_US = 2000,
};
int
main(int argc, char **argv)
{
test(ITER_NUM, RETRY_NUM, MAX_THREADS_NUM, RETRY_SLEEP_TIME_US);
return 0;
}

View File

@ -9,14 +9,6 @@
#include <stdio.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 200000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 12,
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;
@ -31,11 +23,11 @@ thread_func(void *arg)
}
void
spawn_thread(pthread_t *thread)
spawn_thread(pthread_t *thread, int retry_time, int iter_num)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
int timeout_us = retry_time;
for (int tries = 0; status_code != 0 && tries < iter_num; ++tries) {
status_code = pthread_create(thread, NULL, &thread_func, NULL);
__atomic_fetch_add(&threads_creation_tried, 1, __ATOMIC_RELAXED);
@ -49,32 +41,33 @@ spawn_thread(pthread_t *thread)
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
void
test(int iter_num, int max_threads_num, int retry_num, int retry_time_us)
{
double percentage = 0.1;
int second_us = 1000 * 1000 * 1000; // 1 second in us
for (int iter = 0; iter < NUM_ITER; ++iter) {
if (iter > NUM_ITER * percentage) {
for (int iter = 0; iter < iter_num; ++iter) {
if (iter > iter_num * 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) {
== max_threads_num) {
usleep(100);
}
__atomic_fetch_add(&threads_in_use, 1, __ATOMIC_SEQ_CST);
pthread_t tmp;
spawn_thread(&tmp);
spawn_thread(&tmp, retry_time_us, iter_num);
pthread_detach(tmp);
}
while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) {
// Casting to int* to supress compiler warning
__builtin_wasm_memory_atomic_wait32((int *)(&threads_in_use), 0,
SECOND);
second_us);
}
assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0);
@ -91,5 +84,18 @@ main(int argc, char **argv)
"with retry ratio %f\n",
threads_creation_tried,
(1. * threads_creation_tried) / threads_executed);
}
enum DEFAULT_PARAMETERS {
ITER_NUM = 50000,
RETRY_NUM = 8,
MAX_NUM_THREADS = 12,
RETRY_SLEEP_TIME_US = 4000,
};
int
main(int argc, char **argv)
{
test(ITER_NUM, MAX_NUM_THREADS, RETRY_NUM, RETRY_SLEEP_TIME_US);
return 0;
}