You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
1
(10) |
2
(8) |
3
(17) |
4
(28) |
5
(22) |
6
(8) |
|
7
(8) |
8
(22) |
9
(12) |
10
(17) |
11
(14) |
12
(15) |
13
(6) |
|
14
(9) |
15
(9) |
16
(16) |
17
(13) |
18
(18) |
19
(7) |
20
(5) |
|
21
(6) |
22
(5) |
23
(11) |
24
(5) |
25
(11) |
26
(7) |
27
(15) |
|
28
(11) |
29
(12) |
30
(12) |
31
(15) |
|
|
|
|
From: <sv...@va...> - 2007-10-25 23:12:50
|
Author: sewardj
Date: 2007-10-26 00:12:48 +0100 (Fri, 26 Oct 2007)
New Revision: 7035
Log:
* enhanced VCG output for happens-before graph
* fix assertion failure shown up by tc18_semabuse.c
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-25 17:39:42 UTC (rev 7034)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-25 23:12:48 UTC (rev 7035)
@@ -117,8 +117,9 @@
// 2 = as 1 + segments at condition variable signal/broadcast/wait too
static Int clo_happens_before = 2; /* default setting */
-/* Generate .vcg output of the happens-before graph? */
-static Bool clo_gen_vcg = False;
+/* Generate .vcg output of the happens-before graph?
+ 0: no 1: yes, without VTSs 2: yes, with VTSs */
+static Int clo_gen_vcg = 0;
/* When comparing race errors for equality, should the race address be
taken into account? For users, no, but for verification purposes
@@ -2118,10 +2119,14 @@
VG_(printf)("Thr# %d", seg->thr->errmsg_index);
}
- show_VTS( vtsstr, sizeof(vtsstr)-1, seg->vts );
- vtsstr[sizeof(vtsstr)-1] = 0;
+ if (clo_gen_vcg >= 2) {
+ show_VTS( vtsstr, sizeof(vtsstr)-1, seg->vts );
+ vtsstr[sizeof(vtsstr)-1] = 0;
+ VG_(printf)("\\n%s", vtsstr);
+ }
- VG_(printf)("\\n%s\" }\n", vtsstr);
+ VG_(printf)("\" }\n", vtsstr);
+
if (seg->prev)
VG_(printf)(PFX "edge: { sourcename: \"%p\" targetname: \"%p\""
"color: black }\n", seg->prev, seg );
@@ -5863,9 +5868,13 @@
} else {
/* Hmm. How can a wait on 'cond' succeed if nobody signalled
it? If this happened it would surely be a bug in the
- threads library. */
- // FIXME
- tl_assert(0);
+ threads library. Or one of those fabled "spurious
+ wakeups". */
+ record_error_Misc( thr, "Bug in libpthread: pthread_cond_wait "
+ "succeeded on"
+ " without prior pthread_cond_post");
+ tl_assert(new_seg->prev->vts);
+ new_seg->vts = tick_VTS( new_seg->thr, new_seg->prev->vts );
}
}
}
@@ -6179,6 +6188,8 @@
threads library. */
record_error_Misc( thr, "Bug in libpthread: sem_wait succeeded on"
" semaphore without prior sem_post");
+ tl_assert(new_seg->prev->vts);
+ new_seg->vts = tick_VTS( new_seg->thr, new_seg->prev->vts );
}
}
}
@@ -7169,6 +7180,20 @@
evh__TC_POSIX_SEM_ZAPSTACK( tid, (void*)args[1] );
break;
+ case _VG_USERREQ__TC_GET_MY_SEGMENT: { // -> Segment*
+ Thread* thr;
+ SegmentID segid;
+ Segment* seg;
+ thr = map_threads_maybe_lookup( tid );
+ tl_assert(thr); /* cannot fail */
+ segid = thr->csegid;
+ tl_assert(is_sane_SegmentID(segid));
+ seg = map_segments_lookup( segid );
+ tl_assert(seg);
+ *ret = (UWord)seg;
+ break;
+ }
+
default:
/* Unhandled Thrcheck client request! */
tl_assert2(0, "unhandled Thrcheck client request!");
@@ -7954,9 +7979,11 @@
clo_happens_before = 2;
else if (VG_CLO_STREQ(arg, "--gen-vcg=no"))
- clo_gen_vcg = False;
+ clo_gen_vcg = 0;
else if (VG_CLO_STREQ(arg, "--gen-vcg=yes"))
- clo_gen_vcg = True;
+ clo_gen_vcg = 1;
+ else if (VG_CLO_STREQ(arg, "--gen-vcg=yes-w-vts"))
+ clo_gen_vcg = 2;
else if (VG_CLO_STREQ(arg, "--cmp-race-err-addrs=no"))
clo_cmp_race_err_addrs = False;
@@ -7981,7 +8008,7 @@
static void tc_print_debug_usage ( void )
{
VG_(replacement_malloc_print_debug_usage)();
- VG_(printf)(" --gen-vcg=no|yes show happens-before graph "
+ VG_(printf)(" --gen-vcg=no|yes|yes-w-vts show happens-before graph "
"in .vcg format [no]\n");
VG_(printf)(" --cmp-race-err-addrs=no|yes are data addresses in "
"race errors significant? [no]\n");
@@ -7998,7 +8025,7 @@
if (sanity_flags)
all__sanity_check("SK_(fini)");
- if (clo_gen_vcg)
+ if (clo_gen_vcg > 0)
segments__generate_vcg();
if (VG_(clo_verbosity) >= 2) {
|
|
From: <sv...@va...> - 2007-10-25 17:39:41
|
Author: sewardj
Date: 2007-10-25 18:39:42 +0100 (Thu, 25 Oct 2007)
New Revision: 7034
Log:
Add a (pretty lame) test re doing stupid things with semaphores.
Added:
branches/THRCHECK/thrcheck/tests/tc18_semabuse.c
branches/THRCHECK/thrcheck/tests/tc18_semabuse.stderr.exp
branches/THRCHECK/thrcheck/tests/tc18_semabuse.stdout.exp
branches/THRCHECK/thrcheck/tests/tc18_semabuse.vgtest
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-10-25 16:59:14 UTC (rev 7033)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-10-25 17:39:42 UTC (rev 7034)
@@ -42,7 +42,9 @@
tc16_byterace.vgtest tc16_byterace.stderr.exp \
tc16_byterace.stdout.exp \
tc17_sembar.vgtest tc17_sembar.stderr.exp \
- tc17_sembar.stdout.exp
+ tc17_sembar.stdout.exp \
+ tc18_semabuse.vgtest tc18_semabuse.stderr.exp \
+ tc18_semabuse.stdout.exp
check_PROGRAMS = \
hg01_all_ok \
@@ -67,7 +69,8 @@
tc14_laog_dinphils \
tc15_laog_lockdel \
tc16_byterace \
- tc17_sembar
+ tc17_sembar \
+ tc18_semabuse
# is this necessary?
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI)
Added: branches/THRCHECK/thrcheck/tests/tc18_semabuse.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc18_semabuse.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc18_semabuse.c 2007-10-25 17:39:42 UTC (rev 7034)
@@ -0,0 +1,42 @@
+
+/* Do stupid things with semaphores, and check that Thrcheck doesn't
+ fall over and does report errors appropriately. If nothing else
+ this just checks that the relevant functions are getting
+ intercepted. */
+
+/* This is pretty lame, because making the sem_ functions fail is
+ difficult. Not sure it's really worth having. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <string.h>
+
+int main ( void )
+{
+ int r;
+ sem_t s1;
+
+ /* Do sem_init with huge initial count */
+ r= sem_init(&s1, 0, ~0);
+
+ /* initialise properly */
+ r= sem_init(&s1, 0, 0);
+
+ /* in glibc, sem_destroy is a no-op; making it fail is
+ impossible. */
+
+ /* Do 'wait' on a bogus semaphore. This should fail, but on glibc
+ it succeeds. */
+ memset(&s1, 0x55, sizeof(s1));
+ r= sem_wait(&s1); /* assert(r != 0); */
+
+ /* this really ought to fail, but it doesn't. */
+ r= sem_post(&s1); assert(!r);
+
+ sem_destroy(&s1);
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc18_semabuse.stderr.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc18_semabuse.stderr.exp (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc18_semabuse.stderr.exp 2007-10-25 17:39:42 UTC (rev 7034)
@@ -0,0 +1,14 @@
+
+Thread #1 is the program's root thread
+
+Thread #1's call to sem_init failed
+ with error code 22 (EINVAL: Invalid argument)
+ at 0x........: sem_init@* (tc_intercepts.c:...)
+ by 0x........: main (tc18_semabuse.c:23)
+
+Thread #1: Bug in libpthread: sem_wait succeeded on semaphore without prior sem_post
+ at 0x........: sem_wait_WRK (tc_intercepts.c:...)
+ by 0x........: sem_wait (tc_intercepts.c:...)
+ by 0x........: main (tc18_semabuse.c:34)
+
+ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc18_semabuse.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc18_semabuse.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc18_semabuse.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc18_semabuse.vgtest 2007-10-25 17:39:42 UTC (rev 7034)
@@ -0,0 +1 @@
+prog: tc18_semabuse
|
|
From: <sv...@va...> - 2007-10-25 16:59:13
|
Author: sewardj
Date: 2007-10-25 17:59:14 +0100 (Thu, 25 Oct 2007)
New Revision: 7033
Log:
Test semaphore handling, by using them to build a barrier.
Added:
branches/THRCHECK/thrcheck/tests/tc17_sembar.c
branches/THRCHECK/thrcheck/tests/tc17_sembar.stderr.exp
branches/THRCHECK/thrcheck/tests/tc17_sembar.stdout.exp
branches/THRCHECK/thrcheck/tests/tc17_sembar.vgtest
Modified:
branches/THRCHECK/thrcheck/tests/Makefile.am
Modified: branches/THRCHECK/thrcheck/tests/Makefile.am
===================================================================
--- branches/THRCHECK/thrcheck/tests/Makefile.am 2007-10-25 16:09:46 UTC (rev 7032)
+++ branches/THRCHECK/thrcheck/tests/Makefile.am 2007-10-25 16:59:14 UTC (rev 7033)
@@ -1,6 +1,4 @@
-# FIXME: this is completely bogus (a copy of Helgrind's one)
-
# For AM_FLAG_M3264_PRI
include $(top_srcdir)/Makefile.flags.am
@@ -42,7 +40,9 @@
tc15_laog_lockdel.vgtest tc15_laog_lockdel.stderr.exp \
tc15_laog_lockdel.stdout.exp \
tc16_byterace.vgtest tc16_byterace.stderr.exp \
- tc16_byterace.stdout.exp
+ tc16_byterace.stdout.exp \
+ tc17_sembar.vgtest tc17_sembar.stderr.exp \
+ tc17_sembar.stdout.exp
check_PROGRAMS = \
hg01_all_ok \
@@ -66,7 +66,8 @@
tc13_laog1 \
tc14_laog_dinphils \
tc15_laog_lockdel \
- tc16_byterace
+ tc16_byterace \
+ tc17_sembar
# is this necessary?
AM_CFLAGS = $(WERROR) -Winline -Wall -Wshadow -g $(AM_FLAG_M3264_PRI)
Added: branches/THRCHECK/thrcheck/tests/tc17_sembar.c
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc17_sembar.c (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc17_sembar.c 2007-10-25 16:59:14 UTC (rev 7033)
@@ -0,0 +1,178 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+/* This is really a test of semaphore handling
+ (sem_{init,destroy,post,wait}). Using semaphores a barrier
+ function is created. Thrcheck does understand the barrier
+ semantics implied by the barrier, as pieced together from
+ happens-before relationships obtained from the component
+ semaphores. However, it does falsely report one race. Ah well. */
+
+/* This code is derived from
+ gcc-4.3-20071012/libgomp/config/posix/bar.c, which is
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Contributed by Richard Henderson <rt...@re...>.
+
+ and available under version 2.1 or later of the GNU Lesser General
+ Public License.
+
+ Relative to the libgomp sources, the gomp_barrier_t type here has
+ an extra semaphore field, xxx. This is not functionally useful,
+ but it is used to create enough extra inter-thread dependencies
+ that the barrier-like behaviour of gomp_barrier_t is evident to
+ Thrcheck. There is no other purpose for the .xxx field. */
+
+typedef struct
+{
+ pthread_mutex_t mutex1;
+ pthread_mutex_t mutex2;
+ sem_t sem1;
+ sem_t sem2;
+ unsigned total;
+ unsigned arrived;
+ sem_t xxx;
+} gomp_barrier_t;
+
+typedef long bool;
+
+void
+gomp_barrier_init (gomp_barrier_t *bar, unsigned count)
+{
+ pthread_mutex_init (&bar->mutex1, NULL);
+ pthread_mutex_init (&bar->mutex2, NULL);
+ sem_init (&bar->sem1, 0, 0);
+ sem_init (&bar->sem2, 0, 0);
+ sem_init (&bar->xxx, 0, 0);
+ bar->total = count;
+ bar->arrived = 0;
+}
+
+void
+gomp_barrier_destroy (gomp_barrier_t *bar)
+{
+ /* Before destroying, make sure all threads have left the barrier. */
+ pthread_mutex_lock (&bar->mutex1);
+ pthread_mutex_unlock (&bar->mutex1);
+
+ pthread_mutex_destroy (&bar->mutex1);
+ pthread_mutex_destroy (&bar->mutex2);
+ sem_destroy (&bar->sem1);
+ sem_destroy (&bar->sem2);
+ sem_destroy(&bar->xxx);
+}
+
+void
+gomp_barrier_reinit (gomp_barrier_t *bar, unsigned count)
+{
+ pthread_mutex_lock (&bar->mutex1);
+ bar->total = count;
+ pthread_mutex_unlock (&bar->mutex1);
+}
+
+void
+gomp_barrier_wait (gomp_barrier_t *bar)
+{
+ unsigned int n;
+ pthread_mutex_lock (&bar->mutex1);
+
+ ++bar->arrived;
+
+ if (bar->arrived == bar->total)
+ {
+ bar->arrived--;
+ n = bar->arrived;
+ if (n > 0)
+ {
+ { unsigned int i;
+ for (i = 0; i < n; i++)
+ sem_wait(&bar->xxx); // acquire an obvious dependency from
+ // all other threads arriving at the barrier
+ }
+ // 1 up n times, 2 down once
+ // now let all the other threads past the barrier, giving them
+ // an obvious dependency with this thread.
+ do
+ sem_post (&bar->sem1); // 1 up
+ while (--n != 0);
+ // and wait till the last thread has left
+ sem_wait (&bar->sem2); // 2 down
+ }
+ pthread_mutex_unlock (&bar->mutex1);
+ /* Resultat professionnel! First we made this thread have an
+ obvious (Thrcheck-visible) dependency on all other threads
+ calling gomp_barrier_wait. Then, we released them all again,
+ so they all have a (visible) dependency on this thread.
+ Transitively, the result is that all threads leaving the
+ barrier have a a Thrcheck-visible dependency on all threads
+ arriving at the barrier. As required. */
+ }
+ else
+ {
+ pthread_mutex_unlock (&bar->mutex1);
+ sem_post(&bar->xxx);
+ // first N-1 threads wind up waiting here
+ sem_wait (&bar->sem1); // 1 down
+
+ pthread_mutex_lock (&bar->mutex2);
+ n = --bar->arrived; /* XXX see below */
+ pthread_mutex_unlock (&bar->mutex2);
+
+ if (n == 0)
+ sem_post (&bar->sem2); // 2 up
+ }
+}
+
+
+/* re XXX, thrcheck reports a race at this point. It doesn't
+ understand that bar->arrived is protected by mutex1 whilst threads
+ are arriving at the barrier and by mutex2 whilst they are leaving,
+ but not consistently by either of them. Oh well. */
+
+gomp_barrier_t bar;
+
+void* child ( void* argV )
+{
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ gomp_barrier_wait( &bar );
+ return NULL;
+}
+
+#define NNN 4
+
+int main (int argc, char *argv[])
+{
+ int j;
+ long i; int res;
+ pthread_t thr[NNN];
+ fprintf(stderr, "starting\n");
+
+ for (j = 0; j < 1; j++) {
+ gomp_barrier_init( &bar, NNN );
+
+ for (i = 0; i < NNN; i++) {
+ res = pthread_create( &thr[i], NULL, child, (void*)i );
+ assert(!res);
+ }
+
+ for (i = 0; i < NNN; i++) {
+ res = pthread_join( thr[i], NULL );
+ assert(!res);
+ }
+
+ gomp_barrier_destroy( &bar );
+ }
+ fprintf(stderr, "done\n");
+
+ return 0;
+}
Added: branches/THRCHECK/thrcheck/tests/tc17_sembar.stderr.exp
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc17_sembar.stderr.exp (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc17_sembar.stderr.exp 2007-10-25 16:59:14 UTC (rev 7033)
@@ -0,0 +1,46 @@
+
+starting
+Thread #2 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: ...
+ by 0x........: pthread_create@@GLIBC_2.2.5 (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc17_sembar.c:164)
+
+Thread #3 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: ...
+ by 0x........: pthread_create@@GLIBC_2.2.5 (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc17_sembar.c:164)
+
+Thread #4 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: ...
+ by 0x........: pthread_create@@GLIBC_2.2.5 (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc17_sembar.c:164)
+
+Thread #5 was created
+ at 0x........: clone (in /...libc...)
+ by 0x........: ...
+ by 0x........: pthread_create@@GLIBC_2.2.5 (in /lib/libpthread...)
+ by 0x........: pthread_create@* (tc_intercepts.c:...)
+ by 0x........: main (tc17_sembar.c:164)
+
+Possible data race during read of size 4 at 0x........
+ at 0x........: gomp_barrier_wait (tc17_sembar.c:122)
+ by 0x........: child (tc17_sembar.c:140)
+ by 0x........: mythread_wrapper (tc_intercepts.c:...)
+ by 0x........: ...
+ by 0x........: ...
+ Old state: shared-modified by threads #2, #3, #4, #5
+ New state: shared-modified by threads #2, #3, #4, #5
+ Reason: this thread, #2, holds no consistent locks
+ Last consistently used lock for 0x........ was first observed
+ at 0x........: pthread_mutex_init (tc_intercepts.c:...)
+ by 0x........: gomp_barrier_init (tc17_sembar.c:46)
+ by 0x........: main (tc17_sembar.c:161)
+done
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Added: branches/THRCHECK/thrcheck/tests/tc17_sembar.stdout.exp
===================================================================
Added: branches/THRCHECK/thrcheck/tests/tc17_sembar.vgtest
===================================================================
--- branches/THRCHECK/thrcheck/tests/tc17_sembar.vgtest (rev 0)
+++ branches/THRCHECK/thrcheck/tests/tc17_sembar.vgtest 2007-10-25 16:59:14 UTC (rev 7033)
@@ -0,0 +1 @@
+prog: tc17_sembar
|
|
From: <sv...@va...> - 2007-10-25 16:09:50
|
Author: sewardj
Date: 2007-10-25 17:09:46 +0100 (Thu, 25 Oct 2007)
New Revision: 7032
Log:
Fix intercepts for sem_wait and sem_post on 32-bit systems.
Modified:
branches/THRCHECK/thrcheck/tc_intercepts.c
Modified: branches/THRCHECK/thrcheck/tc_intercepts.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_intercepts.c 2007-10-25 09:45:57 UTC (rev 7031)
+++ branches/THRCHECK/thrcheck/tc_intercepts.c 2007-10-25 16:09:46 UTC (rev 7032)
@@ -844,7 +844,8 @@
const struct timespec *restrict abs_timeout);
*/
-/* glibc-2.5 has sem_init@@GLIBC_2.2.5; match sem_init@* */
+/* glibc-2.5 has sem_init@@GLIBC_2.2.5 (amd64-linux)
+ and sem_init@@GLIBC_2.1 (x86-linux): match sem_init@* */
PTH_FUNC(int, semZuinitZAZa, sem_t* sem, int pshared, unsigned long value)
{
OrigFn fn;
@@ -874,7 +875,8 @@
}
-/* glibc-2.5 has sem_destroy@@GLIBC_2.2.5; match sem_destroy@* */
+/* glibc-2.5 has sem_destroy@@GLIBC_2.2.5 (amd64-linux)
+ and sem_destroy@@GLIBC_2.1 (x86-linux); match sem_destroy@* */
PTH_FUNC(int, semZudestroyZAZa, sem_t* sem)
{
OrigFn fn;
@@ -903,9 +905,10 @@
}
-/* glibc-2.5 has sem_wait; match sem_wait */
+/* glibc-2.5 has sem_wait (amd64-linux); match sem_wait
+ and sem_wait@@GLIBC_2.1 (x86-linux); match sem_wait@* */
/* wait: decrement semaphore - acquire lockage */
-PTH_FUNC(int, semZuwait, sem_t* sem)
+static int sem_wait_WRK(sem_t* sem)
{
OrigFn fn;
int ret;
@@ -931,11 +934,18 @@
return ret;
}
+PTH_FUNC(int, semZuwait, sem_t* sem) { /* sem_wait */
+ return sem_wait_WRK(sem);
+}
+PTH_FUNC(int, semZuwaitZAZa, sem_t* sem) { /* sem_wait@* */
+ return sem_wait_WRK(sem);
+}
-/* glibc-2.5 has sem_post; match sem_post */
+/* glibc-2.5 has sem_post (amd64-linux); match sem_post
+ and sem_post@@GLIBC_2.1 (x86-linux); match sem_post@* */
/* post: increment semaphore - release lockage */
-PTH_FUNC(int, semZupost, sem_t* sem)
+static int sem_post_WRK(sem_t* sem)
{
OrigFn fn;
int ret;
@@ -962,8 +972,15 @@
return ret;
}
+PTH_FUNC(int, semZupost, sem_t* sem) { /* sem_post */
+ return sem_post_WRK(sem);
+}
+PTH_FUNC(int, semZupostZAZa, sem_t* sem) { /* sem_post@* */
+ return sem_post_WRK(sem);
+}
+
/*----------------------------------------------------------------*/
/*--- Qt 4 threading functions (w/ GNU name mangling) ---*/
/*----------------------------------------------------------------*/
|
|
From: Bart V. A. <bar...@gm...> - 2007-10-25 10:03:50
|
Welcome to the world of vector clocks ... Do you see an opportunity of sharing the vector clock / vector timestamp code between thrcheck and drd ? Bart. On 10/25/07, sv...@va... <sv...@va...> wrote: > Author: sewardj > Date: 2007-10-25 10:45:57 +0100 (Thu, 25 Oct 2007) > New Revision: 7031 > > Log: > Use a vector timestamp mechanism to speed up comparisons in the > happens-before graph, which can tend to dominate all other costs in > programs which generate more than a few thousand Segments. > > Modified: > branches/THRCHECK/thrcheck/tc_main.c |
|
From: <sv...@va...> - 2007-10-25 09:45:58
|
Author: sewardj
Date: 2007-10-25 10:45:57 +0100 (Thu, 25 Oct 2007)
New Revision: 7031
Log:
Use a vector timestamp mechanism to speed up comparisons in the
happens-before graph, which can tend to dominate all other costs in
programs which generate more than a few thousand Segments.
Modified:
branches/THRCHECK/thrcheck/tc_main.c
Modified: branches/THRCHECK/thrcheck/tc_main.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_main.c 2007-10-23 22:26:12 UTC (rev 7030)
+++ branches/THRCHECK/thrcheck/tc_main.c 2007-10-25 09:45:57 UTC (rev 7031)
@@ -303,6 +303,7 @@
struct _Segment* prev; /* The previous segment in this thread */
struct _Segment* other; /* Possibly a segment from some other
thread, which happened-before me */
+ XArray* vts; /* XArray of ScalarTS */
/* DEBUGGING ONLY: what does 'other' arise from?
c=thread creation, j=join, s=cvsignal, S=semaphore */
Char other_hint;
@@ -574,6 +575,7 @@
seg->thr = thr;
seg->prev = prev;
seg->other = other;
+ seg->vts = NULL;
seg->other_hint = ' ';
seg->magic = Segment_MAGIC;
seg->admin = admin_segments;
@@ -1279,6 +1281,7 @@
static void shmem__set_mbHasLocks ( Addr a, Bool b );
static Bool shmem__get_mbHasLocks ( Addr a );
static void shadow_mem_set8 ( Thread* uu_thr_acc, Addr a, UInt svNew );
+static XArray* singleton_VTS ( Thread* thr, UWord tym );
static void initialise_data_structures ( void )
{
@@ -1343,7 +1346,11 @@
thr = mk_Thread( segid );
seg->thr = thr;
- /* and bind it in the thread-map table */
+ /* Give the thread a starting-off vector timestamp. */
+ seg->vts = singleton_VTS( seg->thr, 1 );
+
+ /* and bind it in the thread-map table.
+ FIXME: assumes root ThreadId == 1. */
map_threads[1] = thr;
tl_assert(VG_INVALID_THREADID == 0);
@@ -1482,6 +1489,8 @@
/*--- the DAG of thread segments ---*/
/*----------------------------------------------------------------*/
+static void segments__generate_vcg ( void ); /* fwds */
+
/*--------------- SegmentID to Segment* maps ---------------*/
static Segment* map_segments_lookup ( SegmentID segid )
@@ -1512,6 +1521,351 @@
TC_(addToFM)( map_segments, (Word)segid, (Word)seg );
}
+/*--------------- to do with Vector Timestamps ---------------*/
+
+/* Scalar Timestamp */
+typedef
+ struct {
+ Thread* thr;
+ UWord tym;
+ }
+ ScalarTS;
+
+/* Vector Timestamp = XArray* ScalarTS */
+
+static Bool is_sane_VTS ( XArray* vts )
+{
+ UWord i, n;
+ ScalarTS *st1, *st2;
+ n = VG_(sizeXA)( vts );
+ if (n >= 2) {
+ for (i = 0; i < n-1; i++) {
+ st1 = VG_(indexXA)( vts, i );
+ st2 = VG_(indexXA)( vts, i+1 );
+ if (st1->thr >= st2->thr)
+ return False;
+ if (st1->tym == 0 || st2->tym == 0)
+ return False;
+ }
+ }
+ return True;
+}
+
+static XArray* new_VTS ( void ) {
+ return VG_(newXA)( tc_zalloc, tc_free, sizeof(ScalarTS) );
+}
+static XArray* singleton_VTS ( Thread* thr, UWord tym ) {
+ ScalarTS st;
+ XArray* vts;
+ tl_assert(thr);
+ tl_assert(tym >= 1);
+ vts = new_VTS();
+ tl_assert(vts);
+ st.thr = thr;
+ st.tym = tym;
+ VG_(addToXA)( vts, &st );
+ return vts;
+}
+
+
+static Bool cmpGEQ_VTS ( XArray* a, XArray* b )
+{
+ Word ia, ib, useda, usedb;
+ UWord tyma, tymb;
+ Thread* thr;
+ ScalarTS *tmpa, *tmpb;
+
+ Bool all_leq = True;
+ Bool all_geq = True;
+
+ tl_assert(a);
+ tl_assert(b);
+ useda = VG_(sizeXA)( a );
+ usedb = VG_(sizeXA)( b );
+
+ ia = ib = 0;
+
+ while (1) {
+
+ /* This logic is to enumerate triples (thr, tyma, tymb) drawn
+ from a and b in order, where thr is the next Thread*
+ occurring in either a or b, and tyma/b are the relevant
+ scalar timestamps, taking into account implicit zeroes. */
+ tl_assert(ia >= 0 && ia <= useda);
+ tl_assert(ib >= 0 && ib <= usedb);
+ tmpa = tmpb = NULL;
+
+ if (ia == useda && ib == usedb) {
+ /* both empty - done */
+ break;
+ }
+ else
+ if (ia == useda && ib != usedb) {
+ /* a empty, use up b */
+ tmpb = VG_(indexXA)( b, ib );
+ thr = tmpb->thr;
+ tyma = 0;
+ tymb = tmpb->tym;
+ ib++;
+ }
+ else
+ if (ia != useda && ib == usedb) {
+ /* b empty, use up a */
+ tmpa = VG_(indexXA)( a, ia );
+ thr = tmpa->thr;
+ tyma = tmpa->tym;
+ tymb = 0;
+ ia++;
+ }
+ else {
+ /* both not empty; extract lowest-Thread*'d triple */
+ tmpa = VG_(indexXA)( a, ia );
+ tmpb = VG_(indexXA)( b, ib );
+ if (tmpa->thr < tmpb->thr) {
+ /* a has the lowest unconsidered Thread* */
+ thr = tmpa->thr;
+ tyma = tmpa->tym;
+ tymb = 0;
+ ia++;
+ }
+ else
+ if (tmpa->thr > tmpb->thr) {
+ /* b has the lowest unconsidered Thread* */
+ thr = tmpb->thr;
+ tyma = 0;
+ tymb = tmpb->tym;
+ ib++;
+ } else {
+ /* they both next mention the same Thread* */
+ tl_assert(tmpa->thr == tmpb->thr);
+ thr = tmpa->thr; /* == tmpb->thr */
+ tyma = tmpa->tym;
+ tymb = tmpb->tym;
+ ia++;
+ ib++;
+ }
+ }
+
+ /* having laboriously determined (thr, tyma, tymb), do something
+ useful with it. */
+ if (tyma < tymb)
+ all_geq = False;
+ if (tyma > tymb)
+ all_leq = False;
+ }
+
+ if (all_leq && all_geq)
+ return True; /* PordEQ */
+ /* now we know they aren't equal, so either all_leq or all_geq or
+ both are false. */
+ if (all_leq)
+ return False; /* PordLT */
+ if (all_geq)
+ return True; /* PordGT */
+ /* hmm, neither all_geq or all_leq. This means unordered. */
+ return False; /* PordUN */
+}
+
+
+/* Compute max((tick(thra,a),b) into a new XArray. a and b are
+ unchanged. If neither a nor b supply a value for 'thra',
+ assert. */
+static
+XArray* tickL_and_joinR_VTS ( Thread* thra, XArray* a, XArray* b )
+{
+ Word ia, ib, useda, usedb, ticks_found;
+ UWord tyma, tymb, tymMax;
+ Thread* thr;
+ XArray* res;
+ ScalarTS *tmpa, *tmpb;
+
+ tl_assert(a);
+ tl_assert(b);
+ tl_assert(thra);
+ useda = VG_(sizeXA)( a );
+ usedb = VG_(sizeXA)( b );
+
+ res = new_VTS();
+ ia = ib = ticks_found = 0;
+
+ while (1) {
+
+ /* This logic is to enumerate triples (thr, tyma, tymb) drawn
+ from a and b in order, where thr is the next Thread*
+ occurring in either a or b, and tyma/b are the relevant
+ scalar timestamps, taking into account implicit zeroes. */
+ tl_assert(ia >= 0 && ia <= useda);
+ tl_assert(ib >= 0 && ib <= usedb);
+ tmpa = tmpb = NULL;
+
+ if (ia == useda && ib == usedb) {
+ /* both empty - done */
+ break;
+ }
+ else
+ if (ia == useda && ib != usedb) {
+ /* a empty, use up b */
+ tmpb = VG_(indexXA)( b, ib );
+ thr = tmpb->thr;
+ tyma = 0;
+ tymb = tmpb->tym;
+ ib++;
+ }
+ else
+ if (ia != useda && ib == usedb) {
+ /* b empty, use up a */
+ tmpa = VG_(indexXA)( a, ia );
+ thr = tmpa->thr;
+ tyma = tmpa->tym;
+ tymb = 0;
+ ia++;
+ }
+ else {
+ /* both not empty; extract lowest-Thread*'d triple */
+ tmpa = VG_(indexXA)( a, ia );
+ tmpb = VG_(indexXA)( b, ib );
+ if (tmpa->thr < tmpb->thr) {
+ /* a has the lowest unconsidered Thread* */
+ thr = tmpa->thr;
+ tyma = tmpa->tym;
+ tymb = 0;
+ ia++;
+ }
+ else
+ if (tmpa->thr > tmpb->thr) {
+ /* b has the lowest unconsidered Thread* */
+ thr = tmpb->thr;
+ tyma = 0;
+ tymb = tmpb->tym;
+ ib++;
+ } else {
+ /* they both next mention the same Thread* */
+ tl_assert(tmpa->thr == tmpb->thr);
+ thr = tmpa->thr; /* == tmpb->thr */
+ tyma = tmpa->tym;
+ tymb = tmpb->tym;
+ ia++;
+ ib++;
+ }
+ }
+
+ /* having laboriously determined (thr, tyma, tymb), do something
+ useful with it. */
+ if (thr == thra) {
+ if (tyma > 0) {
+ /* VTS 'a' actually supplied this value; it is not a
+ default zero. Do the required 'tick' action. */
+ tyma++;
+ ticks_found++;
+ } else {
+ /* 'a' didn't supply this value, so 'b' must have. */
+ tl_assert(tymb > 0);
+ }
+ }
+ tymMax = tyma > tymb ? tyma : tymb;
+ if (tymMax > 0) {
+ ScalarTS st;
+ st.thr = thr;
+ st.tym = tymMax;
+ VG_(addToXA)( res, &st );
+ }
+
+ }
+
+ tl_assert(is_sane_VTS( res ));
+
+ if (thra != NULL) {
+ tl_assert(ticks_found == 1);
+ } else {
+ tl_assert(ticks_found == 0);
+ }
+
+ return res;
+}
+
+
+/* Do 'vts[me]++', so to speak. If 'me' does not have an entry in
+ 'vts', set it to 1 in the returned VTS. */
+
+static XArray* tick_VTS ( Thread* me, XArray* vts ) {
+ ScalarTS* here = NULL;
+ ScalarTS tmp;
+ XArray* res;
+ Word i, n;
+ tl_assert(me);
+ tl_assert(is_sane_VTS(vts));
+ if (0) VG_(printf)("tick vts thrno %ld szin %d\n",
+ (Word)me->errmsg_index, (Int)VG_(sizeXA)(vts) );
+ res = new_VTS();
+ n = VG_(sizeXA)( vts );
+ for (i = 0; i < n; i++) {
+ here = VG_(indexXA)( vts, i );
+ if (me < here->thr) {
+ /* We just went past 'me', without seeing it. */
+ tmp.thr = me;
+ tmp.tym = 1;
+ VG_(addToXA)( res, &tmp );
+ tmp = *here;
+ VG_(addToXA)( res, &tmp );
+ i++;
+ break;
+ }
+ else if (me == here->thr) {
+ tmp = *here;
+ tmp.tym++;
+ VG_(addToXA)( res, &tmp );
+ i++;
+ break;
+ }
+ else /* me > here->thr */ {
+ tmp = *here;
+ VG_(addToXA)( res, &tmp );
+ }
+ }
+ tl_assert(i >= 0 && i <= n);
+ if (i == n && here && here->thr < me) {
+ tmp.thr = me;
+ tmp.tym = 1;
+ VG_(addToXA)( res, &tmp );
+ } else {
+ for (/*keepgoing*/; i < n; i++) {
+ here = VG_(indexXA)( vts, i );
+ tmp = *here;
+ VG_(addToXA)( res, &tmp );
+ }
+ }
+ tl_assert(is_sane_VTS(res));
+ if (0) VG_(printf)("tick vts thrno %ld szou %d\n",
+ (Word)me->errmsg_index, (Int)VG_(sizeXA)(res) );
+ return res;
+}
+
+static void show_VTS ( HChar* buf, Int nBuf, XArray* vts ) {
+ ScalarTS* st;
+ HChar unit[64];
+ Word i, n;
+ Int avail = nBuf;
+ tl_assert(avail > 16);
+ buf[0] = '[';
+ buf[1] = 0;
+ n = VG_(sizeXA)( vts );
+ for (i = 0; i < n; i++) {
+ tl_assert(avail >= 10);
+ st = VG_(indexXA)( vts, i );
+ VG_(memset)(unit, 0, sizeof(unit));
+ VG_(sprintf)(unit, i < n-1 ? "%ld:%ld " : "%ld:%ld",
+ (Word)st->thr->errmsg_index, st->tym);
+ if (avail < VG_(strlen)(unit) + 10/*let's say*/) {
+ VG_(strcat)(buf, " ...]");
+ return;
+ }
+ VG_(strcat)(buf, unit);
+ avail -= VG_(strlen)(unit);
+ }
+ VG_(strcat)(buf, "]");
+}
+
+
/*------------ searching the happens-before graph ------------*/
static UWord stats__hbefore_queries = 0; // total # queries
@@ -1614,18 +1968,9 @@
}
__attribute__((noinline))
-static Bool happens_before_wrk ( SegmentID segid1, SegmentID segid2 )
+static Bool happens_before_wrk ( Segment* seg1, Segment* seg2 )
{
- Bool reachable;
- Segment *seg1, *seg2;
- tl_assert(is_sane_SegmentID(segid1));
- tl_assert(is_sane_SegmentID(segid2));
- tl_assert(segid1 != segid2);
- seg1 = map_segments_lookup(segid1);
- seg2 = map_segments_lookup(segid2);
- tl_assert(is_sane_Segment(seg1));
- tl_assert(is_sane_Segment(seg2));
- tl_assert(seg1 != seg2);
+ Bool reachable;
{ static Int nnn = 0;
if (SHOW_EXPENSIVE_STUFF && (nnn++ % 1000) == 0)
@@ -1640,14 +1985,10 @@
if (dfsver_stack == NULL) {
dfsver_stack = VG_(newXA)( tc_zalloc, tc_free, sizeof(Segment*) );
tl_assert(dfsver_stack);
- }
+ }
reachable = happens_before_do_dfs_from_to( seg2, seg1 );
- if (0)
- VG_(printf)("happens_before 0x%x 0x%x: %s\n",
- (Int)segid1, (Int)segid2, reachable ? "Y" : "N");
-
return reachable;
}
@@ -1675,8 +2016,9 @@
static Bool happens_before ( SegmentID segid1, SegmentID segid2 )
{
- Bool hb;
- Int i, j, iNSERT_POINT;
+ Bool hbG, hbV;
+ Int i, j, iNSERT_POINT;
+ Segment *seg1, *seg2;
tl_assert(is_sane_SegmentID(segid1));
tl_assert(is_sane_SegmentID(segid2));
tl_assert(segid1 != segid2);
@@ -1701,7 +2043,34 @@
}
/* Not found. Search the graph and add an entry to the cache. */
stats__hbefore_gsearches++;
- hb = happens_before_wrk( segid1, segid2 );
+
+ seg1 = map_segments_lookup(segid1);
+ seg2 = map_segments_lookup(segid2);
+ tl_assert(is_sane_Segment(seg1));
+ tl_assert(is_sane_Segment(seg2));
+ tl_assert(seg1 != seg2);
+ tl_assert(seg1->vts);
+ tl_assert(seg2->vts);
+
+ hbV = cmpGEQ_VTS( seg2->vts, seg1->vts );
+ if (0) {
+ /* Crosscheck the vector-timestamp comparison result against that
+ obtained from the explicit graph approach. Can be very
+ slow. */
+ hbG = happens_before_wrk( seg1, seg2 );
+ } else {
+ /* Assume the vector-timestamp comparison result is correct, and
+ use it as-is. */
+ hbG = hbV;
+ }
+
+ if (hbV != hbG) {
+ VG_(printf)("seg1 %p seg2 %p hbV %d hbG %d\n",
+ seg1,seg2,(Int)hbV,(Int)hbG);
+ segments__generate_vcg();
+ }
+ tl_assert(hbV == hbG);
+
iNSERT_POINT = (1*HBEFORE__N_CACHE)/4 - 1;
/* if (iNSERT_POINT > 4) iNSERT_POINT = 4; */
@@ -1710,11 +2079,11 @@
}
hbefore__cache[iNSERT_POINT].segid1 = segid1;
hbefore__cache[iNSERT_POINT].segid2 = segid2;
- hbefore__cache[iNSERT_POINT].result = hb;
+ hbefore__cache[iNSERT_POINT].result = hbG;
if (0)
VG_(printf)("hb %d %d\n", (Int)segid1-(1<<24), (Int)segid2-(1<<24));
- return hb;
+ return hbG;
}
/*--------------- generating .vcg output ---------------*/
@@ -1727,9 +2096,10 @@
Green -- thread creation, link to parent
Red -- thread exit, link to exiting thread
Yellow -- signal edge
- Ping -- semaphore-up edge
+ Pink -- semaphore-up edge
*/
Segment* seg;
+ HChar vtsstr[128];
VG_(printf)(PFX "graph: { title: \"Segments\"\n");
VG_(printf)(PFX "orientation: top_to_bottom\n");
VG_(printf)(PFX "height: 900\n");
@@ -1740,14 +2110,18 @@
for (seg = admin_segments; seg; seg=seg->admin) {
VG_(printf)(PFX "node: { title: \"%p\" color: lightcyan "
- "textcolor: darkgreen label: \"Seg %x\\n",
+ "textcolor: darkgreen label: \"Seg %p\\n",
seg, seg);
if (seg->thr->errmsg_index == 1) {
- VG_(printf)("ROOT_THREAD\" }\n");
+ VG_(printf)("ROOT_THREAD");
} else {
- VG_(printf)("Thr# %d\" }\n", seg->thr->errmsg_index);
+ VG_(printf)("Thr# %d", seg->thr->errmsg_index);
}
+ show_VTS( vtsstr, sizeof(vtsstr)-1, seg->vts );
+ vtsstr[sizeof(vtsstr)-1] = 0;
+
+ VG_(printf)("\\n%s\" }\n", vtsstr);
if (seg->prev)
VG_(printf)(PFX "edge: { sourcename: \"%p\" targetname: \"%p\""
"color: black }\n", seg->prev, seg );
@@ -1757,7 +2131,7 @@
case 'c': colour = "darkgreen"; break; /* creation */
case 'j': colour = "red"; break; /* join (exit) */
case 's': colour = "orange"; break; /* signal */
- case 'S': colour = "pink"; break; /* signal */
+ case 'S': colour = "pink"; break; /* sem_post->wait */
case 'u': colour = "cyan"; break; /* unlock */
default: tl_assert(0);
}
@@ -1947,7 +2321,8 @@
/*--- Sanity checking the data structures ---*/
/*----------------------------------------------------------------*/
-static Bool is_sane_CacheLine ( CacheLine* cl );
+static Bool is_sane_CacheLine ( CacheLine* cl ); /* fwds */
+static Bool cmpGEQ_VTS ( XArray* a, XArray* b ); /* fwds */
/* REQUIRED INVARIANTS:
@@ -2158,6 +2533,13 @@
for (seg = admin_segments; seg; seg = seg->admin) {
if (!is_sane_Segment(seg)) BAD("2");
if (!is_sane_Thread(seg->thr)) BAD("3");
+ if (!seg->vts) BAD("4");
+ if (seg->prev && seg->prev->vts
+ && !cmpGEQ_VTS(seg->vts, seg->prev->vts))
+ BAD("5");
+ if (seg->other && seg->other->vts
+ && !cmpGEQ_VTS(seg->vts, seg->other->vts))
+ BAD("6");
}
return;
bad:
@@ -3481,8 +3863,8 @@
case 0: case 4:
tl_assert(descr & TREE_DESCR_64);
tree[4] = tree[0];
- descr &= ~TREE_DESCR_64;
- descr |= (TREE_DESCR_32_1 | TREE_DESCR_32_0);
+ descr &= ~TREE_DESCR_64;
+ descr |= (TREE_DESCR_32_1 | TREE_DESCR_32_0);
break;
default:
tl_assert(0);
@@ -3495,7 +3877,7 @@
switch (toff) {
case 0: case 2:
if (!(descr & TREE_DESCR_32_0)) {
- descr = pulldown_to_32(tree, 0, descr);
+ descr = pulldown_to_32(tree, 0, descr);
}
tl_assert(descr & TREE_DESCR_32_0);
tree[2] = tree[0];
@@ -3504,7 +3886,7 @@
break;
case 4: case 6:
if (!(descr & TREE_DESCR_32_1)) {
- descr = pulldown_to_32(tree, 4, descr);
+ descr = pulldown_to_32(tree, 4, descr);
}
tl_assert(descr & TREE_DESCR_32_1);
tree[6] = tree[4];
@@ -4889,6 +5271,8 @@
/* Make the child's new segment depend on the parent */
seg_c->other = map_segments_lookup( thr_p->csegid );
seg_c->other_hint = 'c';
+ seg_c->vts = tick_VTS( thr_c, seg_c->other->vts );
+ tl_assert(seg_c->prev == NULL);
/* and start a new segment for the parent. */
{ SegmentID new_segid = 0; /* bogus */
Segment* new_seg = NULL;
@@ -4896,6 +5280,8 @@
thr_p );
tl_assert(is_sane_SegmentID(new_segid));
tl_assert(is_sane_Segment(new_seg));
+ new_seg->vts = tick_VTS( thr_p, new_seg->prev->vts );
+ tl_assert(new_seg->other == NULL);
}
}
}
@@ -4965,6 +5351,9 @@
tl_assert(new_seg->other == NULL);
new_seg->other = map_segments_lookup( thr_q->csegid );
new_seg->other_hint = 'j';
+ tl_assert(new_seg->thr == thr_s);
+ new_seg->vts = tickL_and_joinR_VTS( thr_s, new_seg->prev->vts,
+ new_seg->other->vts );
}
// FIXME: error-if: exiting thread holds any locks
@@ -5394,6 +5783,8 @@
tl_assert( is_sane_Segment(new_seg) );
tl_assert( new_seg->thr == thr );
tl_assert( is_sane_Segment(new_seg->prev) );
+ tl_assert( new_seg->prev->vts );
+ new_seg->vts = tick_VTS( new_seg->thr, new_seg->prev->vts );
/* ... and add the binding. */
TC_(addToFM)( map_cond_to_Segment, (Word)cond,
@@ -5460,8 +5851,15 @@
NULL, (Word*)&signalling_seg, (Word)cond );
if (found) {
tl_assert(is_sane_Segment(signalling_seg));
+ tl_assert(new_seg->prev);
+ tl_assert(new_seg->prev->vts);
new_seg->other = signalling_seg;
new_seg->other_hint = 's';
+ tl_assert(new_seg->other->vts);
+ new_seg->vts = tickL_and_joinR_VTS(
+ new_seg->thr,
+ new_seg->prev->vts,
+ new_seg->other->vts );
} else {
/* Hmm. How can a wait on 'cond' succeed if nobody signalled
it? If this happened it would surely be a bug in the
@@ -5721,6 +6119,8 @@
tl_assert( is_sane_Segment(new_seg) );
tl_assert( new_seg->thr == thr );
tl_assert( is_sane_Segment(new_seg->prev) );
+ tl_assert( new_seg->prev->vts );
+ new_seg->vts = tick_VTS( new_seg->thr, new_seg->prev->vts );
/* ... and add the binding. */
push_Segment_for_sem( sem, new_seg->prev );
@@ -5764,8 +6164,15 @@
posting_seg = mb_pop_Segment_for_sem( sem );
if (posting_seg) {
tl_assert(is_sane_Segment(posting_seg));
+ tl_assert(new_seg->prev);
+ tl_assert(new_seg->prev->vts);
new_seg->other = posting_seg;
new_seg->other_hint = 'S';
+ tl_assert(new_seg->other->vts);
+ new_seg->vts = tickL_and_joinR_VTS(
+ new_seg->thr,
+ new_seg->prev->vts,
+ new_seg->other->vts );
} else {
/* Hmm. How can a wait on 'sem' succeed if nobody posted to
it? If this happened it would surely be a bug in the
|
|
From: Tom H. <th...@cy...> - 2007-10-25 02:31:20
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2007-10-25 03:15:02 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 260 tests, 27 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-25 02:23:59
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2007-10-25 03:05:09 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-25 02:23:32
|
Nightly build on dellow ( x86_64, Fedora 7 ) started at 2007-10-25 03:10:04 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 293 tests, 4 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2007-10-25 02:15:52
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2007-10-25 03:00:03 BST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 295 tests, 6 stderr failures, 1 stdout failure, 0 posttest failures == memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |
|
From: <js...@ac...> - 2007-10-25 00:16:51
|
Nightly build on g5 ( SuSE 10.1, ppc970 ) started at 2007-10-25 02:00:01 CEST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 228 tests, 6 stderr failures, 2 stdout failures, 0 posttest failures == memcheck/tests/deep_templates (stdout) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/pointer-trace (stderr) none/tests/faultstatus (stderr) none/tests/fdleak_cmsg (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) |