|
From: <sv...@va...> - 2007-11-27 01:59:39
|
Author: sewardj
Date: 2007-11-27 01:59:38 +0000 (Tue, 27 Nov 2007)
New Revision: 7238
Log:
Translate the drd regtests from C++ to C. (Bart Van Assche).
Added:
trunk/exp-drd/tests/fp_race.c
trunk/exp-drd/tests/pth_broadcast.c
trunk/exp-drd/tests/pth_cond_race.c
trunk/exp-drd/tests/pth_create_chain.c
trunk/exp-drd/tests/sigalrm.c
Removed:
trunk/exp-drd/tests/fp_race.cpp
trunk/exp-drd/tests/new_delete.cpp
trunk/exp-drd/tests/pth_broadcast.cpp
trunk/exp-drd/tests/pth_cond_race.cpp
trunk/exp-drd/tests/pth_create_chain.cpp
trunk/exp-drd/tests/sigalrm.cpp
trunk/exp-drd/tests/std-string.cpp
Modified:
trunk/exp-drd/tests/Makefile.am
trunk/exp-drd/tests/abort.cpp
trunk/exp-drd/tests/fp_race.stderr.exp
trunk/exp-drd/tests/fp_race.stderr.exp2
trunk/exp-drd/tests/pth_cond_race.stderr.exp
trunk/glibc-2.X-drd.supp
Modified: trunk/exp-drd/tests/Makefile.am
===================================================================
--- trunk/exp-drd/tests/Makefile.am 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/Makefile.am 2007-11-27 01:59:38 UTC (rev 7238)
@@ -34,39 +34,27 @@
AM_CXXFLAGS = $(AM_CFLAGS)
check_PROGRAMS = \
- abort \
fp_race \
- new_delete \
pth_broadcast \
pth_cond_race \
pth_create_chain \
pth_detached \
- sigalrm \
- std-string
+ sigalrm
-abort_SOURCES = abort.cpp
-abort_LDADD = -lpthread
-
-fp_race_SOURCES = fp_race.cpp
+fp_race_SOURCES = fp_race.c
fp_race_LDADD = -lpthread
-new_delete_SOURCES = new_delete.cpp
-new_delete_LDADD = -lpthread
-
-pth_broadcast_SOURCES = pth_broadcast.cpp
+pth_broadcast_SOURCES = pth_broadcast.c
pth_broadcast_LDADD = -lpthread
-pth_cond_race_SOURCES = pth_cond_race.cpp
+pth_cond_race_SOURCES = pth_cond_race.c
pth_cond_race_LDADD = -lpthread
-pth_create_chain_SOURCES = pth_create_chain.cpp
+pth_create_chain_SOURCES = pth_create_chain.c
pth_create_chain_LDADD = -lpthread
pth_detached_SOURCES = pth_detached.c
pth_detached_LDADD = -lpthread
-sigalrm_SOURCES = sigalrm.cpp
+sigalrm_SOURCES = sigalrm.c
sigalrm_LDADD = -lpthread -lrt
-
-std_string_SOURCES = std-string.cpp
-std_string_LDADD = -lpthread
Modified: trunk/exp-drd/tests/abort.cpp
===================================================================
--- trunk/exp-drd/tests/abort.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/abort.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,37 +0,0 @@
-// assert(false) calls __assert_fail(), which in turn calls abort() and
-// _IO_flush_all_lockp(). This last function triggers a race. Check that this
-// race is suppressed. Note: the test program below is not sufficient for
-// reproducing this race.
-
-
-#include <iostream>
-#include <fstream>
-#include <cassert>
-#include <pthread.h>
-#include <stdio.h>
-static pthread_mutex_t s_mutex;
-
-void* thread_func(void*)
-{
- pthread_mutex_lock(&s_mutex);
- pthread_mutex_unlock(&s_mutex);
- std::cout << "thread\n";
- assert(false);
- return 0;
-}
-
-int main(int argc, char** argv)
-{
- pthread_mutex_init(&s_mutex, 0);
- pthread_t tid;
- pthread_mutex_lock(&s_mutex);
- pthread_create(&tid, 0, thread_func, 0);
- FILE* fp = fopen("/tmp/valgrind-drd-tests-abort", "w");
- fprintf(fp, "x");
- pthread_mutex_unlock(&s_mutex);
- pthread_join(tid, 0);
- pthread_mutex_destroy(&s_mutex);
- fclose(fp);
-
- return 0;
-}
Added: trunk/exp-drd/tests/fp_race.c
===================================================================
--- trunk/exp-drd/tests/fp_race.c (rev 0)
+++ trunk/exp-drd/tests/fp_race.c 2007-11-27 01:59:38 UTC (rev 7238)
@@ -0,0 +1,139 @@
+/*
+ This file is part of drd, a data race detector.
+
+ Copyright (C) 2006-2007 Bart Van Assche
+ bar...@gm...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+// Test data race detection between floating point variables.
+
+#include <assert.h>
+#include <stdio.h> // printf()
+#include <pthread.h>
+#include <unistd.h> // usleep()
+#include "../drd_clientreq.h"
+
+
+// Local functions declarations.
+
+static void* thread_func(void*);
+
+// Local variables.
+
+// s_mutex protects s_d3.
+static pthread_mutex_t s_mutex;
+
+static double s_d1; // accessed before thread creation and in the created
+ // thread (not a race).
+static double s_d2; // accessed in the created thread and after the join
+ // (not a race).
+static double s_d3; // accessed simultaneously from both threads (race).
+static int s_debug = 0;
+static int s_do_printf = 0;
+static int s_use_mutex = 0;
+
+
+// Function definitions.
+
+static void set_thread_name(const char* const name)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_THREAD_NAME,
+ name, 0, 0, 0, 0);
+}
+
+int main(int argc, char** argv)
+{
+ int optchar;
+ pthread_t threadid;
+
+ set_thread_name("main");
+
+ while ((optchar = getopt(argc, argv, "dmp")) != EOF)
+ {
+ switch (optchar)
+ {
+ case 'd':
+ s_debug = 1;
+ break;
+ case 'm':
+ s_use_mutex = 1;
+ break;
+ case 'p':
+ s_do_printf = 1;
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ pthread_mutex_init(&s_mutex, 0);
+
+ // Switch to line-buffered mode, such that timing information can be
+ // obtained for each printf() call with strace.
+ setlinebuf(stdout);
+
+ if (s_debug)
+ {
+ printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
+ }
+
+ s_d1 = 1;
+ s_d3 = 3;
+
+ pthread_create(&threadid, 0, thread_func, 0);
+ // Wait until the printf() in the created thread finished.
+
+ {
+ if (s_use_mutex) pthread_mutex_lock(&s_mutex);
+ s_d3++;
+ if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
+ }
+
+ // Wait until the thread finished.
+ //printf("Before call to pthread_join()\n");
+ //fflush(stdout);
+ pthread_join(threadid, 0);
+ //printf("After call to pthread_join()\n");
+ //fflush(stdout);
+ if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
+ if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
+
+ pthread_mutex_destroy(&s_mutex);
+
+ return 0;
+}
+
+static void* thread_func(void* thread_arg)
+{
+ set_thread_name("thread_func");
+
+ if (s_do_printf)
+ {
+ printf("s_d1 = %g (should be 1)\n", s_d1);
+ }
+ s_d2 = 2;
+ {
+ if (s_use_mutex) pthread_mutex_lock(&s_mutex);
+ s_d3++;
+ if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
+ }
+ return 0;
+}
Deleted: trunk/exp-drd/tests/fp_race.cpp
===================================================================
--- trunk/exp-drd/tests/fp_race.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/fp_race.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,150 +0,0 @@
-/*
- This file is part of drd, a data race detector.
-
- Copyright (C) 2006-2007 Bart Van Assche
- bar...@gm...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-// Test data race detection between floating point variables.
-
-#include <cassert>
-#include <cstdio> // printf()
-#include <pthread.h>
-#include <unistd.h> // usleep()
-#include "../drd_clientreq.h"
-
-
-// Local functions declarations.
-
-static void* thread_func(void*);
-
-// Local variables.
-
-// s_mutex protects s_d3.
-static pthread_mutex_t s_mutex;
-
-static double s_d1; // accessed before thread creation and in the created
- // thread (not a race).
-static double s_d2; // accessed in the created thread and after the join
- // (not a race).
-static double s_d3; // accessed simultaneously from both threads (race).
-static bool s_debug = false;
-static bool s_do_printf = false;
-static bool s_use_mutex = false;
-
-
-class CScopedLock
-{
-public:
- CScopedLock()
- { if (s_use_mutex) pthread_mutex_lock(&s_mutex); }
- ~CScopedLock()
- { if (s_use_mutex) pthread_mutex_unlock(&s_mutex); }
-
-private:
- CScopedLock(CScopedLock const&);
- CScopedLock& operator=(CScopedLock const&);
-};
-
-
-// Function definitions.
-
-static void set_thread_name(const char* const name)
-{
- int res;
- VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_THREAD_NAME,
- name, 0, 0, 0, 0);
-}
-
-int main(int argc, char** argv)
-{
- set_thread_name("main");
-
- int optchar;
- while ((optchar = getopt(argc, argv, "dmp")) != EOF)
- {
- switch (optchar)
- {
- case 'd':
- s_debug = true;
- break;
- case 'm':
- s_use_mutex = true;
- break;
- case 'p':
- s_do_printf = true;
- break;
- default:
- assert(false);
- }
- }
-
- pthread_mutex_init(&s_mutex, 0);
-
- // Switch to line-buffered mode, such that timing information can be
- // obtained for each printf() call with strace.
- setlinebuf(stdout);
-
- if (s_debug)
- {
- printf("&s_d1 = %p; &s_d2 = %p; &s_d3 = %p\n", &s_d1, &s_d2, &s_d3);
- }
-
- s_d1 = 1;
- s_d3 = 3;
-
- pthread_t threadid;
- pthread_create(&threadid, 0, thread_func, 0);
- // Wait until the printf() in the created thread finished.
-
- {
- CScopedLock ScopedLock;
- s_d3++;
- }
-
- // Wait until the thread finished.
- //printf("Before call to pthread_join()\n");
- //fflush(stdout);
- pthread_join(threadid, 0);
- //printf("After call to pthread_join()\n");
- //fflush(stdout);
- if (s_do_printf) printf("s_d2 = %g (should be 2)\n", s_d2);
- if (s_do_printf) printf("s_d3 = %g (should be 5)\n", s_d3);
-
- pthread_mutex_destroy(&s_mutex);
-
- return 0;
-}
-
-static void* thread_func(void*)
-{
- set_thread_name("thread_func");
-
- if (s_do_printf)
- {
- printf("s_d1 = %g (should be 1)\n", s_d1);
- }
- s_d2 = 2;
- {
- CScopedLock ScopedLock;
- s_d3++;
- }
- return 0;
-}
Modified: trunk/exp-drd/tests/fp_race.stderr.exp
===================================================================
--- trunk/exp-drd/tests/fp_race.stderr.exp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/fp_race.stderr.exp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,6 +1,6 @@
Conflicting load by main at 0x........ size 8
- at 0x........: main (fp_race.cpp:?)
+ at 0x........: main (fp_race.c:?)
Allocation context: s_d3 (offset 0, size 8) in fp_race, NONE:BSS
Other segment start (thread_func)
(thread finished, call stack no longer available)
@@ -8,7 +8,7 @@
(thread finished, call stack no longer available)
Conflicting store by main at 0x........ size 8
- at 0x........: main (fp_race.cpp:?)
+ at 0x........: main (fp_race.c:?)
Allocation context: s_d3 (offset 0, size 8) in fp_race, NONE:BSS
Other segment start (thread_func)
(thread finished, call stack no longer available)
Modified: trunk/exp-drd/tests/fp_race.stderr.exp2
===================================================================
--- trunk/exp-drd/tests/fp_race.stderr.exp2 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/fp_race.stderr.exp2 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,6 +1,6 @@
Conflicting load by main at 0x........ size 8
- at 0x........: main (fp_race.cpp:?)
+ at 0x........: main (fp_race.c:?)
Allocation context: unknown
Other segment start (thread_func)
(thread finished, call stack no longer available)
@@ -8,7 +8,7 @@
(thread finished, call stack no longer available)
Conflicting store by main at 0x........ size 8
- at 0x........: main (fp_race.cpp:?)
+ at 0x........: main (fp_race.c:?)
Allocation context: unknown
Other segment start (thread_func)
(thread finished, call stack no longer available)
Deleted: trunk/exp-drd/tests/new_delete.cpp
===================================================================
--- trunk/exp-drd/tests/new_delete.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/new_delete.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,21 +0,0 @@
-#include <iostream>
-#include <pthread.h>
-
-void* thread_func(void*)
-{
- delete new int;
- return 0;
-}
-
-int main(int argc, char** argv)
-{
- pthread_t tid;
- std::cout << "main, before pthread_create()\n" << std::flush;
- pthread_create(&tid, 0, thread_func, 0);
- std::cout << "main, after pthread_create()\n" << std::flush;
- delete new int;
- std::cout << "main, before pthread_join()\n" << std::flush;
- pthread_join(tid, 0);
- std::cout << "main, after pthread_join()\n" << std::flush;
- return 0;
-}
Added: trunk/exp-drd/tests/pth_broadcast.c
===================================================================
--- trunk/exp-drd/tests/pth_broadcast.c (rev 0)
+++ trunk/exp-drd/tests/pth_broadcast.c 2007-11-27 01:59:38 UTC (rev 7238)
@@ -0,0 +1,175 @@
+// Broadcast a (POSIX threads) signal to all running threads, where the
+// number of threads can be specified on the command line. This test program
+// is intended not only to test the correctness of drd but also to test
+// whether performance does not degrade too much when the number of threads
+// increases.
+
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+// Counting semaphore.
+
+struct csema
+{
+ pthread_mutex_t m_mutex;
+ pthread_cond_t m_cond;
+ int m_count;
+};
+
+void csema_ctr(struct csema* p)
+{
+ memset(p, 0, sizeof(*p));
+ pthread_mutex_init(&p->m_mutex, 0);
+ pthread_cond_init(&p->m_cond, 0);
+}
+
+void csema_dtr(struct csema* p)
+{
+ pthread_cond_destroy(&p->m_cond);
+ pthread_mutex_destroy(&p->m_mutex);
+}
+
+void csema_p(struct csema* p, const int n)
+{
+ pthread_mutex_lock(&p->m_mutex);
+ while (p->m_count < n)
+ pthread_cond_wait(&p->m_cond, &p->m_mutex);
+ p->m_count -= n;
+ pthread_cond_signal(&p->m_cond);
+ pthread_mutex_unlock(&p->m_mutex);
+}
+
+void csema_v(struct csema* p)
+{
+ pthread_mutex_lock(&p->m_mutex);
+ p->m_count++;
+ pthread_cond_signal(&p->m_cond);
+ pthread_mutex_unlock(&p->m_mutex);
+}
+
+
+struct cthread
+{
+ pthread_t m_thread;
+ int m_threadnum;
+ struct csema* m_sema;
+};
+
+void cthread_ctr(struct cthread* p)
+{
+ p->m_thread = 0;
+ p->m_sema = 0;
+}
+
+void cthread_dtr(struct cthread* p)
+{ }
+
+
+// Local variables.
+
+static int s_debug = 0;
+static int s_trace = 0;
+static int s_signal_count;
+static pthread_mutex_t s_mutex;
+static pthread_cond_t s_cond;
+
+
+// Function definitions.
+
+static void thread_func(struct cthread* thread_info)
+{
+ int i;
+
+ pthread_mutex_lock(&s_mutex);
+
+ for (i = 0; i < s_signal_count; i++)
+ {
+ if (s_trace)
+ {
+ printf("thread %d [%d] (1)\n", thread_info->m_threadnum, i);
+ }
+ csema_v(thread_info->m_sema);
+
+ // Wait until the main thread signals us via pthread_cond_broadcast().
+ pthread_cond_wait(&s_cond, &s_mutex);
+ if (s_trace)
+ {
+ printf("thread %d [%d] (2)\n", thread_info->m_threadnum, i);
+ }
+ }
+
+ pthread_mutex_unlock(&s_mutex);
+}
+
+int main(int argc, char** argv)
+{
+ int optchar;
+ int thread_count;
+
+ while ((optchar = getopt(argc, argv, "d")) != EOF)
+ {
+ switch (optchar)
+ {
+ case 'd':
+ s_debug = 1;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ s_signal_count = argc > optind ? atoi(argv[optind]) : 10;
+ thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10;
+
+ if (s_debug)
+ printf("&s_cond = %p\n", &s_cond);
+
+ pthread_mutex_init(&s_mutex, 0);
+ pthread_cond_init(&s_cond, 0);
+ {
+ int i;
+ struct csema sema;
+ struct cthread* p;
+ struct cthread* thread_vec;
+
+ csema_ctr(&sema);
+ thread_vec = malloc(sizeof(struct cthread) * thread_count);
+ for (p = thread_vec; p != thread_vec + thread_count; p++)
+ {
+ cthread_ctr(p);
+ p->m_threadnum = p - thread_vec;
+ p->m_sema = &sema;
+ pthread_create(&p->m_thread, 0,
+ (void*(*)(void*))thread_func, &*p);
+ }
+ for (i = 0; i < s_signal_count; i++)
+ {
+ if (s_trace)
+ printf("main [%d] (1)\n", i);
+ csema_p(&sema, thread_count);
+ if (s_trace)
+ printf("main [%d] (2)\n", i);
+ pthread_mutex_lock(&s_mutex);
+ pthread_cond_broadcast(&s_cond);
+ pthread_mutex_unlock(&s_mutex);
+ if (s_trace)
+ printf("main [%d] (3)\n", i);
+ }
+ for (i = 0; i < thread_count; i++)
+ {
+ pthread_join(thread_vec[i].m_thread, 0);
+ cthread_dtr(&thread_vec[i]);
+ }
+ free(thread_vec);
+ csema_dtr(&sema);
+ }
+ pthread_cond_destroy(&s_cond);
+ pthread_mutex_destroy(&s_mutex);
+ return 0;
+}
Deleted: trunk/exp-drd/tests/pth_broadcast.cpp
===================================================================
--- trunk/exp-drd/tests/pth_broadcast.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/pth_broadcast.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,163 +0,0 @@
-// Broadcast a (POSIX threads) signal to all running threads, where the
-// number of threads can be specified on the command line. This test program
-// is intended not only to test the correctness of drd but also to test
-// whether performance does not degrade too much when the number of threads
-// increases.
-
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-#include <pthread.h>
-#include <unistd.h>
-
-// Class definitions.
-
-// Counting semaphore.
-
-class CSema
-{
-public:
- CSema()
- : m_mutex(), m_cond(), m_count(0)
- {
- pthread_mutex_init(&m_mutex, 0);
- pthread_cond_init(&m_cond, 0);
- }
- ~CSema()
- {
- pthread_cond_destroy(&m_cond);
- pthread_mutex_destroy(&m_mutex);
- }
- void p(const int n)
- {
- pthread_mutex_lock(&m_mutex);
- while (m_count < n)
- pthread_cond_wait(&m_cond, &m_mutex);
- m_count -= n;
- pthread_cond_signal(&m_cond);
- pthread_mutex_unlock(&m_mutex);
- }
- void v()
- {
- pthread_mutex_lock(&m_mutex);
- m_count++;
- pthread_cond_signal(&m_cond);
- pthread_mutex_unlock(&m_mutex);
- }
-
-private:
- CSema(CSema const&);
- CSema& operator=(CSema const&);
-
- pthread_mutex_t m_mutex;
- pthread_cond_t m_cond;
- int m_count;
-};
-
-struct CThread
-{
- CThread()
- : m_thread(), m_sema()
- { }
- ~CThread()
- { }
-
- pthread_t m_thread;
- int m_threadnum;
- CSema* m_sema;
-};
-
-
-// Local variables.
-
-static bool s_debug = false;
-static bool s_trace = false;
-static int s_signal_count;
-static pthread_mutex_t s_mutex;
-static pthread_cond_t s_cond;
-
-
-// Function definitions.
-
-static void thread_func(CThread* thread_info)
-{
- pthread_mutex_lock(&s_mutex);
-
- for (int i = 0; i < s_signal_count; i++)
- {
- if (s_trace)
- {
- std::cout << "thread " << thread_info->m_threadnum
- << " [" << i << "] (1)" << std::endl;
- }
- thread_info->m_sema->v();
-
- // Wait until the main thread signals us via pthread_cond_broadcast().
- pthread_cond_wait(&s_cond, &s_mutex);
- if (s_trace)
- {
- std::cout << "thread " << thread_info->m_threadnum
- << " [" << i << "] (2)" << std::endl;
- }
- }
-
- pthread_mutex_unlock(&s_mutex);
-}
-
-int main(int argc, char** argv)
-{
- int optchar;
- while ((optchar = getopt(argc, argv, "d")) != EOF)
- {
- switch (optchar)
- {
- case 'd':
- s_debug = true;
- break;
- default:
- assert(false);
- break;
- }
- }
- s_signal_count = argc > optind ? atoi(argv[optind]) : 10;
- const int thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10;
-
- if (s_debug)
- std::cout << "&s_cond = " << &s_cond << std::endl;
-
- pthread_mutex_init(&s_mutex, 0);
- pthread_cond_init(&s_cond, 0);
- {
- CSema sema;
- std::vector<CThread> thread_vec(thread_count);
- for (std::vector<CThread>::iterator p = thread_vec.begin();
- p != thread_vec.end(); p++)
- {
- p->m_threadnum = std::distance(thread_vec.begin(), p);
- p->m_sema = &sema;
- pthread_create(&p->m_thread, 0,
- (void*(*)(void*))thread_func, &*p);
- }
- for (int i = 0; i < s_signal_count; i++)
- {
- if (s_trace)
- std::cout << "main [" << i << "] (1)\n";
- sema.p(thread_count);
- if (s_trace)
- std::cout << "main [" << i << "] (2)\n";
- pthread_mutex_lock(&s_mutex);
- pthread_cond_broadcast(&s_cond);
- pthread_mutex_unlock(&s_mutex);
- if (s_trace)
- std::cout << "main [" << i << "] (3)\n";
- }
- for (int i = 0; i < thread_count; i++)
- {
- pthread_join(thread_vec[i].m_thread, 0);
- }
- }
- pthread_cond_destroy(&s_cond);
- pthread_mutex_destroy(&s_mutex);
- return 0;
-}
Added: trunk/exp-drd/tests/pth_cond_race.c
===================================================================
--- trunk/exp-drd/tests/pth_cond_race.c (rev 0)
+++ trunk/exp-drd/tests/pth_cond_race.c 2007-11-27 01:59:38 UTC (rev 7238)
@@ -0,0 +1,83 @@
+/* Unit test for drd that triggers a race on the use of a POSIX condition
+ variable. By Bart Van Assche.
+*/
+
+#include <assert.h>
+#include <stdio.h> // printf()
+#include <pthread.h>
+#include <unistd.h> // usleep()
+#include "../drd_clientreq.h"
+
+
+// Local functions declarations.
+
+static void* thread_func(void* thread_arg);
+
+
+// Local variables.
+
+static pthread_mutex_t s_mutex;
+static pthread_cond_t s_cond;
+static int s_use_mutex = 0;
+
+
+// Function definitions.
+
+static void set_thread_name(const char* const name)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_THREAD_NAME,
+ "%s", name, 0, 0, 0);
+}
+
+int main(int argc, char** argv)
+{
+ int optchar;
+ pthread_t threadid;
+
+ set_thread_name("main");
+
+ while ((optchar = getopt(argc, argv, "m")) != EOF)
+ {
+ switch (optchar)
+ {
+ case 'm':
+ s_use_mutex = 1;
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+ pthread_cond_init(&s_cond, 0);
+ pthread_mutex_init(&s_mutex, 0);
+ pthread_mutex_lock(&s_mutex);
+
+ pthread_create(&threadid, 0, thread_func, 0);
+
+ pthread_cond_wait(&s_cond, &s_mutex);
+ pthread_mutex_unlock(&s_mutex);
+
+ pthread_join(threadid, 0);
+
+ pthread_mutex_destroy(&s_mutex);
+ pthread_cond_destroy(&s_cond);
+
+ return 0;
+}
+
+static void* thread_func(void* thread_arg)
+{
+ set_thread_name("thread_func");
+
+ // Wait until the main thread has entered pthread_cond_wait().
+ pthread_mutex_lock(&s_mutex);
+ pthread_mutex_unlock(&s_mutex);
+
+ // Signal the condition variable.
+ if (s_use_mutex) pthread_mutex_lock(&s_mutex);
+ pthread_cond_signal(&s_cond);
+ if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
+
+ return 0;
+}
Deleted: trunk/exp-drd/tests/pth_cond_race.cpp
===================================================================
--- trunk/exp-drd/tests/pth_cond_race.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/pth_cond_race.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,96 +0,0 @@
-/* Unit test for drd that triggers a race on the use of a POSIX condition
- variable. By Bart Van Assche.
-*/
-
-#include <cassert>
-#include <cstdio> // printf()
-#include <pthread.h>
-#include <unistd.h> // usleep()
-#include "../drd_clientreq.h"
-
-
-// Local functions declarations.
-
-static void* thread_func(void*);
-
-
-// Local variables.
-
-static pthread_mutex_t s_mutex;
-static pthread_cond_t s_cond;
-static bool s_use_mutex = false;
-
-
-class CScopedLock
-{
-public:
- CScopedLock()
- { if (s_use_mutex) pthread_mutex_lock(&s_mutex); }
- ~CScopedLock()
- { if (s_use_mutex) pthread_mutex_unlock(&s_mutex); }
-
-private:
- CScopedLock(CScopedLock const&);
- CScopedLock& operator=(CScopedLock const&);
-};
-
-
-// Function definitions.
-
-static void set_thread_name(const char* const name)
-{
- int res;
- VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__SET_THREAD_NAME,
- "%s", name, 0, 0, 0);
-}
-
-int main(int argc, char** argv)
-{
- set_thread_name("main");
-
- int optchar;
- while ((optchar = getopt(argc, argv, "m")) != EOF)
- {
- switch (optchar)
- {
- case 'm':
- s_use_mutex = true;
- break;
- default:
- assert(false);
- }
- }
-
- pthread_cond_init(&s_cond, 0);
- pthread_mutex_init(&s_mutex, 0);
- pthread_mutex_lock(&s_mutex);
-
- pthread_t threadid;
- pthread_create(&threadid, 0, thread_func, 0);
-
- pthread_cond_wait(&s_cond, &s_mutex);
- pthread_mutex_unlock(&s_mutex);
-
- pthread_join(threadid, 0);
-
- pthread_mutex_destroy(&s_mutex);
- pthread_cond_destroy(&s_cond);
-
- return 0;
-}
-
-static void* thread_func(void*)
-{
- set_thread_name("thread_func");
-
- // Wait until the main thread has entered pthread_cond_wait().
- pthread_mutex_lock(&s_mutex);
- pthread_mutex_unlock(&s_mutex);
-
- // Signal the condition variable.
- if (s_use_mutex) pthread_mutex_lock(&s_mutex);
- pthread_cond_signal(&s_cond);
- if (s_use_mutex) pthread_mutex_unlock(&s_mutex);
-
- return 0;
-}
Modified: trunk/exp-drd/tests/pth_cond_race.stderr.exp
===================================================================
--- trunk/exp-drd/tests/pth_cond_race.stderr.exp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/pth_cond_race.stderr.exp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -2,7 +2,7 @@
Thread 2:
Race condition: condition variable 0x........ has been signalled but the associated mutex 0x........ is not locked by the signalling thread
at 0x........: pthread_cond_signal@* (drd_preloaded.c:?)
- by 0x........: thread_func(void*) (pth_cond_race.cpp:?)
+ by 0x........: thread_func (pth_cond_race.c:?)
by 0x........: vg_thread_wrapper (drd_preloaded.c:?)
by 0x........: start_thread (in libpthread-?.?.so)
by 0x........: clone (in /...libc...)
Added: trunk/exp-drd/tests/pth_create_chain.c
===================================================================
--- trunk/exp-drd/tests/pth_create_chain.c (rev 0)
+++ trunk/exp-drd/tests/pth_create_chain.c 2007-11-27 01:59:38 UTC (rev 7238)
@@ -0,0 +1,58 @@
+// Create threads in such a way that there is a realistic chance that the
+// parent thread finishes before the created thread finishes.
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+
+static pthread_t s_thread[1000];
+static int s_arg[1000];
+
+static void* thread_func(void* p)
+{
+ int thread_count = *(int*)(p);
+ if (thread_count > 0)
+ {
+ thread_count--;
+ // std::cout << "create " << thread_count << std::endl;
+ s_arg[thread_count] = thread_count;
+ pthread_create(&s_thread[thread_count], 0, thread_func,
+ &s_arg[thread_count]);
+#if 0
+ std::cout << "created " << thread_count << "(" << s_thread[thread_count]
+ << ")" << std::endl;
+#endif
+ }
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ int thread_count;
+ int i;
+
+ thread_count = argc > 1 ? atoi(argv[1]) : 50;
+ assert(thread_count <= sizeof(s_thread) / sizeof(s_thread[0]));
+ assert(thread_count >= 1);
+ thread_count--;
+ // std::cout << "create " << thread_count << std::endl;
+ pthread_create(&s_thread[thread_count], 0, thread_func,
+ &thread_count);
+#if 0
+ std::cout << "created " << thread_count << "(" << s_thread[thread_count]
+ << ")" << std::endl;
+#endif
+ for (i = thread_count; i >= 0; i--)
+ {
+ // std::cout << "join " << i << "(" << s_thread[i] << ")" << std::endl;
+ pthread_join(s_thread[i], 0);
+ }
+ return 0;
+}
+
+// Local variables:
+// compile-command: "g++ -o pthread_create-chain -g -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused pthread_create-chain.cpp -lpthread"
+// End:
Deleted: trunk/exp-drd/tests/pth_create_chain.cpp
===================================================================
--- trunk/exp-drd/tests/pth_create_chain.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/pth_create_chain.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,53 +0,0 @@
-// Create threads in such a way that there is a realistic chance that the
-// parent thread finishes before the created thread finishes.
-
-#include <cassert>
-#include <cstdlib>
-#include <iostream>
-#include <pthread.h>
-
-static pthread_t s_thread[1000];
-static int s_arg[1000];
-
-static void* thread_func(void* p)
-{
- int thread_count = *reinterpret_cast<int*>(p);
- if (thread_count > 0)
- {
- thread_count--;
- // std::cout << "create " << thread_count << std::endl;
- s_arg[thread_count] = thread_count;
- pthread_create(&s_thread[thread_count], 0, thread_func,
- &s_arg[thread_count]);
-#if 0
- std::cout << "created " << thread_count << "(" << s_thread[thread_count]
- << ")" << std::endl;
-#endif
- }
- return 0;
-}
-
-int main(int argc, char** argv)
-{
- unsigned thread_count = argc > 1 ? atoi(argv[1]) : 50;
- assert(thread_count <= sizeof(s_thread) / sizeof(s_thread[0]));
- assert(thread_count >= 1);
- thread_count--;
- // std::cout << "create " << thread_count << std::endl;
- pthread_create(&s_thread[thread_count], 0, thread_func,
- const_cast<unsigned*>(&thread_count));
-#if 0
- std::cout << "created " << thread_count << "(" << s_thread[thread_count]
- << ")" << std::endl;
-#endif
- for (int i = thread_count; i >= 0; i--)
- {
- // std::cout << "join " << i << "(" << s_thread[i] << ")" << std::endl;
- pthread_join(s_thread[i], 0);
- }
- return 0;
-}
-
-// Local variables:
-// compile-command: "g++ -o pthread_create-chain -g -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused pthread_create-chain.cpp -lpthread"
-// End:
Added: trunk/exp-drd/tests/sigalrm.c
===================================================================
--- trunk/exp-drd/tests/sigalrm.c (rev 0)
+++ trunk/exp-drd/tests/sigalrm.c 2007-11-27 01:59:38 UTC (rev 7238)
@@ -0,0 +1,95 @@
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+#include "../drd_clientreq.h"
+
+
+static int s_debug = 0;
+
+
+static int getktid()
+{
+ return syscall(__NR_gettid);
+}
+
+static int getvgtid()
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__GET_THREAD_SELF, 0, 0, 0,0,0);
+ return res;
+}
+
+static void SignalHandler(const int iSignal)
+{
+ if (s_debug)
+ {
+ char msg[256];
+ snprintf(msg, sizeof(msg), "Signal %d was delivered to kernel thread ID %d"
+ " / Valgrind thread ID %d\n",
+ iSignal, getktid(), getvgtid());
+ write(STDOUT_FILENO, msg, strlen(msg));
+ }
+}
+
+void* thread_func(void* thread_arg)
+{
+ struct timespec tsRemain, tsDelay;
+
+ if (s_debug)
+ {
+ printf("thread: kernel thread ID %d / Valgrind thread ID %d\n",
+ getktid(), getvgtid());
+ }
+
+ tsDelay.tv_sec = 10;
+ tsDelay.tv_nsec = 0;
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &tsDelay, &tsRemain);
+ //assert(result < 0 && errno == EINTR);
+
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ int vgthreadid;
+ pthread_t threadid;
+ struct timespec tsDelay;
+
+ // Primitive argument parsing.
+ if (argc > 1)
+ s_debug = 1;
+
+ vgthreadid = getvgtid();
+
+ if (s_debug)
+ {
+ printf("main: kernel thread ID %d / Valgrind thread ID %d\n",
+ getktid(), vgthreadid);
+ }
+
+ {
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = &SignalHandler;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGALRM, &sa, 0);
+ }
+
+ pthread_create(&threadid, 0, thread_func, 0);
+ // Wait until the thread is inside clock_nanosleep().
+ tsDelay.tv_sec = 0;
+ tsDelay.tv_nsec = 20 * 1000 * 1000;
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &tsDelay, 0);
+ // And send SIGALRM to the thread.
+ pthread_kill(threadid, SIGALRM);
+ pthread_join(threadid, 0);
+
+ return 0;
+}
Deleted: trunk/exp-drd/tests/sigalrm.cpp
===================================================================
--- trunk/exp-drd/tests/sigalrm.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/sigalrm.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,113 +0,0 @@
-#include <cassert>
-#include <cerrno>
-#include <cstdio>
-#include <cstdlib>
-#include <ctime>
-#include <iostream>
-#include <features.h>
-#include <pthread.h>
-#include <signal.h>
-#include <unistd.h>
-#include <string.h>
-#include "../drd_clientreq.h"
-#include <asm/unistd.h>
-
-#if !defined(__GLIBC_PREREQ)
-# error "This program requires __GLIBC_PREREQ (in /usr/include/features.h)"
-#endif
-
-#if __GLIBC_PREREQ(2,3)
-
-#define VALGRIND_START_NEW_SEGMENT \
-{ \
- int res; \
- VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__DRD_START_NEW_SEGMENT, \
- pthread_self(), 0, 0,0,0); \
-}
-
-static bool s_debug = false;
-
-
-static int getktid()
-{
- return syscall(__NR_gettid);
-}
-
-static int getvgtid()
-{
- int res;
- VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__GET_THREAD_SELF, 0, 0, 0,0,0);
- return res;
-}
-
-static void SignalHandler(const int iSignal)
-{
- if (s_debug)
- {
- char msg[256];
- snprintf(msg, sizeof(msg), "Signal %d was delivered to kernel thread ID %d"
- " / Valgrind thread ID %d\n",
- iSignal, getktid(), getvgtid());
- write(STDOUT_FILENO, msg, strlen(msg));
- }
-}
-
-void* thread_func(void*)
-{
- if (s_debug)
- {
- std::cout << "thread: kernel thread ID " << getktid()
- << " / Valgrind thread ID " << getvgtid() << "\n";
- }
-
- const timespec tsDelay = { 10, 0 };
- timespec tsRemain;
- clock_nanosleep(CLOCK_MONOTONIC, 0, &tsDelay, &tsRemain);
- //assert(result < 0 && errno == EINTR);
-
- return 0;
-}
-
-int main(int argc, char** )
-{
- // Primitive argument parsing.
- if (argc > 1)
- s_debug = true;
-
- const int vgthreadid = getvgtid();
-
- if (s_debug)
- {
- std::cout << "main: kernel thread ID " << getktid()
- << " / Valgrind thread ID " << vgthreadid << std::endl;
- }
-
- {
- struct sigaction sa;
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = &SignalHandler;
- sigemptyset(&sa.sa_mask);
- sigaction(SIGALRM, &sa, 0);
- }
-
- pthread_t threadid;
- pthread_create(&threadid, 0, thread_func, 0);
- // Wait until the thread is inside clock_nanosleep().
- const timespec tsDelay = { 0, 20 * 1000 * 1000 };
- clock_nanosleep(CLOCK_MONOTONIC, 0, &tsDelay, 0);
- // And send SIGALRM to the thread.
- pthread_kill(threadid, SIGALRM);
- pthread_join(threadid, 0);
-
- return 0;
-}
-
-#else /* !__GLIBC_PREREQ(2,3) */
-
-int main(int argc, char** )
-{
- std::cout << "program does not work on glibc < 2.3" << std::endl;
- return 0;
-}
-
-#endif /* __GLIBC_PREREQ(2,3) */
Deleted: trunk/exp-drd/tests/std-string.cpp
===================================================================
--- trunk/exp-drd/tests/std-string.cpp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/exp-drd/tests/std-string.cpp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -1,45 +0,0 @@
-// Note: the code below is not yet sufficient for reproducing the race on
-// basic_string<>::_Rep_base::_M_refcount
-
-
-#include <iostream>
-#include <pthread.h>
-#include <string>
-#include <unistd.h>
-
-
-static std::string s_string;
-
-static void* thread_func(void*)
-{
- std::cout << "thread: string = " << s_string << std::endl;
- return 0;
-}
-
-int main(int argc, char** argv)
-{
- const bool detached = argc <= 1;
-
- s_string = "(allocated by main thread)";
-
- pthread_t tid;
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr,
- detached
- ? PTHREAD_CREATE_DETACHED
- : PTHREAD_CREATE_JOINABLE);
- pthread_create(&tid, &attr, thread_func, 0);
- pthread_attr_destroy(&attr);
-
- std::cout << std::flush;
-
- if (detached)
- sleep(1);
- else
- pthread_join(tid, 0);
-
- std::cout << std::flush;
-
- return 0;
-}
Modified: trunk/glibc-2.X-drd.supp
===================================================================
--- trunk/glibc-2.X-drd.supp 2007-11-27 01:59:02 UTC (rev 7237)
+++ trunk/glibc-2.X-drd.supp 2007-11-27 01:59:38 UTC (rev 7238)
@@ -74,7 +74,7 @@
exp-drd:ConflictingAccess
fun:start_thread
fun:clone
-}
+}
{
pthread
exp-drd:ConflictingAccess
|