|
From: <sv...@va...> - 2007-09-10 14:06:44
|
Author: sewardj
Date: 2007-09-10 15:06:40 +0100 (Mon, 10 Sep 2007)
New Revision: 6812
Log:
Some simple regression tests for Thrcheck, including 6 from helgrind/tests.
Added:
branches/THRCHECK/thrcheck/tests/hg01_all_ok.c
branches/THRCHECK/thrcheck/tests/hg01_all_ok.stderr.exp
branches/THRCHECK/thrcheck/tests/hg01_all_ok.stdout.exp
branches/THRCHECK/thrcheck/tests/hg01_all_ok.vgtest
branches/THRCHECK/thrcheck/tests/hg02_deadlock.c
branches/THRCHECK/thrcheck/tests/hg02_deadlock.stderr.exp
branches/THRCHECK/thrcheck/tests/hg02_deadlock.stdout.exp
branches/THRCHECK/thrcheck/tests/hg02_deadlock.vgtest
branches/THRCHECK/thrcheck/tests/hg03_inherit.c
branches/THRCHECK/thrcheck/tests/hg03_inherit.stderr.exp
branches/THRCHECK/thrcheck/tests/hg03_inherit.stdout.exp
branches/THRCHECK/thrcheck/tests/hg03_inherit.vgtest
branches/THRCHECK/thrcheck/tests/hg04_race.c
branches/THRCHECK/thrcheck/tests/hg04_race.stderr.exp
branches/THRCHECK/thrcheck/tests/hg04_race.stdout.exp
branches/THRCHECK/thrcheck/tests/hg04_race.vgtest
branches/THRCHECK/thrcheck/tests/hg05_race2.c
branches/THRCHECK/thrcheck/tests/hg05_race2.stderr.exp
branches/THRCHECK/thrcheck/tests/hg05_race2.stdout.exp
branches/THRCHECK/thrcheck/tests/hg05_race2.vgtest
branches/THRCHECK/thrcheck/tests/hg06_readshared.c
branches/THRCHECK/thrcheck/tests/hg06_readshared.stderr.exp
branches/THRCHECK/thrcheck/tests/hg06_readshared.stdout.exp
branches/THRCHECK/thrcheck/tests/hg06_readshared.vgtest
branches/THRCHECK/thrcheck/tests/tc01_simple_race.c
branches/THRCHECK/thrcheck/tests/tc01_simple_race.stderr.exp
branches/THRCHECK/thrcheck/tests/tc01_simple_race.stdout.exp
branches/THRCHECK/thrcheck/tests/tc01_simple_race.vgtest
branches/THRCHECK/thrcheck/tests/tc02_simple_tls.c
branches/THRCHECK/thrcheck/tests/tc02_simple_tls.stderr.exp
branches/THRCHECK/thrcheck/tests/tc02_simple_tls.stdout.exp
branches/THRCHECK/thrcheck/tests/tc02_simple_tls.vgtest
branches/THRCHECK/thrcheck/tests/tc03_re_excl.c
branches/THRCHECK/thrcheck/tests/tc03_re_excl.stderr.exp
branches/THRCHECK/thrcheck/tests/tc03_re_excl.stdout.exp
branches/THRCHECK/thrcheck/tests/tc03_re_excl.vgtest
branches/THRCHECK/thrcheck/tests/tc04_free_lock.c
branches/THRCHECK/thrcheck/tests/tc04_free_lock.stderr.exp
branches/THRCHECK/thrcheck/tests/tc04_free_lock.stdout.exp
branches/THRCHECK/thrcheck/tests/tc04_free_lock.vgtest
branches/THRCHECK/thrcheck/tests/tc05_simple_race.c
branches/THRCHECK/thrcheck/tests/tc05_simple_race.stderr.exp
branches/THRCHECK/thrcheck/tests/tc05_simple_race.stdout.exp
branches/THRCHECK/thrcheck/tests/tc05_simple_race.vgtest
branches/THRCHECK/thrcheck/tests/tc06_two_races.c
branches/THRCHECK/thrcheck/tests/tc06_two_races.stderr.exp
branches/THRCHECK/thrcheck/tests/tc06_two_races.stdout.exp
branches/THRCHECK/thrcheck/tests/tc06_two_races.vgtest
branches/THRCHECK/thrcheck/tests/tc07_hbl1.c
branches/THRCHECK/thrcheck/tests/tc07_hbl1.stderr.exp
branches/THRCHECK/thrcheck/tests/tc07_hbl1.stdout.exp
branches/THRCHECK/thrcheck/tests/tc07_hbl1.vgtest
branches/THRCHECK/thrcheck/tests/tc08_hbl2.c
branches/THRCHECK/thrcheck/tests/tc08_hbl2.stderr.exp
branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp
branches/THRCHECK/thrcheck/tests/tc08_hbl2.vgtest
branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c
branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.stderr.exp
branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.stdout.exp
branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.vgtest
branches/THRCHECK/thrcheck/tests/tc10_rec_lock.c
branches/THRCHECK/thrcheck/tests/tc10_rec_lock.stderr.exp
branches/THRCHECK/thrcheck/tests/tc10_rec_lock.stdout.exp
branches/THRCHECK/thrcheck/tests/tc10_rec_lock.vgtest
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-09-10 14:04:57 UTC (rev 6811)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-09-10 14:06:40 UTC (rev 6812)
@@ -7,28 +7,50 @@
noinst_SCRIPTS = filter_stderr
EXTRA_DIST = $(noinst_SCRIPTS) \
- allok.stderr.exp allok.vgtest \
- deadlock.stderr.exp deadlock.vgtest \
- inherit.stderr.exp inherit.vgtest \
- race.stderr.exp race.vgtest \
- race2.stderr.exp race2.vgtest \
- readshared.stderr.exp readshared.vgtest \
- toobig-allocs.stderr.exp toobig-allocs.vgtest
+ hg01_all_ok.vgtest hg01_all_ok.stderr.exp hg01_all_ok.stdout.exp \
+ hg02_deadlock.vgtest hg02_deadlock.stderr.exp hg02_deadlock.stdout.exp \
+ hg03_inherit.vgtest hg03_inherit.stderr.exp hg03_inherit.stdout.exp \
+ hg04_race.vgtest hg04_race.stderr.exp hg04_race.stdout.exp \
+ hg05_race2.vgtest hg05_race2.stderr.exp hg05_race2.stdout.exp \
+ hg06_readshared.vgtest hg06_readshared.stderr.exp \
+ hg06_readshared.stdout.exp \
+ tc01_simple_race.vgtest tc01_simple_race.stderr.exp \
+ tc01_simple_race.stdout.exp \
+ tc02_simple_tls.vgtest tc02_simple_tls.stderr.exp \
+ tc02_simple_tls.stdout.exp \
+ tc03_re_excl.vgtest tc03_re_excl.stderr.exp tc03_re_excl.stdout.exp \
+ tc04_free_lock.vgtest tc04_free_lock.stderr.exp \
+ tc04_free_lock.stdout.exp \
+ tc05_simple_race.vgtest tc05_simple_race.stderr.exp \
+ tc05_simple_race.stdout.exp \
+ tc06_two_races.vgtest tc06_two_races.stderr.exp \
+ tc06_two_races.stdout.exp \
+ tc07_hbl1.vgtest tc07_hbl1.stderr.exp tc07_hbl1.stdout.exp \
+ tc08_hbl2.vgtest tc08_hbl2.stderr.exp tc08_hbl2.stdout.exp \
+ tc09_bad_unlock.vgtest tc09_bad_unlock.stderr.exp \
+ tc09_bad_unlock.stdout.exp \
+ tc10_rec_lock.vgtest tc10_rec_lock.stderr.exp \
+ tc10_rec_lock.stdout.exp
check_PROGRAMS = \
- allok deadlock inherit race race2 readshared
+ hg01_all_ok \
+ hg02_deadlock \
+ hg03_inherit \
+ hg04_race \
+ hg05_race2 \
+ hg06_readshared \
+ tc01_simple_race \
+ tc02_simple_tls \
+ tc03_re_excl \
+ tc04_free_lock \
+ tc05_simple_race \
+ tc06_two_races \
+ tc07_hbl1 \
+ tc08_hbl2 \
+ tc09_bad_unlock \
+ tc10_rec_lock
-# force -gstabs, because we don't print symaddr for DWARF yet
-# Sigh, gcc-3.4.3 on ppc64 generates bogus .stabs. So disable it
-# for now on ppc64-linux.
-if VGP_PPC64_LINUX
+# is this necessary?
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI)
-else
-# In fact -gstabs is broken on many systems now
-#AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -gstabs $(AM_FLAG_M3264_PRI)
-AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI)
-
-endif
-
LDADD = -lpthread
Added: branches/THRCHECK/thrcheck/tests/hg01_all_ok.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg01_all_ok.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg01_all_ok.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,32 @@
+/* All OK */
+
+#include <pthread.h>
+
+static pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
+
+static int shared;
+
+static void *th(void *v)
+{
+ pthread_mutex_lock(&mx);
+ shared++;
+ pthread_mutex_unlock(&mx);
+
+ return 0;
+}
+
+int main()
+{
+ pthread_t a, b;
+
+ pthread_mutex_lock(&mx);
+ pthread_mutex_unlock(&mx);
+
+ pthread_create(&a, NULL, th, NULL);
+ pthread_create(&b, NULL, th, NULL);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/hg01_all_ok.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg01_all_ok.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg01_all_ok.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg01_all_ok.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg01_all_ok.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg01_all_ok
Added: branches/THRCHECK/thrcheck/tests/hg02_deadlock.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg02_deadlock.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg02_deadlock.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,43 @@
+/* Simple possible deadlock */
+#include <pthread.h>
+
+static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
+
+static void *t1(void *v)
+{
+ pthread_mutex_lock(&m1);
+ pthread_mutex_lock(&m2);
+ pthread_mutex_unlock(&m1);
+ pthread_mutex_unlock(&m2);
+
+ return 0;
+}
+
+static void *t2(void *v)
+{
+ pthread_mutex_lock(&m2);
+ pthread_mutex_lock(&m1);
+ pthread_mutex_unlock(&m1);
+ pthread_mutex_unlock(&m2);
+
+ return 0;
+}
+
+int main()
+{
+ pthread_t a, b;
+
+ /* prevent spurious messages from the dynamic linker */
+ pthread_mutex_lock(&m1);
+ pthread_mutex_unlock(&m1);
+
+ pthread_create(&a, NULL, t1, NULL);
+ pthread_create(&b, NULL, t2, NULL);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ return 0;
+}
+
Added: branches/THRCHECK/thrcheck/tests/hg02_deadlock.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg02_deadlock.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg02_deadlock.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg02_deadlock.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg02_deadlock.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg02_deadlock
Added: branches/THRCHECK/thrcheck/tests/hg03_inherit.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg03_inherit.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg03_inherit.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,55 @@
+/* test child thread inheriting data */
+
+// ***
+//
+// Helgrind should detect an error on line 48 for this test, but it doesn't!
+//
+// ***
+
+#include <pthread.h>
+#include <unistd.h>
+
+static volatile int shared[2];
+
+static void *t1(void *v)
+{
+ volatile int *ip = (int *)v;
+ *ip += 44;
+ *ip *= 2;
+ sleep(1);
+ return 0;
+}
+
+static void *t2(void *v)
+{
+ volatile int *ip = (int *)v;
+ *ip += 88;
+ *ip *= 3;
+ sleep(2);
+ return 0;
+}
+
+int main()
+{
+ pthread_t a, b;
+ volatile int ret = 0;
+
+ sleep(0);
+
+ shared[0] = 22;
+ shared[1] = 77;
+
+ pthread_create(&a, NULL, t1, (void *)&shared[0]);
+ pthread_create(&b, NULL, t2, (void *)&shared[1]);
+
+ pthread_join(a, NULL);
+
+ ret += shared[0]; /* no error - a is finished */
+ ret += shared[1]; /* expect error - b has not finished,
+ so we can't touch shared[1] yet */
+
+ pthread_join(b, NULL);
+
+
+ return ret;
+}
Added: branches/THRCHECK/thrcheck/tests/hg03_inherit.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg03_inherit.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg03_inherit.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg03_inherit.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg03_inherit.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg03_inherit
Added: branches/THRCHECK/thrcheck/tests/hg04_race.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg04_race.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg04_race.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,27 @@
+/* A simple race */
+
+#include <pthread.h>
+#include <unistd.h>
+
+static int shared;
+
+static void *th(void *v)
+{
+ shared++;
+
+ return 0;
+}
+
+int main()
+{
+ pthread_t a, b;
+
+ pthread_create(&a, NULL, th, NULL);
+ sleep(1); /* force ordering */
+ pthread_create(&b, NULL, th, NULL);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/hg04_race.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg04_race.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg04_race.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg04_race.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg04_race.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg04_race
Added: branches/THRCHECK/thrcheck/tests/hg05_race2.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg05_race2.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg05_race2.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,35 @@
+/* A simple race - test symaddr */
+
+#include <pthread.h>
+#include <unistd.h>
+
+struct foo {
+ struct bar {
+ int plop[22];
+ char biff;
+ } poot[11];
+};
+
+static void *th(void *v)
+{
+ struct foo *f = (struct foo *)v;
+
+ f->poot[5].plop[11]++;
+
+ return 0;
+}
+
+int main()
+{
+ struct foo foo;
+ pthread_t a, b;
+
+ pthread_create(&a, NULL, th, &foo);
+ sleep(1); /* force ordering */
+ pthread_create(&b, NULL, th, &foo);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/hg05_race2.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg05_race2.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg05_race2.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg05_race2.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg05_race2.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg05_race2
Added: branches/THRCHECK/thrcheck/tests/hg06_readshared.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg06_readshared.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg06_readshared.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,33 @@
+/* All OK - test allowed read sharing */
+
+#include <pthread.h>
+#include <assert.h>
+
+static int shared;
+
+static void *t1(void *v)
+{
+ return (void *)(long)(shared + 44);
+}
+
+static void *t2(void *v)
+{
+ return (void *)(long)(shared + 55);
+}
+
+int main()
+{
+ pthread_t a, b;
+
+ shared = 22;
+
+ pthread_create(&a, NULL, t1, NULL);
+ pthread_create(&b, NULL, t2, NULL);
+
+ pthread_join(a, NULL);
+ pthread_join(b, NULL);
+
+ assert(shared == 22);
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/hg06_readshared.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg06_readshared.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/hg06_readshared.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/hg06_readshared.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/hg06_readshared.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: hg06_readshared
Added: branches/THRCHECK/thrcheck/tests/tc01_simple_race.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc01_simple_race.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc01_simple_race.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,36 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, has a race. Parent and child both modify x
+ with no locking. */
+
+int x = 0;
+
+void* child_fn ( void* arg )
+{
+ /* Unprotected relative to parent */
+ x++;
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ /* Unprotected relative to child */
+ x++;
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc01_simple_race.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc01_simple_race.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc01_simple_race.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc01_simple_race.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc01_simple_race.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc01_simple_race
Added: branches/THRCHECK/thrcheck/tests/tc02_simple_tls.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc02_simple_tls.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc02_simple_tls.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,39 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, no race: parent only modified x after child
+ has modified it and then joined with the parent. Tests simple
+ thread lifetime segment handling. */
+
+int x = 0;
+
+void* child_fn ( void* arg )
+{
+ /* Unprotected relative to parent, but in child's segment only */
+ x++;
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+
+ x++; /* happens in parent's segment */
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ /* Now back in parent's segment */
+ x++;
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc02_simple_tls.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc02_simple_tls.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc02_simple_tls.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc02_simple_tls.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc02_simple_tls.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc02_simple_tls
Added: branches/THRCHECK/thrcheck/tests/tc03_re_excl.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc03_re_excl.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc03_re_excl.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,45 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, no race: parent only modified x after child
+ has modified it and then joined with the parent. Tests simple
+ thread lifetime segment handling. */
+
+/* A simple function to "use" a value, so that gcc can't
+ possibly optimise it into nothing. */
+static void use ( int x ) {
+ __asm__ __volatile__( "nop" : : "r"(x) : "cc","memory" );
+}
+
+static void* worker_thread ( void* argV )
+{
+ int* arg = (int*)argV;
+ use(arg[5]); /* read access */
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t thread_id;
+ int* x = malloc(10 * sizeof(int));
+ x[5] = 0;
+ /* x[5] is Excl(parent) */
+
+ pthread_create(&thread_id, 0, worker_thread, x);
+
+ use(x[5]); /* read access */
+
+ /* Just before the threads join, x[5] is ShR (read by both parent
+ and child) */
+ pthread_join(thread_id, 0);
+ /* x[5] is Excl(parent), because only parent and child accessed it
+ and child has merged to parent. So now it's ok for parent to
+ access it without locking. */
+
+ x[5] = 99; /* write access */
+
+ free(x);
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc03_re_excl.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc03_re_excl.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc03_re_excl.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc03_re_excl.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc03_re_excl.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc03_re_excl
Added: branches/THRCHECK/thrcheck/tests/tc04_free_lock.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc04_free_lock.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc04_free_lock.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,50 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+/* Delete memory that has a held lock and see what happens. */
+
+typedef struct { int stuff[2000];
+ pthread_mutex_t lock; int morestuff[2000]; } XX;
+
+void bar ( void );
+void foo ( void );
+
+int main ( void )
+{
+ XX* xx = malloc(sizeof(XX));
+ assert(xx);
+
+ pthread_mutex_init( &xx->lock, NULL );
+
+ pthread_mutex_lock( &xx->lock );
+
+ free(xx);
+
+ bar();
+ foo();
+ bar();
+
+ return 0;
+}
+
+/* Try the same, on the stack */
+void bar ( void )
+{
+ pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;
+ // pthread_mutex_init( &mx, NULL );
+ pthread_mutex_lock( &mx );
+ /* now just abandon mx */
+}
+
+/* and again ... */
+void foo ( void )
+{
+ pthread_mutex_t mx;
+ pthread_mutex_init( &mx, NULL );
+ pthread_mutex_lock( &mx );
+ /* now just abandon mx */
+}
+
Added: branches/THRCHECK/thrcheck/tests/tc04_free_lock.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc04_free_lock.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc04_free_lock.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc04_free_lock.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc04_free_lock.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc04_free_lock
Added: branches/THRCHECK/thrcheck/tests/tc05_simple_race.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc05_simple_race.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc05_simple_race.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,44 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, has a race. Parent and child both modify y
+ with no locking. This is the program shown in Fig 2 of the
+ original Eraser paper by Savage et al. */
+
+int y = 0, v = 0;
+pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
+
+void* child_fn ( void* arg )
+{
+ /* "Thread 2" in the paper */
+ pthread_mutex_lock( &mu );
+ v = v + 1;
+ pthread_mutex_unlock( &mu );
+ y = y + 1;
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ /* "Thread 1" in the paper */
+ y = y + 1;
+ pthread_mutex_lock( &mu );
+ v = v + 1;
+ pthread_mutex_unlock( &mu );
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc05_simple_race.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc05_simple_race.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc05_simple_race.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc05_simple_race.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc05_simple_race.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc05_simple_race
Added: branches/THRCHECK/thrcheck/tests/tc06_two_races.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc06_two_races.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc06_two_races.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,43 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, has two races. A happens-before detector can only
+ ever detect one of them, though. */
+
+int unprot1 = 0, unprot2 = 0, prot = 0;
+pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
+
+void* child_fn ( void* arg )
+{
+ unprot1 ++;
+ pthread_mutex_lock( &mu );
+ prot ++;
+ pthread_mutex_unlock( &mu );
+ unprot2 ++;
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ unprot1 ++;
+ pthread_mutex_lock( &mu );
+ prot ++;
+ pthread_mutex_unlock( &mu );
+ unprot2 ++;
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc06_two_races.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc06_two_races.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc06_two_races.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc06_two_races.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc06_two_races.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc06_two_races
Added: branches/THRCHECK/thrcheck/tests/tc07_hbl1.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc07_hbl1.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc07_hbl1.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,66 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Simple test program, no race. Parent and child both modify x and
+ use the hardware bus lock. */
+
+#undef PLAT_x86_linux
+#undef PLAT_amd64_linux
+#undef PLAT_ppc32_linux
+#undef PLAT_ppc64_linux
+#undef PLAT_ppc32_aix5
+#undef PLAT_ppc64_aix5
+
+#if !defined(_AIX) && defined(__i386__)
+# define PLAT_x86_linux 1
+#elif !defined(_AIX) && defined(__x86_64__)
+# define PLAT_amd64_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+# define PLAT_ppc32_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+# define PLAT_ppc64_linux 1
+#elif defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#endif
+
+
+#if defined(PLAT_amd64_linux)
+# define INC(_lval) \
+ __asm__ __volatile__ ( \
+ "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
+#else
+# error "Fix Me for this platform"
+#endif
+
+
+int x = 0;
+
+void* child_fn ( void* arg )
+{
+ INC(x);
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ INC(x);
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ printf("x = %d\n", x);
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc07_hbl1.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc07_hbl1.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc07_hbl1.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc07_hbl1.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc07_hbl1.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc07_hbl1
Added: branches/THRCHECK/thrcheck/tests/tc08_hbl2.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc08_hbl2.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc08_hbl2.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,87 @@
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+
+/* Simple test program, no race. Parent writes atomically to a counter
+ whilst child reads it. When counter reaches a prearranged value,
+ child joins back to parent. Parent (writer) uses hardware bus lock;
+ child is only reading and so does not need to use a bus lock. */
+
+
+#undef PLAT_x86_linux
+#undef PLAT_amd64_linux
+#undef PLAT_ppc32_linux
+#undef PLAT_ppc64_linux
+#undef PLAT_ppc32_aix5
+#undef PLAT_ppc64_aix5
+
+#if !defined(_AIX) && defined(__i386__)
+# define PLAT_x86_linux 1
+#elif !defined(_AIX) && defined(__x86_64__)
+# define PLAT_amd64_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
+# define PLAT_ppc32_linux 1
+#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
+# define PLAT_ppc64_linux 1
+#elif defined(_AIX) && defined(__64BIT__)
+# define PLAT_ppc64_aix5 1
+#elif defined(_AIX) && !defined(__64BIT__)
+# define PLAT_ppc32_aix5 1
+#endif
+
+
+#if defined(PLAT_amd64_linux)
+# define INC(_lval) \
+ __asm__ __volatile__ ( \
+ "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
+#else
+# error "Fix Me for this platform"
+#endif
+
+
+
+#define LIMIT 10
+
+int x = 0;
+
+void* child_fn ( void* arg )
+{
+ int q = 0;
+ int oldx = 0;
+ while (1) {
+ q = x == LIMIT;
+ if (x != oldx) {
+ oldx = x;
+ printf("child: new value %d\n", oldx);
+ }
+ if (q) break;
+ }
+ return NULL;
+}
+
+int main ( void )
+{
+ pthread_t child;
+ int i;
+
+ if (pthread_create(&child, NULL, child_fn, NULL)) {
+ perror("pthread_create");
+ exit(1);
+ }
+
+ for (i = 0; i < LIMIT; i++) {
+ INC(x);
+ /* Not really necessary, but just gives the child a chance
+ to run too. */
+ sched_yield();
+ }
+
+ if (pthread_join(child, NULL)) {
+ perror("pthread join");
+ exit(1);
+ }
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc08_hbl2.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc08_hbl2.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc08_hbl2.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc08_hbl2.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc08_hbl2.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc08_hbl2
Added: branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,52 @@
+
+/* Check that an error is reported for various kinds of bogus
+ pthread_mutex_unlock calls. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void* child_fn ( void* arg )
+{
+ pthread_mutex_unlock( (pthread_mutex_t*)arg ); /* ERROR */
+ return NULL;
+}
+
+void nearly_main ( void )
+{
+ pthread_t child;
+ pthread_mutex_t mx1, mx2;
+ int bogus[100];
+
+ /* Unlocking a lock that is already unlocked */
+
+ pthread_mutex_init( &mx1, NULL );
+ pthread_mutex_lock( &mx1 );
+ pthread_mutex_unlock( &mx1 );
+
+ pthread_mutex_unlock( &mx1 ); /* ERROR */
+
+ /* Unlocking a lock that is held by a different thread */
+
+ pthread_mutex_init( &mx2, NULL );
+ pthread_mutex_lock( &mx2 );
+ // start child and get it to unlock this lock
+
+ pthread_create( &child, NULL, child_fn, (void*)&mx2 );
+ /* child runs and attempts to unlock our lock. Error
+ is reported in child_fn. */
+ pthread_join(child, NULL );
+
+ /* Unlocking a totally bogus lock. */
+ pthread_mutex_unlock( (pthread_mutex_t*) &bogus[50] ); /* ERROR */
+
+ /* Now we get a freeing-locked-lock error, since the stack
+ frame is removed whilst mx2 is still locked. */
+}
+
+int main ( void )
+{
+ nearly_main();
+ nearly_main();
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc09_bad_unlock.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc09_bad_unlock
Added: branches/THRCHECK/thrcheck/tests/tc10_rec_lock.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc10_rec_lock.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc10_rec_lock.c 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1,46 @@
+
+/* Do simple things with a recursive mutex. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define __USE_UNIX98 1
+#include <pthread.h>
+
+void nearly_main ( void )
+{
+ pthread_mutex_t mx1;
+ pthread_mutexattr_t attr;
+ int r;
+
+ r = pthread_mutexattr_init( &attr );
+ assert(r==0);
+ r = pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
+ assert(r==0);
+ r = pthread_mutex_init( &mx1, &attr );
+ assert(r==0);
+
+ fprintf(stderr, "before lock #1\n");
+ r = pthread_mutex_lock( &mx1 ); assert(r == 0);
+ fprintf(stderr, "before lock #2\n");
+ r = pthread_mutex_lock( &mx1 ); assert(r == 0);
+ fprintf(stderr, "before lock #3\n");
+ r = pthread_mutex_lock( &mx1 ); assert(r == 0);
+
+ fprintf(stderr, "before unlock #1\n");
+ r = pthread_mutex_unlock( &mx1 ); assert(r == 0);
+ fprintf(stderr, "before unlock #2\n");
+ r = pthread_mutex_unlock( &mx1 ); assert(r == 0);
+ fprintf(stderr, "before unlock #3\n");
+ r = pthread_mutex_unlock( &mx1 ); assert(r == 0);
+
+ fprintf(stderr, "before unlock #4\n");
+ r = pthread_mutex_unlock( &mx1 ); /* FAILS: assert(r == 0); */
+}
+
+int main ( void )
+{
+ nearly_main();
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc10_rec_lock.stderr.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc10_rec_lock.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc10_rec_lock.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc10_rec_lock.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc10_rec_lock.vgtest 2007-09-10 14:06:40 UTC (rev 6812)
@@ -0,0 +1 @@
+prog: tc10_rec_lock
|