2015-01-03 17:18:07 +03:00
|
|
|
#! /bin/bash
|
|
|
|
|
|
|
|
#
|
|
|
|
# This file has several tests to check for memory leaks.
|
|
|
|
# valgrind is used so make sure you have it installed
|
|
|
|
#
|
|
|
|
|
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
|
|
|
|
# --------------------------- Generic ----------------------------------
|
|
|
|
|
2015-01-03 17:18:07 +03:00
|
|
|
function needle { #needle #haystack
|
|
|
|
python -c "import re; print(re.search(r'$1', '$2').group(0))"
|
|
|
|
}
|
|
|
|
function extract_num { #needle with number #haystack
|
|
|
|
string=$(needle "$1" "$2")
|
|
|
|
needle "[0-9]*" "$string"
|
|
|
|
}
|
|
|
|
function err { #string #log
|
|
|
|
echo "------------------- ERROR ------------------------"
|
|
|
|
echo "$1"
|
|
|
|
echo "$2" >> memleaks.log
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ---------------------------- Tests -----------------------------------
|
|
|
|
|
|
|
|
|
2015-01-03 17:18:07 +03:00
|
|
|
function test_single_thread_alloc {
|
|
|
|
|
|
|
|
read -d '' code <<"EOF"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include "../thpool.h"
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
|
|
|
|
thpool_t* threadpool;
|
|
|
|
threadpool = thpool_init(1);
|
|
|
|
thpool_destroy(threadpool);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
echo "Testing single thread creation and destruction in pool"
|
2015-01-03 17:18:07 +03:00
|
|
|
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
|
2015-01-06 22:10:30 +03:00
|
|
|
return
|
2015-01-03 17:18:07 +03:00
|
|
|
fi
|
|
|
|
err "Allocated $allocs times but freed only $frees" "$output"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
function test_many_thread_allocs {
|
|
|
|
|
|
|
|
read -d '' code <<"EOF"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include "../thpool.h"
|
2015-01-03 17:18:07 +03:00
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
int main(){
|
|
|
|
|
|
|
|
thpool_t* threadpool;
|
|
|
|
threadpool = thpool_init(4); // VALGRIND SPENDS 1 SEC TO KILL EACH THREAD
|
|
|
|
// SO KEEP THIS LOW
|
|
|
|
thpool_destroy(threadpool);
|
2015-01-03 17:18:07 +03:00
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
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
|
|
|
|
fi
|
|
|
|
err "Allocated $allocs times but freed only $frees" "$output"
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# This is the same with test_many_thread_allocs but multiplied
|
|
|
|
function test_many_thread_allocs_multi {
|
|
|
|
|
|
|
|
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 ~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")
|
|
|
|
allocs=$(extract_num "[0-9]* allocs" "$heap_usage")
|
|
|
|
frees=$(extract_num "[0-9]* frees" "$heap_usage")
|
|
|
|
if (( "$allocs"-"$frees" > 4 )); then
|
|
|
|
#if [ "$allocs" != "$frees" ]; then
|
|
|
|
msg2="Max 4 leaks are allowed since each pthread might erronoumesly show a leak in valgrind."
|
|
|
|
err "Allocated $allocs times but freed only $frees. $msg2" "$output"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
2015-01-03 17:18:07 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Run tests
|
|
|
|
test_single_thread_alloc
|
2015-01-06 22:10:30 +03:00
|
|
|
test_many_thread_allocs
|
|
|
|
test_many_thread_allocs_multi
|
2015-01-03 17:18:07 +03:00
|
|
|
|
2015-01-06 22:10:30 +03:00
|
|
|
echo "No memory leaks"
|