From: Bart Van Assche Date: Wed, 17 Dec 2008 19:21:17 +0000 (+0000) Subject: Added another regression test. X-Git-Tag: svn/VALGRIND_3_4_0~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ca92c847da072edeeefe203dc472bc481efd52d;p=thirdparty%2Fvalgrind.git Added another regression test. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8837 --- diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index b747e22e03..64bd0867a0 100644 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -26,6 +26,8 @@ EXTRA_DIST = \ bar_trivial.vgtest \ boost_thread.stderr.exp \ boost_thread.vgtest \ + circular_buffer.stderr.exp \ + circular_buffer.vgtest \ drd_bitmap_test.stderr.exp \ drd_bitmap_test.stdout.exp \ drd_bitmap_test.vgtest \ @@ -201,6 +203,7 @@ check_PROGRAMS = \ atomic_var \ bar_bad \ bar_trivial \ + circular_buffer \ drd_bitmap_test \ fp_race \ hg01_all_ok \ @@ -277,6 +280,9 @@ bar_bad_LDADD = -lpthread bar_trivial_SOURCES = ../../helgrind/tests/bar_trivial.c bar_trivial_LDADD = -lpthread +circular_buffer_SOURCES = circular_buffer.c +circular_buffer_LDADD = -lpthread + drd_bitmap_test_SOURCES = drd_bitmap_test.c drd_bitmap_test_CFLAGS = $(AM_CFLAGS) -O2 \ -DENABLE_DRD_CONSISTENCY_CHECKS\ diff --git a/drd/tests/circular_buffer.c b/drd/tests/circular_buffer.c new file mode 100644 index 0000000000..8a6037ad3d --- /dev/null +++ b/drd/tests/circular_buffer.c @@ -0,0 +1,144 @@ +/* Test program that performs producer-consumer style communication through + * a circular buffer. This test program is a slightly modified version of the + * test program made available by Miguel Ojeda + * -- see also http://article.gmane.org/gmane.comp.debugging.valgrind/8782. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define BUFFER_MAX (2) + +typedef int data_t; + +typedef struct { + /* Counting semaphore representing the number of data items in the buffer. */ + sem_t data; + /* Counting semaphore representing the number of free elements. */ + sem_t free; + /* Position where a new elements should be written. */ + size_t in; + /* Position from where an element can be removed. */ + size_t out; + /* Mutex that protects 'in'. */ + pthread_mutex_t mutex_in; + /* Mutex that protects 'out'. */ + pthread_mutex_t mutex_out; + /* Data buffer. */ + data_t buffer[BUFFER_MAX]; +} buffer_t; + +static int quiet = 0; + +void buffer_init(buffer_t * b) +{ + sem_init(&b->data, 0, 0); + sem_init(&b->free, 0, BUFFER_MAX); + + pthread_mutex_init(&b->mutex_in, NULL); + pthread_mutex_init(&b->mutex_out, NULL); + + b->in = 0; + b->out = 0; +} + +void buffer_recv(buffer_t * b, data_t * d) +{ + sem_wait(&b->data); + pthread_mutex_lock(&b->mutex_out); + memcpy(d, b->buffer + b->out, sizeof(data_t)); + b->out = (b->out + 1) % BUFFER_MAX; + pthread_mutex_unlock(&b->mutex_out); + sem_post(&b->free); +} + +void buffer_send(buffer_t * b, data_t * d) +{ + sem_wait(&b->free); + pthread_mutex_lock(&b->mutex_in); + memcpy(b->buffer + b->in, d, sizeof(data_t)); + b->in = (b->in + 1) % BUFFER_MAX; + pthread_mutex_unlock(&b->mutex_in); + sem_post(&b->data); +} + +void buffer_destroy(buffer_t * b) +{ + sem_destroy(&b->data); + sem_destroy(&b->free); + + pthread_mutex_destroy(&b->mutex_in); + pthread_mutex_destroy(&b->mutex_out); +} + +buffer_t b; + +void producer(int* id) +{ + buffer_send(&b, id); + pthread_exit(NULL); +} + +#define MAXSLEEP (100 * 1000) + +void consumer(int* id) +{ + int d; + usleep(rand() % MAXSLEEP); + buffer_recv(&b, &d); + if (! quiet) + printf("%i: %i\n", *id, d); + pthread_exit(NULL); +} + +#define THREADS (10) + +int main(int argc, char** argv) +{ + pthread_t producers[THREADS]; + pthread_t consumers[THREADS]; + int thread_arg[THREADS]; + int i; + int optchar; + + while ((optchar = getopt(argc, argv, "q")) != EOF) + { + switch (optchar) + { + case 'q': + quiet = 1; + break; + } + } + + srand(time(NULL)); + + buffer_init(&b); + + for (i = 0; i < THREADS; ++i) + { + thread_arg[i] = i; + pthread_create(producers + i, NULL, + (void * (*)(void *)) producer, &thread_arg[i]); + } + + for (i = 0; i < THREADS; ++i) + pthread_create(consumers + i, NULL, + (void * (*)(void *)) consumer, &thread_arg[i]); + + for (i = 0; i < THREADS; ++i) + { + pthread_join(producers[i], NULL); + pthread_join(consumers[i], NULL); + } + + buffer_destroy(&b); + + return 0; +} diff --git a/drd/tests/circular_buffer.stderr.exp b/drd/tests/circular_buffer.stderr.exp new file mode 100644 index 0000000000..d18786f806 --- /dev/null +++ b/drd/tests/circular_buffer.stderr.exp @@ -0,0 +1,3 @@ + + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/drd/tests/circular_buffer.vgtest b/drd/tests/circular_buffer.vgtest new file mode 100644 index 0000000000..ef01f9a2a1 --- /dev/null +++ b/drd/tests/circular_buffer.vgtest @@ -0,0 +1,2 @@ +prog: circular_buffer +args: -q