mirror of
https://github.com/Pithikos/C-Thread-Pool
synced 2024-11-22 05:31:18 +03:00
Refactored tests
This commit is contained in:
parent
8658cde5a7
commit
e60a838d19
33
tests/funcs
Normal file
33
tests/funcs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# This file should be included by other shell scripts that
|
||||||
|
# want to use any of the functions
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
function needle { #needle #haystack
|
||||||
|
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
msg="Python script error"
|
||||||
|
err "$msg" "$msg"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function extract_num { #needle with number #haystack
|
||||||
|
string=$(needle "$1" "$2")
|
||||||
|
needle "[0-9]*" "$string"
|
||||||
|
if (( $? != 0 )); then
|
||||||
|
msg="Python script error"
|
||||||
|
err "$msg" "$msg"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function err { #string #log
|
||||||
|
echo "------------------- ERROR ------------------------"
|
||||||
|
echo "$1"
|
||||||
|
echo "$2" >> memleaks.log
|
||||||
|
exit 1
|
||||||
|
}
|
135
tests/memleaks
135
tests/memleaks
@ -5,97 +5,23 @@
|
|||||||
# valgrind is used so make sure you have it installed
|
# valgrind is used so make sure you have it installed
|
||||||
#
|
#
|
||||||
|
|
||||||
|
. funcs
|
||||||
|
|
||||||
# --------------------------- Generic ----------------------------------
|
|
||||||
|
|
||||||
function needle { #needle #haystack
|
|
||||||
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
|
||||||
if (( $? != 0 )); then
|
|
||||||
err "Python script error"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function extract_num { #needle with number #haystack
|
|
||||||
string=$(needle "$1" "$2")
|
|
||||||
needle "[0-9]*" "$string"
|
|
||||||
if (( $? != 0 )); then
|
|
||||||
err "Python script error"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
function err { #string #log
|
|
||||||
echo "------------------- ERROR ------------------------"
|
|
||||||
echo "$1"
|
|
||||||
echo "$2" >> memleaks.log
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------- Tests -----------------------------------
|
# ---------------------------- Tests -----------------------------------
|
||||||
|
|
||||||
|
|
||||||
function test_single_thread_alloc {
|
function test_thread_free { #threads
|
||||||
|
echo "Testing creation and destruction of threads(=$1)"
|
||||||
read -d '' code <<"EOF"
|
gcc src/no_work.c ../thpool.c -pthread -o test
|
||||||
#include <stdio.h>
|
output=$(valgrind --leak-check=full --track-origins=yes ./test "$1" 2>&1 > /dev/null)
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(1);
|
|
||||||
thpool_destroy(threadpool);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Testing single thread creation and destruction in pool"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
|
||||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
heap_usage=$(echo "$output" | grep "total heap usage")
|
||||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
||||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
||||||
if [ "$allocs" == "$frees" ]; then
|
if (( "$allocs" == 0 )); then
|
||||||
return
|
err "Allocated 0 times. Something is wrong.." "$output"
|
||||||
fi
|
fi
|
||||||
err "Allocated $allocs times but freed only $frees" "$output"
|
if (( "$allocs" == "$frees" )); then
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function test_many_thread_allocs {
|
|
||||||
|
|
||||||
read -d '' code <<"EOF"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(4); // VALGRIND SPENDS 1 SEC TO KILL EACH THREAD
|
|
||||||
// SO KEEP THIS LOW
|
|
||||||
thpool_destroy(threadpool);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Testing multiple threads creation and destruction in pool (est ~4secs)"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
|
||||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
|
||||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
|
||||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
|
||||||
if [ "$allocs" == "$frees" ]; then
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
err "Allocated $allocs times but freed only $frees" "$output"
|
err "Allocated $allocs times but freed only $frees" "$output"
|
||||||
@ -103,44 +29,33 @@ EOF
|
|||||||
|
|
||||||
|
|
||||||
# This is the same with test_many_thread_allocs but multiplied
|
# This is the same with test_many_thread_allocs but multiplied
|
||||||
function test_many_thread_allocs_multi {
|
function test_thread_free_multi { #threads #times
|
||||||
|
echo "Testing multiple threads creation and destruction in pool (this can take a while)"
|
||||||
read -d '' code <<"EOF"
|
gcc src/no_work.c ../thpool.c -pthread -o test
|
||||||
#include <stdio.h>
|
for ((i = 1; i <= $1; i++)); do
|
||||||
#include <unistd.h>
|
output=$(valgrind --leak-check=full --track-origins=yes ./test "$1" 2>&1 > /dev/null)
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(4); // VALGRIND SPENDS 1 SEC TO KILL EACH THREAD
|
|
||||||
// SO KEEP THIS LOW
|
|
||||||
thpool_destroy(threadpool);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Testing multiple threads creation and destruction in pool (est ~40secs)"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
for i in {1..10}; do
|
|
||||||
output=$(valgrind --leak-check=full --track-origins=yes ./test 2>&1 /dev/null)
|
|
||||||
heap_usage=$(echo "$output" | grep "total heap usage")
|
heap_usage=$(echo "$output" | grep "total heap usage")
|
||||||
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
||||||
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
||||||
if [ "$allocs" != "$frees" ]; then
|
if (( "$allocs" == 0 )); then
|
||||||
|
err "Allocated 0 times. Something is wrong.." "$output"
|
||||||
|
fi
|
||||||
|
if (( "$allocs" != "$frees" )); then
|
||||||
err "Allocated $allocs times but freed only $frees" "$output"
|
err "Allocated $allocs times but freed only $frees" "$output"
|
||||||
fi
|
fi
|
||||||
|
echo "Allocs: $allocs Frees: $frees"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
test_single_thread_alloc
|
test_thread_free 1
|
||||||
test_many_thread_allocs
|
test_thread_free 2
|
||||||
test_many_thread_allocs_multi
|
test_thread_free 4
|
||||||
|
test_thread_free 8
|
||||||
|
test_thread_free 1
|
||||||
|
test_thread_free 100
|
||||||
|
test_thread_free_multi 4 20
|
||||||
|
|
||||||
echo "No memory leaks"
|
echo "No memory leaks"
|
||||||
|
41
tests/src/conc_increment.c
Normal file
41
tests/src/conc_increment.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../../thpool.h"
|
||||||
|
|
||||||
|
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
int sum=0;
|
||||||
|
|
||||||
|
|
||||||
|
void add_one() {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
sum ++;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]){
|
||||||
|
|
||||||
|
char* p;
|
||||||
|
if (argc != 3){
|
||||||
|
puts("This testfile needs excactly two arguments");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int jobs = strtol(argv[1], &p, 10);
|
||||||
|
int threads = strtol(argv[2], &p, 10);
|
||||||
|
|
||||||
|
thpool_t* threadpool;
|
||||||
|
threadpool = thpool_init(threads);
|
||||||
|
|
||||||
|
int n;
|
||||||
|
for (n=0; n<jobs; n++){
|
||||||
|
thpool_add_work(threadpool, (void*)add_one, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
thpool_wait(threadpool);
|
||||||
|
|
||||||
|
printf("%d\n", sum);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
22
tests/src/no_work.c
Normal file
22
tests/src/no_work.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "../../thpool.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]){
|
||||||
|
|
||||||
|
char* p;
|
||||||
|
if (argc != 2){
|
||||||
|
puts("This testfile needs excactly one arguments");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
int threads = strtol(argv[1], &p, 10);
|
||||||
|
|
||||||
|
thpool_t* thpool;
|
||||||
|
thpool = thpool_init(threads);
|
||||||
|
thpool_destroy(thpool);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
180
tests/threadpool
180
tests/threadpool
@ -1,182 +1,28 @@
|
|||||||
#! /bin/bash
|
#! /bin/bash
|
||||||
|
|
||||||
#
|
#
|
||||||
# This file has several tests to check for memory leaks.
|
# This file has several functional tests similar to what a user
|
||||||
# valgrind is used so make sure you have it installed
|
# might use in his/her code
|
||||||
#
|
#
|
||||||
|
|
||||||
|
. funcs
|
||||||
|
|
||||||
|
|
||||||
# --------------------------- Generic ----------------------------------
|
function test_mass_addition { #endsum #threads
|
||||||
|
echo "Adding up to $1 with $2 threads"
|
||||||
function needle { #needle #haystack
|
gcc src/conc_increment.c ../thpool.c -pthread -o test
|
||||||
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
output=$(./test $1 $2)
|
||||||
}
|
num=$(echo $output | awk '{print $(NF)}')
|
||||||
function extract_num { #needle with number #haystack
|
if [ "$num" == "$1" ]; then
|
||||||
string=$(needle "$1" "$2")
|
|
||||||
needle "[0-9]*" "$string"
|
|
||||||
}
|
|
||||||
function err { #string #log
|
|
||||||
echo "------------------- ERROR ------------------------"
|
|
||||||
echo "$1"
|
|
||||||
echo "$2" >> memleaks.log
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------- Tests -----------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
function test_mass_addition {
|
|
||||||
|
|
||||||
read -d '' code <<"EOF"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
int sum=0;
|
|
||||||
|
|
||||||
void add_one() {
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
sum ++;
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(10);
|
|
||||||
|
|
||||||
int n;
|
|
||||||
for (n=0; n<1000; n++){
|
|
||||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
thpool_wait(threadpool);
|
|
||||||
|
|
||||||
printf("%d", sum);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Adding up to 1000 with 10 threads"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
output=$(./test 2>&1 /dev/null)
|
|
||||||
if [ "$output" == "1000" ]; then
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
err "Expected 1000 but got $output" "$output"
|
err "Expected $1 but got $output" "$output"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function test_mass_addition2 {
|
|
||||||
|
|
||||||
read -d '' code <<"EOF"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
int sum=0;
|
|
||||||
|
|
||||||
void add_one() {
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
sum ++;
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(1000);
|
|
||||||
|
|
||||||
int n;
|
|
||||||
for (n=0; n<100; n++){
|
|
||||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
thpool_wait(threadpool);
|
|
||||||
|
|
||||||
printf("%d", sum);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Adding up to 100 with 1000 threads"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
output=$(./test 2>&1 /dev/null)
|
|
||||||
if [ "$output" == "100" ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
err "Expected 100 but got $output" "$output"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function test_mass_addition3 {
|
|
||||||
|
|
||||||
read -d '' code <<"EOF"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include "../thpool.h"
|
|
||||||
|
|
||||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
int sum=0;
|
|
||||||
|
|
||||||
void add_one() {
|
|
||||||
pthread_mutex_lock(&mutex);
|
|
||||||
sum ++;
|
|
||||||
pthread_mutex_unlock(&mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(){
|
|
||||||
|
|
||||||
thpool_t* threadpool;
|
|
||||||
threadpool = thpool_init(1000);
|
|
||||||
|
|
||||||
int n;
|
|
||||||
for (n=0; n<100000; n++){
|
|
||||||
thpool_add_work(threadpool, (void*)add_one, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
thpool_wait(threadpool);
|
|
||||||
|
|
||||||
printf("%d", sum);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Adding up to 100000 with 1000 threads"
|
|
||||||
echo "$code" > _test_.c
|
|
||||||
gcc _test_.c ../thpool.c -pthread -o test
|
|
||||||
output=$(./test 2>&1 /dev/null)
|
|
||||||
if [ "$output" == "100000" ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
err "Expected 100000 but got $output" "$output"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
test_mass_addition
|
test_mass_addition 100 4
|
||||||
test_mass_addition2
|
test_mass_addition 100 1000
|
||||||
test_mass_addition3
|
test_mass_addition 100000 1000
|
||||||
|
|
||||||
echo "No errors"
|
echo "No errors"
|
||||||
|
11
thpool.c
11
thpool.c
@ -1,14 +1,15 @@
|
|||||||
/* ********************************
|
/* ********************************
|
||||||
* Author: Johan Hanssen Seferidis
|
* Author: Johan Hanssen Seferidis
|
||||||
* Date: 12/08/2011
|
* License: MIT
|
||||||
* License: MIT
|
|
||||||
* Description: Library providing a threading pool where you can add
|
* Description: Library providing a threading pool where you can add
|
||||||
* work. For an example on usage refer to the main file
|
* work. For an example on usage refer to the main file
|
||||||
* found in the same package
|
* found in the same package
|
||||||
*
|
*
|
||||||
*//** @file thpool.h *//*
|
*//** @file thpool.h *//*
|
||||||
|
*
|
||||||
********************************/
|
********************************/
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user