Removed submodules
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Ignore all compiled files regardless of location
|
||||
main.o
|
||||
mutex.o
|
||||
pingpong.o
|
||||
tests/public.o
|
||||
tests/testsuite.o
|
||||
|
||||
# But not the private.o
|
||||
!tests/private.o
|
||||
|
||||
# Ignore executables for this project
|
||||
synch
|
||||
testsuite
|
||||
|
||||
# Ignore test outputs
|
||||
tests/ckstyle
|
||||
tests/itests.txt
|
||||
tests/outputs
|
||||
tests/style.txt
|
||||
tests/valgrind
|
||||
tests/utests.txt
|
||||
|
||||
**/.nfs*
|
||||
**/.vscode
|
||||
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# Simple Makefile
|
||||
# Mike Lam, James Madison University, August 2016
|
||||
#
|
||||
# This makefile builds a simple application that contains a main module
|
||||
# (specified by the EXE variable) and a predefined list of additional modules
|
||||
# (specified by the MODS variable). If there are any external library
|
||||
# dependencies (e.g., the math library, "-lm"), list them in the LIBS variable.
|
||||
# If there are any precompiled object files, list them in the OBJS variable.
|
||||
#
|
||||
# By default, this makefile will build the project with debugging symbols and
|
||||
# without optimization. To change this, edit or remove the "-g" and "-O0"
|
||||
# options in CFLAGS and LDFLAGS accordingly.
|
||||
#
|
||||
# By default, this makefile build the application using the GNU C compiler,
|
||||
# adhering to the C99 standard with all warnings enabled.
|
||||
|
||||
|
||||
# application-specific settings and run target
|
||||
|
||||
EXE=synch
|
||||
MODS=mutex.o pingpong.o
|
||||
OBJS=
|
||||
LIBS=-lm
|
||||
|
||||
default: $(EXE)
|
||||
|
||||
test: $(EXE)
|
||||
make -C tests test
|
||||
|
||||
# compiler/linker settings
|
||||
|
||||
CC=gcc
|
||||
#CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
|
||||
CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
|
||||
LDFLAGS=-g -O0 -pthread
|
||||
|
||||
|
||||
# build targets
|
||||
|
||||
$(EXE): main.o $(MODS) $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $(EXE) $^ $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
rm -f $(EXE) main.o $(MODS)
|
||||
make -C tests clean
|
||||
|
||||
.PHONY: default clean
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* CS 361: Template project driver
|
||||
*
|
||||
* Name: Nicholas Tamassia
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mutex.h"
|
||||
#include "pingpong.h"
|
||||
|
||||
int cmdline (int, char**, bool*, bool*, size_t *);
|
||||
|
||||
void
|
||||
usage (void)
|
||||
{
|
||||
printf ("Usage: synch option [option...]\n");
|
||||
printf (" At least one argument must be passed\n");
|
||||
printf (" Options are:\n");
|
||||
printf (" -m Execute the runner() threads to demonstrate locks\n");
|
||||
printf (" -p N Run pingong() with N iterations to demonstrate "
|
||||
"semaphore-based timing\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
bool run_mutex = false;
|
||||
bool run_pingpong = false;
|
||||
size_t count = 0;
|
||||
if (cmdline (argc, argv, &run_mutex, &run_pingpong, &count) < 0)
|
||||
{
|
||||
usage ();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Use mutexes for mutual exclusion
|
||||
if (run_mutex)
|
||||
{
|
||||
printf ("Running mutual exclusion test\n");
|
||||
int64_t shared = run ();
|
||||
printf ("Value of shared: %" PRId64 "\n", shared);
|
||||
}
|
||||
|
||||
// Use semaphores to demonstrate signaling
|
||||
if (run_pingpong)
|
||||
{
|
||||
printf ("Running %zd iteration(s) of ping-pong\n", count);
|
||||
ping (&count);
|
||||
printf ("There should be 0 iterations left: %zd\n", count);
|
||||
}
|
||||
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
****************** DO NOT MODIFY FUNCTIONS IN THIS SECTION ******************
|
||||
*****************************************************************************/
|
||||
|
||||
int
|
||||
cmdline (int argc, char **argv, bool *mutex, bool *pingpong, size_t *count)
|
||||
{
|
||||
int option;
|
||||
|
||||
while ((option = getopt (argc, argv, "mp:h")) != -1)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case 'm': *mutex = true;
|
||||
break;
|
||||
case 'p': *pingpong = true;
|
||||
*count = strtol (optarg, NULL, 10);
|
||||
break;
|
||||
case 'h': return -1;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*mutex && !*pingpong)
|
||||
{
|
||||
printf ("You must pass at least one argument\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Use the struct here for passing arguments to the runner() threads.
|
||||
// All instances of this struct should point to the same pthread_mutex_t
|
||||
// and shared variables.
|
||||
typedef struct args {
|
||||
pthread_mutex_t *lock;
|
||||
int64_t *shared;
|
||||
} arg_t;
|
||||
|
||||
/* Function to run in concurrent threads. The argument passed should be a
|
||||
pointer to a pthread_mutex_t to be used for mutual exclusion. Within the
|
||||
nested for-loop structure, use the mutex to protect the the increments
|
||||
and decrements of the shared variable. To get the timing right for the
|
||||
unit tests, experiment with placing the lock/unlock calls in different
|
||||
places (e.g., around both for-loops, inside the outer one, inside the
|
||||
inner one, etc.) */
|
||||
void *
|
||||
runner (void *arg)
|
||||
{
|
||||
// Retrieve the shared pointer and mutex from the passed struct.
|
||||
arg_t *args = (arg_t *) arg;
|
||||
pthread_mutex_t *lock = args->lock;
|
||||
int64_t *shared = args->shared;
|
||||
|
||||
for (int j = 0; j < 1000000; j++)
|
||||
{
|
||||
pthread_mutex_lock (lock);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
*shared += 1;
|
||||
*shared -= 1;
|
||||
}
|
||||
pthread_mutex_unlock (lock);
|
||||
}
|
||||
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
/* Simple fork-join routine that creates two threads running the runner()
|
||||
function above. Pass the lock and a pointer to the shared variable to
|
||||
both threads. When both threads complete, return the shared variable,
|
||||
which should have a value of 0.
|
||||
*/
|
||||
int64_t
|
||||
run (void)
|
||||
{
|
||||
int64_t shared = 0;
|
||||
|
||||
pthread_mutex_t lock;
|
||||
if (pthread_mutex_init (&lock, NULL) != 0)
|
||||
{
|
||||
fprintf (stderr, "Failed to initialize mutex\n");
|
||||
return shared;
|
||||
}
|
||||
|
||||
arg_t args;
|
||||
args.lock = &lock;
|
||||
args.shared = &shared;
|
||||
|
||||
pthread_t t1, t2;
|
||||
if (pthread_create (&t1, NULL, runner, &args) != 0)
|
||||
{
|
||||
fprintf (stderr, "Failed to create thread 1\n");
|
||||
pthread_mutex_destroy (&lock);
|
||||
return shared;
|
||||
}
|
||||
if (pthread_create (&t2, NULL, runner, &args) != 0)
|
||||
{
|
||||
fprintf (stderr, "Failed to create thread 2\n");
|
||||
pthread_cancel (t1);
|
||||
pthread_join (t1, NULL);
|
||||
pthread_mutex_destroy (&lock);
|
||||
return shared;
|
||||
}
|
||||
|
||||
pthread_join (t1, NULL);
|
||||
pthread_join (t2, NULL);
|
||||
|
||||
pthread_mutex_destroy (&lock);
|
||||
|
||||
return shared;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef __mutex_h__
|
||||
#define __mutex_h__
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void * runner (void *);
|
||||
int64_t run (void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pingpong.h"
|
||||
|
||||
typedef struct pparg {
|
||||
sem_t *sem_ping; // Tell ping to wake up
|
||||
sem_t *sem_pong; // Tell pong to wake up
|
||||
size_t *shared;
|
||||
} ppargs_t;
|
||||
|
||||
void *
|
||||
pong (void * _args)
|
||||
{
|
||||
ppargs_t *args = (ppargs_t *) _args;
|
||||
|
||||
while (1)
|
||||
{
|
||||
sem_wait (args->sem_pong);
|
||||
|
||||
printf ("PONG!\n");
|
||||
|
||||
if (*(args->shared) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
sem_post (args->sem_ping);
|
||||
}
|
||||
}
|
||||
|
||||
printf ("PONG: Game over\n");
|
||||
pthread_exit (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
ping (size_t *count)
|
||||
{
|
||||
pthread_t pong_thread;
|
||||
sem_t sem_ping;
|
||||
sem_t sem_pong;
|
||||
|
||||
if (sem_init (&sem_ping, 0, 1) != 0)
|
||||
{
|
||||
perror ("sem_init sem_ping");
|
||||
return;
|
||||
}
|
||||
if (sem_init (&sem_pong, 0, 0) != 0)
|
||||
{
|
||||
perror ("sem_init sem_pong");
|
||||
sem_destroy (&sem_ping);
|
||||
return;
|
||||
}
|
||||
|
||||
ppargs_t args;
|
||||
args.sem_ping = &sem_ping;
|
||||
args.sem_pong = &sem_pong;
|
||||
args.shared = count;
|
||||
|
||||
if (pthread_create (&pong_thread, NULL, pong, (void *)&args) != 0)
|
||||
{
|
||||
perror ("pthread_create");
|
||||
sem_destroy (&sem_ping);
|
||||
sem_destroy (&sem_pong);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
sem_wait (&sem_ping);
|
||||
|
||||
(*count)--;
|
||||
printf ("PING!\n");
|
||||
|
||||
sem_post (&sem_pong);
|
||||
|
||||
if (*count == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// After PONG prints game over and exits, do the same for PING
|
||||
pthread_join (pong_thread, NULL);
|
||||
printf ("PING: Game over\n");
|
||||
|
||||
sem_destroy (&sem_ping);
|
||||
sem_destroy (&sem_pong);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef __CS361_PINGPONG__
|
||||
#define __CS361_PINGPONG__
|
||||
|
||||
void ping (size_t *);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
#
|
||||
# Simple Test Makefile
|
||||
# Mike Lam, James Madison University, August 2016
|
||||
#
|
||||
# This version of the Makefile includes support for building a test suite. The
|
||||
# recommended framework is Check (http://check.sourceforge.net/). To build and
|
||||
# run the test suite, execute the "test" target. The test suite must be located
|
||||
# in a module called "testsuite". The MODS, LIBS, and OBJS variables work as
|
||||
# they do in the main Makefile.
|
||||
#
|
||||
# To change the default build target (which executes when you just type
|
||||
# "make"), change the right-hand side of the definition of the "default"
|
||||
# target.
|
||||
#
|
||||
# By default, this makefile will build the project with debugging symbols and
|
||||
# without optimization. To change this, edit or remove the "-g" and "-O0"
|
||||
# options in CFLAGS and LDFLAGS accordingly.
|
||||
#
|
||||
# By default, this makefile build the application using the GNU C compiler,
|
||||
# adhering to the C99 standard with all warnings enabled.
|
||||
|
||||
|
||||
# application-specific settings and run target
|
||||
|
||||
EXE=../synch
|
||||
TEST=testsuite
|
||||
MODS=public.o
|
||||
OBJS=../mutex.o ../pingpong.o
|
||||
LIBS=
|
||||
|
||||
UTESTOUT=utests.txt
|
||||
ITESTOUT=itests.txt
|
||||
|
||||
default: $(TEST)
|
||||
|
||||
$(EXE):
|
||||
make -C ../
|
||||
|
||||
test: utest itest
|
||||
@echo "========================================"
|
||||
|
||||
utest: $(EXE) $(TEST)
|
||||
@echo "=============================================="
|
||||
@echo " UNIT TESTS"
|
||||
@echo "This should take about 5 seconds"
|
||||
@echo "If it is much slower or faster, your calls to"
|
||||
@echo "pthread_mutex_lock and pthread_mutex_unlock"
|
||||
@echo "are probably in the wrong place."
|
||||
@echo ""
|
||||
@echo "You can see how it works by running:"
|
||||
@echo " ./tests/testsuite"
|
||||
@echo "----------------------------------------------"
|
||||
@./$(TEST) 2>/dev/null >$(UTESTOUT)
|
||||
@cat $(UTESTOUT) | sed -n -e '/Checks/,$$p' | sed -e 's/^private.*:[EF]://g'
|
||||
|
||||
itest: $(EXE)
|
||||
@echo "=============================================="
|
||||
@echo " INTEGRATION TESTS"
|
||||
@./integration.sh | tee $(ITESTOUT)
|
||||
|
||||
|
||||
# compiler/linker settings
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-g -O0 -Wall --std=gnu99 -pedantic
|
||||
LDFLAGS=-g -O0
|
||||
|
||||
CFLAGS=
|
||||
LIBS+=-lcheck -lm -lpthread
|
||||
|
||||
ifeq ($(shell uname -s),Linux)
|
||||
LIBS+=-lrt -lsubunit
|
||||
endif
|
||||
|
||||
|
||||
# build targets
|
||||
|
||||
$(TEST): $(TEST).o $(MODS) $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $(TEST) $^ $(LIBS)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
clean:
|
||||
rm -rf $(TEST) $(TEST).o $(MODS) $(UTESTOUT) $(ITESTOUT) outputs valgrind
|
||||
|
||||
.PHONY: default clean test unittest inttest
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
2c9be6afe105589c6486941c344fa8af47c4f96b
|
||||
@@ -0,0 +1 @@
|
||||
258a022a43b06ef7cd1187fb3445760809d5af0c
|
||||
@@ -0,0 +1 @@
|
||||
8f29a21768d1d35aead683f394e6435fcae1edaf
|
||||
@@ -0,0 +1 @@
|
||||
016cd27526965203f7be5709148c6ba67a2a8cec
|
||||
@@ -0,0 +1,2 @@
|
||||
Running mutual exclusion test
|
||||
Value of shared: 0
|
||||
@@ -0,0 +1,6 @@
|
||||
Running 1 iteration(s) of ping-pong
|
||||
PING!
|
||||
PONG!
|
||||
PONG: Game over
|
||||
PING: Game over
|
||||
There should be 0 iterations left: 0
|
||||
@@ -0,0 +1,24 @@
|
||||
Running 10 iteration(s) of ping-pong
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PONG: Game over
|
||||
PING: Game over
|
||||
There should be 0 iterations left: 0
|
||||
@@ -0,0 +1,14 @@
|
||||
Running 5 iteration(s) of ping-pong
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PONG: Game over
|
||||
PING: Game over
|
||||
There should be 0 iterations left: 0
|
||||
@@ -0,0 +1,24 @@
|
||||
Running a controlled timing exercise
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PING!
|
||||
PONG!
|
||||
PONG: Game over
|
||||
PING: Game over
|
||||
Value of result should be 0: 0
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
|
||||
EXE="../synch"
|
||||
|
||||
function run_test {
|
||||
|
||||
# parameters
|
||||
TAG=$1
|
||||
ARGS=$2
|
||||
|
||||
# file paths
|
||||
OUTPUT=outputs/$TAG.txt
|
||||
DIFF=outputs/$TAG.diff
|
||||
EXPECT=expected/$TAG.txt
|
||||
VALGRND=valgrind/$TAG.txt
|
||||
|
||||
# print tag format
|
||||
PTAG=$(printf '%-30s' "$TAG")
|
||||
|
||||
# check for expected text that needs to be fixed
|
||||
if [ ! -z "$(egrep "<<<<.*>>>>" "$EXPECT")" ] ; then
|
||||
echo "$PTAG FAIL ($EXPECT not correct)"
|
||||
return
|
||||
fi
|
||||
|
||||
# compare the file
|
||||
SHAOUT=$(shasum "$EXPECT" | awk '{print $1}')
|
||||
SHAEXP=$(cat "expected/.$TAG.sha")
|
||||
if [ "$SHAOUT" != "$SHAEXP" ] ; then
|
||||
echo "$PTAG FAIL (expected file is not correct)"
|
||||
return
|
||||
fi
|
||||
|
||||
# run test and compare output to the expected version
|
||||
$EXE $ARGS 2>/dev/null >"$OUTPUT"
|
||||
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
|
||||
if [ -s "$DIFF" ]; then
|
||||
|
||||
# try alternative solution (if it exists)
|
||||
EXPECT=expected/$TAG-2.txt
|
||||
if [ -e "$EXPECT" ]; then
|
||||
diff -u "$OUTPUT" "$EXPECT" >"$DIFF"
|
||||
if [ -s "$DIFF" ]; then
|
||||
echo "$PTAG FAIL (see $DIFF for details)"
|
||||
else
|
||||
echo "$PTAG pass"
|
||||
fi
|
||||
else
|
||||
echo "$PTAG FAIL (see $DIFF for details)"
|
||||
fi
|
||||
else
|
||||
echo "$PTAG pass"
|
||||
fi
|
||||
|
||||
# run valgrind
|
||||
valgrind $EXE $ARGS &>$VALGRND
|
||||
}
|
||||
|
||||
# initialize output folders
|
||||
mkdir -p outputs
|
||||
mkdir -p valgrind
|
||||
rm -f outputs/* valgrind/*
|
||||
|
||||
# run individual tests
|
||||
source itests.include
|
||||
|
||||
# check for memory leaks
|
||||
LEAK=`cat valgrind/*.txt | grep 'definitely lost' | grep -v ' 0 bytes in 0 blocks'`
|
||||
if [ -z "$LEAK" ]; then
|
||||
echo "No memory leak found."
|
||||
else
|
||||
echo "Memory leak(s) found. See files listed below for details."
|
||||
grep 'definitely lost' valgrind/*.txt | grep -v ' 0 bytes in 0 blocks' | sed -e 's/:.*$//g' | sed -e 's/^/ - /g'
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# list of integration tests
|
||||
# format: run_test <TAG> <ARGS>
|
||||
# <TAG> used as the root for all filenames (i.e., "expected/$TAG.txt")
|
||||
# <ARGS> command-line arguments to test
|
||||
|
||||
run_test INTEG_run_mutex "-m"
|
||||
run_test INTEG_run_pingpong "-p 1"
|
||||
run_test INTEG_run_pingpong_5 "-p 5"
|
||||
run_test INTEG_run_pingpong_10 "-p 10"
|
||||
@@ -0,0 +1,98 @@
|
||||
#include <assert.h>
|
||||
#include <check.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../mutex.h"
|
||||
|
||||
double time_diff (struct timeval start, struct timeval end)
|
||||
{
|
||||
double ending = end.tv_sec + (end.tv_usec * 0.000001);
|
||||
double starting = start.tv_sec + (start.tv_usec * 0.000001);
|
||||
return ending - starting;
|
||||
}
|
||||
|
||||
START_TEST (MIN_mutex_run_two_threads)
|
||||
{
|
||||
printf ("======================================\n");
|
||||
printf ("PUBLIC\n");
|
||||
printf (" MIN mutex run two threads\n");
|
||||
printf (" Call runner in two threads and ensure result is 0\n");
|
||||
|
||||
pthread_mutex_t lock;
|
||||
pthread_mutex_init (&lock, NULL);
|
||||
int64_t shared = run ();
|
||||
pthread_mutex_destroy (&lock);
|
||||
ck_assert_int_eq (shared, 0);
|
||||
printf ("\n");
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST (MIN_mutex_run_two_threads_time)
|
||||
{
|
||||
printf ("======================================\n");
|
||||
printf ("PUBLIC\n");
|
||||
printf (" MIN mutex runner two threads time\n");
|
||||
printf (" Call runner in two threads and measure time\n");
|
||||
printf (" Multithreaded should take more than 3 times and\n");
|
||||
printf (" less than 6 times the unithreaded time.\n");
|
||||
|
||||
int64_t num = 0;
|
||||
int64_t *shared = #
|
||||
|
||||
struct timeval start, end;
|
||||
gettimeofday (&start, NULL);
|
||||
for (int j = 0; j < 1000000; j++)
|
||||
{
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
*shared += 1;
|
||||
*shared -= 1;
|
||||
}
|
||||
}
|
||||
gettimeofday (&end, NULL);
|
||||
double unidiff = time_diff (start, end);
|
||||
|
||||
pthread_mutex_t lock;
|
||||
pthread_mutex_init (&lock, NULL);
|
||||
gettimeofday (&start, NULL);
|
||||
num = run ();
|
||||
gettimeofday (&end, NULL);
|
||||
double multidiff = time_diff (start, end);
|
||||
|
||||
printf ("\n Unithreaded time: %f\n Multithreaded time: %f\n\n",
|
||||
unidiff, multidiff);
|
||||
|
||||
ck_assert_int_eq (num, 0);
|
||||
ck_assert (unidiff * 6 > multidiff);
|
||||
ck_assert (unidiff * 2.3 < multidiff);
|
||||
printf ("\n");
|
||||
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/*
|
||||
1 - Create a queue of size 1 and put things in one at a time, pausing
|
||||
for 50 ms in between.
|
||||
2 - Create a queue of size 8, fill it, then start the worker.
|
||||
3 - Create a queue of size 15, start the listener, then pull one item
|
||||
at a time.
|
||||
4 - Just use fifo_queue for size 10, 20, and 30.
|
||||
*/
|
||||
|
||||
void public_tests (Suite *s)
|
||||
{
|
||||
TCase *tc_public = tcase_create ("Public");
|
||||
tcase_set_timeout (tc_public, 30.0);
|
||||
tcase_add_test (tc_public, MIN_mutex_run_two_threads);
|
||||
tcase_add_test (tc_public, MIN_mutex_run_two_threads_time);
|
||||
suite_add_tcase (s, tc_public);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <check.h>
|
||||
|
||||
extern void public_tests (Suite *s);
|
||||
|
||||
Suite * test_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("Default");
|
||||
public_tests (s);
|
||||
return s;
|
||||
}
|
||||
|
||||
void run_testsuite ()
|
||||
{
|
||||
Suite *s = test_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
srunner_free (sr);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
srand((unsigned)time(NULL));
|
||||
run_testsuite ();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user