Skip to content

Commit 8442b30

Browse files
committed
Add multi-threaded tests
Output gets garbeled a bit, but we only care for the result which is `Tests OK/NOP/FAIL: 50/0/0`. Add `-Wno-incomplete-setjmp-declaration` since `clang-10` shipping with Ubuntu 20.04 seems broken... and `-Wno-unknown-warning-option` since `clang-8` doesn't know about this warning... Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent bfefaa4 commit 8442b30

File tree

4 files changed

+82
-27
lines changed

4 files changed

+82
-27
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ jobs:
7373
# Build with small stack-size
7474
- { BUILDOPTIONS: '--with-cc=gcc --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE', SANITIZER: '', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'gcc-multilib' }
7575
- { BUILDOPTIONS: '--with-cc=clang-10 --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang-10 llvm-10 gcc-multilib' }
76+
- { BUILDOPTIONS: '--with-cc=gcc --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE --multithread', SANITIZER: '', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'gcc-multilib' }
77+
- { BUILDOPTIONS: '--with-cc=clang-10 --with-m32 --with-m64 --cflags=-DMP_SMALL_STACK_SIZE --multithread', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang-10 llvm-10 gcc-multilib' }
7678

7779
# Test "autotuning", the automatic evaluation and setting of the Toom-Cook cut-offs.
7880
#- env: SANITIZER=1 BUILDOPTIONS='--with-cc=gcc-5 --cflags=-DMP_16BIT --limit-valgrind --make-option=tune'

demo/test.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,12 +2455,39 @@ static int test_mp_pack_unpack(void)
24552455
#define ONLY_PUBLIC_API_C
24562456
#endif
24572457

2458+
#if !defined(LTM_TEST_MULTITHREAD) || !defined(MP_SMALL_STACK_SIZE)
2459+
#define SINGLE_THREADED_C
2460+
typedef unsigned long int pthread_t;
2461+
extern int pthread_create(pthread_t *, const void *, void *(*)(void *), void *);
2462+
extern int pthread_join(pthread_t, void **);
2463+
#else
2464+
#define MULTI_THREADED_C
2465+
#include <pthread.h>
2466+
#endif
2467+
2468+
struct test_fn {
2469+
const char *name;
2470+
int (*fn)(void);
2471+
};
2472+
2473+
struct thread_info {
2474+
pthread_t thread_id;
2475+
const struct test_fn *t;
2476+
int ret;
2477+
};
2478+
2479+
static void *run(void *arg)
2480+
{
2481+
struct thread_info *tinfo = arg;
2482+
2483+
tinfo->ret = tinfo->t->fn();
2484+
2485+
return arg;
2486+
}
2487+
24582488
static int unit_tests(int argc, char **argv)
24592489
{
2460-
static const struct {
2461-
const char *name;
2462-
int (*fn)(void);
2463-
} test[] = {
2490+
static const struct test_fn test[] = {
24642491
#define T0(n) { #n, test_##n }
24652492
#define T1(n, o) { #n, MP_HAS(o) ? test_##n : NULL }
24662493
#define T2(n, o1, o2) { #n, (MP_HAS(o1) && MP_HAS(o2)) ? test_##n : NULL }
@@ -2522,31 +2549,50 @@ static int unit_tests(int argc, char **argv)
25222549
#undef T2
25232550
#undef T1
25242551
};
2552+
struct thread_info test_threads[sizeof(test)/sizeof(test[0])], *res;
25252553
unsigned long i, ok, fail, nop;
25262554
uint64_t t;
2527-
int j;
2555+
int j = -1;
25282556
ok = fail = nop = 0;
25292557

25302558
t = (uint64_t)time(NULL);
25312559
printf("SEED: 0x%" PRIx64 "\n\n", t);
25322560
s_mp_rand_jenkins_init(t);
25332561
mp_rand_source(s_mp_rand_jenkins);
25342562

2563+
if (MP_HAS(MULTI_THREADED)) {
2564+
printf("Multi-threading enabled\n\n");
2565+
DO(mp_warray_init(sizeof(test) / sizeof(test[0]), 1));
2566+
/* we ignore the fact that jenkings is not thread safe */
2567+
for (i = 0; i < (sizeof(test) / sizeof(test[0])); ++i) {
2568+
test_threads[i].t = &test[i];
2569+
EXPECT(pthread_create(&test_threads[i].thread_id, NULL, run, &test_threads[i]) == 0);
2570+
}
2571+
}
25352572

25362573
for (i = 0; i < (sizeof(test) / sizeof(test[0])); ++i) {
2537-
if (argc > 1) {
2538-
for (j = 1; j < argc; ++j) {
2539-
if (strstr(test[i].name, argv[j]) != NULL) {
2540-
break;
2574+
if (MP_HAS(SINGLE_THREADED)) {
2575+
if (argc > 1) {
2576+
for (j = 1; j < argc; ++j) {
2577+
if (strstr(test[i].name, argv[j]) != NULL) {
2578+
break;
2579+
}
25412580
}
2581+
if (j == argc) continue;
25422582
}
2543-
if (j == argc) continue;
2583+
2584+
if (test[i].fn)
2585+
j = test[i].fn();
2586+
} else if (MP_HAS(MULTI_THREADED)) {
2587+
EXPECT(pthread_join(test_threads[i].thread_id, (void **)&res) == 0);
2588+
j = res->ret;
25442589
}
25452590
printf("TEST %s\n", test[i].name);
2591+
25462592
if (test[i].fn == NULL) {
25472593
nop++;
25482594
printf("NOP %s\n\n", test[i].name);
2549-
} else if (test[i].fn() == EXIT_SUCCESS) {
2595+
} else if (j == EXIT_SUCCESS) {
25502596
ok++;
25512597
printf("\n");
25522598
} else {

makefile_include.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ endif
9797
endif # COMPILE_SIZE
9898

9999
ifneq ($(findstring clang,$(CC)),)
100-
LTM_CFLAGS += -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header
100+
LTM_CFLAGS += -Wno-unknown-warning-option -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header -Wno-incomplete-setjmp-declaration
101101
ifdef IGNORE_SPEED
102102
#for dead code eliminiation
103103
LTM_CFLAGS += -O1

testme.sh

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ All other options will be tested with all MP_xBIT configurations.
7070
runtime and may trigger the 30 minutes
7171
timeout.
7272
73+
--multithread Run tests in multi-threaded mode (via pthread).
74+
7375
Godmode:
7476
7577
--all Choose all architectures and gcc and clang
@@ -128,7 +130,7 @@ _make()
128130
echo -ne " Compile $1 $2"
129131
suffix=$(echo ${1}${2} | tr ' ' '_')
130132
_fixup_cflags "$1"
131-
CC="$1" CFLAGS="$2 $TEST_CFLAGS" make -j$MAKE_JOBS $3 $MAKE_OPTIONS 2>gcc_errors_${suffix}.log
133+
CC="$1" CFLAGS="$2 $TEST_CFLAGS" LFLAGS="$4" LDFLAGS="$5" make -j$MAKE_JOBS $3 $MAKE_OPTIONS 2>gcc_errors_${suffix}.log
132134
errcnt=$(wc -l < gcc_errors_${suffix}.log)
133135
if [[ ${errcnt} -gt 1 ]]; then
134136
echo " failed"
@@ -148,10 +150,10 @@ _runtest()
148150
# "make tune" will run "tune_it.sh" automatically, hence "autotune", but it cannot
149151
# get switched off without some effort, so we just let it run twice for testing purposes
150152
echo -e "\rRun autotune $1 $2"
151-
_make "$1" "$2" ""
153+
_make "$1" "$2" "" "$3" "$4"
152154
$_timeout $TUNE_CMD > test_${suffix}.log || _die "running autotune" $?
153155
else
154-
_make "$1" "$2" "test"
156+
_make "$1" "$2" "test" "$3" "$4"
155157
echo -e "\rRun test $1 $2"
156158
$_timeout ./test > test_${suffix}.log || _die "running tests" $?
157159
fi
@@ -171,13 +173,13 @@ echo "MAKE_OPTIONS = \"$MAKE_OPTIONS\""
171173
if [[ "$MAKE_OPTIONS" =~ "tune" ]]
172174
then
173175
echo "autotune branch"
174-
_make "$1" "$2" ""
176+
_make "$1" "$2" "" "$3" "$4"
175177
# The shell used for /bin/sh is DASH 0.5.7-4ubuntu1 on the author's machine which fails valgrind, so
176178
# we just run on instance of etc/tune with the same options as in etc/tune_it.sh
177179
echo -e "\rRun etc/tune $1 $2 once inside valgrind"
178180
$_timeout $VALGRIND_BIN $VALGRIND_OPTS $TUNE_CMD > test_${suffix}.log || _die "running etc/tune" $?
179181
else
180-
_make "$1" "$2" "test"
182+
_make "$1" "$2" "test" "$3" "$4"
181183
echo -e "\rRun test $1 $2 inside valgrind"
182184
$_timeout $VALGRIND_BIN $VALGRIND_OPTS ./test > test_${suffix}.log || _die "running tests" $?
183185
fi
@@ -301,6 +303,11 @@ do
301303
--symbols)
302304
CHECK_SYMBOLS="1"
303305
;;
306+
--multithread)
307+
CFLAGS="$CFLAGS -DLTM_TEST_MULTITHREAD"
308+
LFLAGS="$LFLAGS -pthread"
309+
LDFLAGS="$LDFLAGS -pthread"
310+
;;
304311
--all)
305312
COMPILERS="gcc clang"
306313
ARCHFLAGS="-m64 -m32 -mx32"
@@ -376,9 +383,9 @@ then
376383
_banner "$CC"
377384
if [[ "$VALGRIND_BIN" != "" ]]
378385
then
379-
_runvalgrind "$CC" ""
386+
_runvalgrind "$CC" "" "$LFLAGS" "$LDFLAGS"
380387
else
381-
_runtest "$CC" ""
388+
_runtest "$CC" "" "$LFLAGS" "$LDFLAGS"
382389
fi
383390
_exit
384391
fi
@@ -398,9 +405,9 @@ _banner
398405
if [[ "$TEST_VS_MTEST" != "" ]]
399406
then
400407
make clean > /dev/null
401-
_make "${compilers[0]}" "${archflags[0]} $CFLAGS" "mtest_opponent"
408+
_make "${compilers[0]}" "${archflags[0]} $CFLAGS" "mtest_opponent" "$LFLAGS" "$LDFLAGS"
402409
echo
403-
_make "gcc" "$MTEST_RAND" "mtest"
410+
_make "gcc" "$MTEST_RAND" "mtest" "$LFLAGS" "$LDFLAGS"
404411
echo
405412
echo "Run test vs. mtest for $TEST_VS_MTEST iterations"
406413
_timeout=""
@@ -429,15 +436,15 @@ do
429436
fi
430437
if [[ "$VALGRIND_BIN" != "" ]]
431438
then
432-
_runvalgrind "$i" "$a $CFLAGS"
439+
_runvalgrind "$i" "$a $CFLAGS" "$LFLAGS" "$LDFLAGS"
433440
[ "$WITH_LOW_MP" != "1" ] && continue
434-
_runvalgrind "$i" "$a -DMP_16BIT $CFLAGS"
435-
_runvalgrind "$i" "$a -DMP_32BIT $CFLAGS"
441+
_runvalgrind "$i" "$a -DMP_16BIT $CFLAGS" "$LFLAGS" "$LDFLAGS"
442+
_runvalgrind "$i" "$a -DMP_32BIT $CFLAGS" "$LFLAGS" "$LDFLAGS"
436443
else
437-
_runtest "$i" "$a $CFLAGS"
444+
_runtest "$i" "$a $CFLAGS" "$LFLAGS" "$LDFLAGS"
438445
[ "$WITH_LOW_MP" != "1" ] && continue
439-
_runtest "$i" "$a -DMP_16BIT $CFLAGS"
440-
_runtest "$i" "$a -DMP_32BIT $CFLAGS"
446+
_runtest "$i" "$a -DMP_16BIT $CFLAGS" "$LFLAGS" "$LDFLAGS"
447+
_runtest "$i" "$a -DMP_32BIT $CFLAGS" "$LFLAGS" "$LDFLAGS"
441448
fi
442449
done
443450
done

0 commit comments

Comments
 (0)