Skip to content
Snippets Groups Projects
Commit f7134822 authored by gback's avatar gback
Browse files

threadpool6 tests

parent 87a8f6aa
No related branches found
No related tags found
No related merge requests found
/*
* Fork/Join Framework
*
* Test that future_free() is implemented and working.
* For this test, we expect that any memory allocated by your
* threadpool implementation is freed when the program exits.
*
* While it is normally ok to not free memory before exiting,
* libraries that are intended for long-running programs, such
* as the threadpool library in this project, cannot leak
* memory during normal operation.
*
* Thus, this test will succeed only if valgrind reports this:
*
* ==2336955== LEAK SUMMARY:
* ==2336955== definitely lost: 0 bytes in 0 blocks
* ==2336955== indirectly lost: 0 bytes in 0 blocks
* ==2336955== possibly lost: 0 bytes in 0 blocks
* ==2336955== still reachable: 0 bytes in 0 blocks
*
* Written by G. Back for CS3214 Summer 2020.
*/
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <time.h>
#include "threadpool.h"
#include "threadpool_lib.h"
#define DEFAULT_THREADS 2
#define DEFAULT_TASKS 50
struct taskno_wrapper {
uintptr_t taskno;
};
static void *
test_task(struct thread_pool *pool, struct taskno_wrapper * data)
{
return (void *)data->taskno;
}
static int
run_test(int nthreads, int ntasks)
{
struct benchmark_data * bdata = start_benchmark();
struct thread_pool * threadpool = thread_pool_new(nthreads);
struct taskno_wrapper * task_data = malloc(sizeof(*task_data) * ntasks);
struct future ** futures = malloc(sizeof(*futures) * ntasks);
printf("starting %d tasks...\n", ntasks);
for (int i = 0; i < ntasks; i++) {
task_data[i].taskno = i;
futures[i] = thread_pool_submit(threadpool, (fork_join_task_t) test_task, task_data + i);
}
for (int i = 0; i < ntasks; i++) {
uintptr_t r = (uintptr_t) future_get(futures[i]);
// consistency check
if (r != i) {
fprintf(stderr, "Wrong result, expected %d, got %lu\n", i, r);
abort();
}
future_free(futures[i]);
}
free(task_data);
free(futures);
thread_pool_shutdown_and_destroy(threadpool);
stop_benchmark(bdata);
report_benchmark_results(bdata);
printf("Test successful.\n");
free(bdata);
return 0;
}
/**********************************************************************************/
static void
usage(char *av0, int exvalue)
{
fprintf(stderr, "Usage: %s [-n <n>] [-t <t>]\n"
" -n number of threads in pool, default %d\n"
" -t number of tasks, default %d\n"
, av0, DEFAULT_THREADS, DEFAULT_TASKS);
exit(exvalue);
}
int
main(int ac, char *av[])
{
int c, nthreads = DEFAULT_THREADS, ntasks = DEFAULT_TASKS;
while ((c = getopt(ac, av, "hn:t:")) != EOF) {
switch (c) {
case 'n':
nthreads = atoi(optarg);
break;
case 't':
ntasks = atoi(optarg);
break;
case 'h':
usage(av[0], EXIT_SUCCESS);
}
}
return run_test(nthreads, ntasks);
}
#!/usr/bin/env python3
#
# Run threadpool_test6 under valgrind, check for leaks
#
import sys, subprocess, re, os
valgrind_cmd = ["valgrind", "--leak-check=full", "--suppressions=sigaltstack.suppression", "./threadpool_test6"]
proc = subprocess.Popen(valgrind_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
print("test did not exit with zero", file=sys.stderr)
sys.exit(proc.returncode)
# expect
# ==2343328== LEAK SUMMARY:
# ==2343328== definitely lost: 0 bytes in 0 blocks
# ==2343328== indirectly lost: 0 bytes in 0 blocks
# ==2343328== possibly lost: 0 bytes in 0 blocks
# ==2343328== still reachable: 0 bytes in 0 blocks
reports = set()
for line in stderr.decode().split('\n'):
line = line.strip()
m = re.match(r'==(\d+)==\s+(\S.*): (\d+) bytes in (\d+) blocks', line)
if m:
g = m.groups()
cat, lost = g[1], g[2]
if lost != '0':
print(f'expected no leaks, but valgrind reports: {line}', file=sys.stderr)
print(f'run with {" ".join(valgrind_cmd)}', file=sys.stderr)
sys.exit(1)
else:
reports.add(cat)
# parent expects runresult.json under parent pid
try:
os.rename(f'runresult.{os.getpid()}.json', f'runresult.{os.getppid()}.json')
except FileNotFoundError as fne:
print (fne, file=sys.stderr)
if reports == {'possibly lost', 'indirectly lost', 'definitely lost', 'still reachable'}:
print ("Leak check successful.")
sys.exit(0)
else:
print (f'Leak check unsuccessful: {reports}', file=sys.stderr)
sys.exit(1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment