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
(6) |
2
(4) |
3
(4) |
4
(4) |
|
5
(6) |
6
(9) |
7
(4) |
8
(15) |
9
(6) |
10
(6) |
11
(22) |
|
12
(12) |
13
(9) |
14
(4) |
15
(11) |
16
(8) |
17
(4) |
18
(6) |
|
19
(6) |
20
(15) |
21
(9) |
22
(9) |
23
(14) |
24
(7) |
25
(7) |
|
26
(8) |
27
(11) |
28
(4) |
29
(4) |
30
(12) |
31
(7) |
|
|
From: <sv...@va...> - 2008-10-11 23:32:42
|
Author: sewardj
Date: 2008-10-12 00:32:26 +0100 (Sun, 12 Oct 2008)
New Revision: 8664
Log:
Speedups to the conflicting-access mechanism:
* keep reference-counted execution contexts (RCECs) in a
hash table instead of an OSet
* don't use eager freeing of RCECs when their ref count falls
to zero. This just creates a lot of pointless malloc/free
activity. Instead, let their rcs fall to zero, possibly
to be pulled back up later; and only delete those with zero
RC in event_map_maybe_GC(), when doing a collection.
* use unboxed address comparisons on OldRef structures.
Modified:
branches/YARD/helgrind/libhb_core.c
Modified: branches/YARD/helgrind/libhb_core.c
===================================================================
--- branches/YARD/helgrind/libhb_core.c 2008-10-11 19:37:45 UTC (rev 8663)
+++ branches/YARD/helgrind/libhb_core.c 2008-10-11 23:32:26 UTC (rev 8664)
@@ -2561,20 +2561,42 @@
ordering on the stack trace vectors.
2. An OSet of OldRefs. These store information about each old ref
- that we need to record. It is indexed by address (of the
- location for which the information is recorded), and contains a
- pointer to a RCEC in (1). Each OldRef also contains a
- generation number, indicating when it was most recently
- accessed.
+ that we need to record. It is indexed by address of the
+ location for which the information is recorded. For LRU
+ purposes, each OldRef also contains a generation number,
+ indicating when it was most recently accessed.
- When we this set becomes too big, we can throw away the subset
- of this set whose generation numbers are below some threshold;
- hence doing approximate LRU discarding. For each discarded
- OldRef we must of course decrement the reference count on the
- ECEC it refers to, in order that entries from (1) eventually get
+ The important part of an OldRef is, however, its accs[] array.
+ This is an array of N_OLDREF_ACCS pairs of Thr and a RCEC. This
+ allows us to collect the last access-traceback by up to
+ N_OLDREF_ACCS different threads for this location. The accs[]
+ array is a MTF-array. If a pair falls off the end, that's too
+ bad -- we will lose info about that thread's access to this
+ location.
+
+ When this OSet becomes too big, we can throw away the entries
+ whose generation numbers are below some threshold; hence doing
+ approximate LRU discarding. For each discarded OldRef we must
+ of course decrement the reference count on the all RCECs it
+ refers to, in order that entries from (1) eventually get
discarded too.
*/
+
+static UWord stats__ctxt_rcdec1 = 0;
+static UWord stats__ctxt_rcdec2 = 0;
+static UWord stats__ctxt_rcdec3 = 0;
+static UWord stats__ctxt_rcdec_calls = 0;
+static UWord stats__ctxt_rcdec_discards = 0;
+static UWord stats__ctxt_rcdec1_eq = 0;
+
+static UWord stats__ctxt_tab_curr = 0;
+static UWord stats__ctxt_tab_max = 0;
+
+static UWord stats__ctxt_tab_qs = 0;
+static UWord stats__ctxt_tab_cmps = 0;
+
+
///////////////////////////////////////////////////////
//// Part (1): An OSet of RCECs
///
@@ -2584,8 +2606,12 @@
// (UInt) `echo "Reference Counted Execution Context" | md5sum`
#define RCEC_MAGIC 0xab88abb2UL
+//#define N_RCEC_TAB 98317 /* prime */
+#define N_RCEC_TAB 196613 /* prime */
+
typedef
- struct {
+ struct _RCEC {
+ struct _RCEC* next;
UWord magic;
UWord rc;
UWord rcX; /* used for crosschecking */
@@ -2593,7 +2619,7 @@
}
RCEC;
-static OSet* contextTree = NULL; /* OSet* of RCEC */
+static RCEC** contextTab = NULL; /* hash table of RCEC*s */
/* Gives an arbitrary total order on RCEC .frames fields */
@@ -2611,20 +2637,13 @@
}
-/* Dec the ref of this EC_RC, and if it becomes zero,
- delete it from the contextTree. */
+/* Dec the ref of this RCEC. */
static void ctxt__rcdec ( RCEC* ec )
{
+ stats__ctxt_rcdec_calls++;
tl_assert(ec && ec->magic == RCEC_MAGIC);
tl_assert(ec->rc > 0);
ec->rc--;
- if (ec->rc == 0) {
- void* nd = VG_(OSetGen_Remove)( contextTree, ec );
- tl_assert(nd); /* must be in the tree */
- tl_assert(nd == ec);
- tl_assert( ((RCEC*)nd)->magic == RCEC_MAGIC );
- VG_(OSetGen_FreeNode)( contextTree, nd );
- }
}
static void ctxt__rcinc ( RCEC* ec )
@@ -2633,6 +2652,50 @@
ec->rc++;
}
+
+/* Find 'ec' in the RCEC list whose head pointer lives at 'headp' and
+ move it one step closer the the front of the list, so as to make
+ subsequent searches for it cheaper. */
+static void move_RCEC_one_step_forward ( RCEC** headp, RCEC* ec )
+{
+ RCEC *ec0, *ec1, *ec2;
+ if (ec == *headp)
+ tl_assert(0); /* already at head of list */
+ tl_assert(ec != NULL);
+ ec0 = *headp;
+ ec1 = NULL;
+ ec2 = NULL;
+ while (True) {
+ if (ec0 == NULL || ec0 == ec) break;
+ ec2 = ec1;
+ ec1 = ec0;
+ ec0 = ec0->next;
+ }
+ tl_assert(ec0 == ec);
+ if (ec0 != NULL && ec1 != NULL && ec2 != NULL) {
+ RCEC* tmp;
+ /* ec0 points to ec, ec1 to its predecessor, and ec2 to ec1's
+ predecessor. Swap ec0 and ec1, that is, move ec0 one step
+ closer to the start of the list. */
+ tl_assert(ec2->next == ec1);
+ tl_assert(ec1->next == ec0);
+ tmp = ec0->next;
+ ec2->next = ec0;
+ ec0->next = ec1;
+ ec1->next = tmp;
+ }
+ else
+ if (ec0 != NULL && ec1 != NULL && ec2 == NULL) {
+ /* it's second in the list. */
+ tl_assert(*headp == ec1);
+ tl_assert(ec1->next == ec0);
+ ec1->next = ec0->next;
+ ec0->next = ec1;
+ *headp = ec0;
+ }
+}
+
+
/* Find the given RCEC in the tree, and return a pointer to it. Or,
if not present, add the given one to the tree (by making a copy of
it, so the caller can immediately deallocate the original) and
@@ -2640,19 +2703,42 @@
on its stack, since we will always return a pointer to a copy of
it, not to the original. Note that the inserted node will have .rc
of zero and so the caller must immediatly increment it. */
+__attribute__((noinline))
static RCEC* ctxt__find_or_add ( RCEC* example )
{
+ UWord hent;
RCEC* copy;
tl_assert(example && example->magic == RCEC_MAGIC);
tl_assert(example->rc == 0);
- copy = VG_(OSetGen_Lookup)( contextTree, example );
+
+ /* Search the hash table to see if we already have it. */
+ stats__ctxt_tab_qs++;
+ hent = example->frames[0] % N_RCEC_TAB;
+ copy = contextTab[hent];
+ while (1) {
+ if (!copy) break;
+ tl_assert(copy->magic == RCEC_MAGIC);
+ stats__ctxt_tab_cmps++;
+ if (0 == RCEC__cmp_by_frames(copy, example)) break;
+ copy = copy->next;
+ }
+
if (copy) {
tl_assert(copy != example);
+ /* optimisation: if it's not at the head of its list, move 1
+ step fwds, to make future searches cheaper */
+ if (copy != contextTab[hent]) {
+ move_RCEC_one_step_forward( &contextTab[hent], copy );
+ }
} else {
- copy = VG_(OSetGen_AllocNode)( contextTree, sizeof(RCEC) );
+ copy = HG_(zalloc)( "libhb.cfoa.1", sizeof(RCEC) );
tl_assert(copy != example);
*copy = *example;
- VG_(OSetGen_Insert)( contextTree, copy );
+ copy->next = contextTab[hent];
+ contextTab[hent] = copy;
+ stats__ctxt_tab_curr++;
+ if (stats__ctxt_tab_curr > stats__ctxt_tab_max)
+ stats__ctxt_tab_max = stats__ctxt_tab_curr;
}
return copy;
}
@@ -2664,6 +2750,7 @@
return w;
}
+__attribute__((noinline))
static RCEC* get_RCEC ( Thr* thr )
{
UWord hash, i;
@@ -2694,9 +2781,9 @@
typedef
struct {
+ Addr ea;
UWord magic;
UWord gen; /* when most recently accessed */
- Addr ea;
/* unused slots in this array have .thr == NULL */
Thr_n_RCEC accs[N_OLDREF_ACCS];
}
@@ -2748,7 +2835,9 @@
i--;
}
here = get_RCEC( thr );
+ if (here == ref->accs[i].rcec) stats__ctxt_rcdec1_eq++;
ctxt__rcinc( here );
+ stats__ctxt_rcdec1++;
ctxt__rcdec( ref->accs[i].rcec );
ref->accs[i].rcec = here;
tl_assert(ref->accs[i].thr == thr);
@@ -2761,6 +2850,7 @@
/* the last slot is in use. We must dec the rc on the
associated rcec. */
tl_assert(ref->accs[N_OLDREF_ACCS-1].rcec);
+ stats__ctxt_rcdec2++;
ctxt__rcdec(ref->accs[N_OLDREF_ACCS-1].rcec);
} else {
tl_assert(!ref->accs[N_OLDREF_ACCS-1].rcec);
@@ -2850,19 +2940,19 @@
static void event_map_init ( void )
{
- tl_assert(!contextTree);
- contextTree = VG_(OSetGen_Create)(
- 0,
- (Word(*)(const void *, const void*))RCEC__cmp_by_frames,
- HG_(zalloc), "libhb.event_map_init.1 (context tree)",
- HG_(free)
- );
- tl_assert(contextTree);
+ Word i;
+ tl_assert(!contextTab);
+ contextTab = HG_(zalloc)( "libhb.event_map_init.1 (context table)",
+ N_RCEC_TAB * sizeof(RCEC*) );
+ tl_assert(contextTab);
+ for (i = 0; i < N_RCEC_TAB; i++)
+ contextTab[i] = NULL;
tl_assert(!oldrefTree);
+ tl_assert(offsetof(OldRef,ea) == 0); /* prereq for unboxed cmps */
oldrefTree = VG_(OSetGen_Create)(
- 0,
- (Word(*)(const void *, const void*))OldRef__cmp_by_EA,
+ offsetof(OldRef,ea), /* == 0 */
+ NULL, /* use unboxed cmp on OldRefs */
HG_(zalloc), "libhb.event_map_init.2 (oldref tree)",
HG_(free)
);
@@ -2873,20 +2963,33 @@
oldrefTreeN = 0;
}
-static void event_map__check_reference_counts ( void )
+static void event_map__check_reference_counts ( Bool before )
{
RCEC* rcec;
OldRef* oldref;
Word i;
+ UWord nEnts = 0;
- /* Set the 'check' reference counts to zero */
- VG_(OSetGen_ResetIter)( contextTree );
- while ( (rcec = VG_(OSetGen_Next)( contextTree )) ) {
- tl_assert(rcec->magic == RCEC_MAGIC);
- tl_assert(rcec->rc > 0); /* unrefd nodes should be immediately rm'd */
- rcec->rcX = 0;
+ /* Set the 'check' reference counts to zero. Also, optionally
+ check that the real reference counts are non-zero. We allow
+ these to fall to zero before a GC, but the GC must get rid of
+ all those that are zero, hence none should be zero after a
+ GC. */
+ for (i = 0; i < N_RCEC_TAB; i++) {
+ for (rcec = contextTab[i]; rcec; rcec = rcec->next) {
+ nEnts++;
+ tl_assert(rcec);
+ tl_assert(rcec->magic == RCEC_MAGIC);
+ if (!before)
+ tl_assert(rcec->rc > 0);
+ rcec->rcX = 0;
+ }
}
+ /* check that the stats are sane */
+ tl_assert(nEnts == stats__ctxt_tab_curr);
+ tl_assert(stats__ctxt_tab_curr <= stats__ctxt_tab_max);
+
/* visit all the referencing points, inc check ref counts */
VG_(OSetGen_ResetIter)( oldrefTree );
while ( (oldref = VG_(OSetGen_Next)( oldrefTree )) ) {
@@ -2903,9 +3006,10 @@
}
/* compare check ref counts with actual */
- VG_(OSetGen_ResetIter)( contextTree );
- while ( (rcec = VG_(OSetGen_Next)( contextTree )) ) {
- tl_assert(rcec->rc == rcec->rcX);
+ for (i = 0; i < N_RCEC_TAB; i++) {
+ for (rcec = contextTab[i]; rcec; rcec = rcec->next) {
+ tl_assert(rcec->rc == rcec->rcX);
+ }
}
}
@@ -2927,7 +3031,7 @@
tl_assert(oldrefTreeN == (UWord) VG_(OSetGen_Size)( oldrefTree ));
/* Check the reference counts */
- event_map__check_reference_counts();
+ event_map__check_reference_counts( True/*before*/ );
/* Compute the distribution of generation values in the ref tree */
/* genMap :: generation-number -> count-of-nodes-with-that-number */
@@ -3006,6 +3110,7 @@
for (j = 0; j < N_OLDREF_ACCS; j++) {
if (ref->accs[j].rcec) {
tl_assert(ref->accs[j].thr);
+ stats__ctxt_rcdec3++;
ctxt__rcdec( ref->accs[j].rcec );
} else {
tl_assert(!ref->accs[j].thr);
@@ -3022,12 +3127,30 @@
oldrefTreeN = retained;
oldrefGenIncAt = oldrefTreeN; /* start new gen right away */
+ /* Throw away all RCECs with zero reference counts */
+ for (i = 0; i < N_RCEC_TAB; i++) {
+ RCEC** pp = &contextTab[i];
+ RCEC* p = *pp;
+ while (p) {
+ if (p->rc == 0) {
+ *pp = p->next;
+ HG_(free)(p);
+ p = *pp;
+ tl_assert(stats__ctxt_tab_curr > 0);
+ stats__ctxt_tab_curr--;
+ } else {
+ pp = &p->next;
+ p = p->next;
+ }
+ }
+ }
+
/* Check the reference counts */
- event_map__check_reference_counts();
+ event_map__check_reference_counts( False/*after*/ );
- if (0)
- VG_(printf)("XXXX final sizes: oldrefTree %ld, contextTree %ld\n\n",
- VG_(OSetGen_Size)(oldrefTree), VG_(OSetGen_Size)(contextTree));
+ //if (0)
+ //VG_(printf)("XXXX final sizes: oldrefTree %ld, contextTree %ld\n\n",
+ // VG_(OSetGen_Size)(oldrefTree), VG_(OSetGen_Size)(contextTree));
}
@@ -4203,9 +4326,20 @@
);
VG_(printf)( " libhb: %lu entries in vts_set\n",
VG_(sizeFM)( vts_set ) );
- //VG_(printf)( " libhb: %lu entries in event_map\n",
- // HG_(sizeFM)( event_map ) );
+ VG_(printf)("%s","\n");
+ VG_(printf)( " libhb: ctxt__rcdec: 1=%lu(%lu eq), 2=%lu, 3=%lu\n",
+ stats__ctxt_rcdec1, stats__ctxt_rcdec1_eq,
+ stats__ctxt_rcdec2,
+ stats__ctxt_rcdec3 );
+ VG_(printf)( " libhb: ctxt__rcdec: calls %lu, discards %lu\n",
+ stats__ctxt_rcdec_calls, stats__ctxt_rcdec_discards);
+ VG_(printf)( " libhb: contextTab: %lu slots, %lu max ents\n",
+ (UWord)N_RCEC_TAB,
+ stats__ctxt_tab_curr );
+ VG_(printf)( " libhb: contextTab: %lu queries, %lu cmps\n",
+ stats__ctxt_tab_qs,
+ stats__ctxt_tab_cmps );
#if 0
VG_(printf)("sizeof(AvlNode) = %lu\n", sizeof(AvlNode));
VG_(printf)("sizeof(WordBag) = %lu\n", sizeof(WordBag));
|
|
From: Sérgio D. J. <ser...@li...> - 2008-10-11 22:13:31
|
Hello Julian, On Sat, 2008-10-11 at 11:33 +0200, Julian Seward wrote: > Another thing you might want to do is try the "YARD" branch Helgrind > with those files. It has a lower false error rate and better error > messages than the trunk or 3.3.1 Helgrind, in that it shows you > tracebacks for both memory accesses involved in a race. It may also > behave better on ppc (maybe; am not sure about that). > > svn co svn://svn.valgrind.org/valgrind/branches/YARD yard > cd yard > ./autogen.sh > > then configure/build as usual. Well, I'll try that branch as well. But IMHO the main "problem" with both Helgrind and DRD is that you have to recompile GCC in order to get things working. That's why I want to understand what's currently "wrong" with GCC and OpenMP nowadays (specially regarding the sys_futex() syscall), and what can be done to get Helgrind/DRD working with default GCC versions that are usually shipped today. I've already sent an e-mail to Bart asking more details about this issue. > > By the way, is there an IRC channel or something where I can get in > > touch with you, guys? I've tried #valgrind on Freenode, but apparently > > it's not even registered. > > Er, no. We've never had an irc channel. Hmm, and with all respect, don't you think it's time to set it up? :-) BTW, thank you very much for your answers. Regards, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil |
|
From: Sérgio D. J. <ser...@li...> - 2008-10-11 22:06:34
|
Hi Bart, On Sat, 2008-10-11 at 21:40 +0200, Bart Van Assche wrote: > The above race report refers to stdout. glibc uses its own locking > mechanism for streams (see also _IO_flockfile(FILE*) in the glibc > source tree). Some of these races were already suppressed by drd, but > not all. This has been fixed (trunk, revision 8663). Thanks for > reporting this. Thanks. I've updated my local copy of the repository and am the tests again. I'll let you know if there's something strange happening. Meanwhile, I'd like to ask a question about the limitations of Valgrind when libgomp uses sys_futex() to make the barrier implementation. I've tried to investigate and understand more about this subject, but unfortunately it seems a little Valgrind-specific (and I'm still new on this field). I've found the following thread discussion involving you and Julian: http://www.mail-archive.com/val...@li.../msg02349.html So, could you explain a little more why do I have to recompile gcc using the --disable-linux-futex parameter? Best regards, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil |
|
From: Bart V. A. <bar...@gm...> - 2008-10-11 19:40:54
|
On Fri, Oct 10, 2008 at 8:52 PM, Sérgio Durigan Júnior <ser...@li...> wrote: > However, DRD reported some errors regarding printf() function. > One of these errors is pasted below: > > ==31740== Conflicting load by thread 2/2 at 0x041930b8 size 4 > ==31740== at 0x40A1C2D: vfprintf (in /lib/libc-2.6.1.so) > ==31740== by 0x40AA9F2: printf (in /lib/libc-2.6.1.so) > ==31740== by 0x80487F5: main.omp_fn.0 (omp_bug5fix.c:39) > ==31740== by 0x402E7E7: gomp_thread_start (team.c:108) > ==31740== by 0x402651E: vg_thread_wrapper > (drd_pthread_intercepts.c:189) > ==31740== by 0x405418A: start_thread (in /lib/libpthread-2.6.1.so) > ==31740== by 0x412709D: clone (in /lib/libc-2.6.1.so) > ==31740== Allocation context: BSS section of /lib/libc-2.6.1.so The above race report refers to stdout. glibc uses its own locking mechanism for streams (see also _IO_flockfile(FILE*) in the glibc source tree). Some of these races were already suppressed by drd, but not all. This has been fixed (trunk, revision 8663). Thanks for reporting this. Bart. |
|
From: <sv...@va...> - 2008-10-11 19:37:52
|
Author: bart
Date: 2008-10-11 20:37:45 +0100 (Sat, 11 Oct 2008)
New Revision: 8663
Log:
Added yet another suppression pattern.
Modified:
trunk/glibc-2.X-drd.supp
Modified: trunk/glibc-2.X-drd.supp
===================================================================
--- trunk/glibc-2.X-drd.supp 2008-10-11 19:25:18 UTC (rev 8662)
+++ trunk/glibc-2.X-drd.supp 2008-10-11 19:37:45 UTC (rev 8663)
@@ -75,6 +75,17 @@
obj:/lib*/libc-*
}
{
+ libc-exit-io-cleanup
+ drd:ConflictingAccess
+ obj:/lib*/libc-*.so
+ obj:/lib*/libc-*.so
+ obj:/lib*/libc-*.so
+ obj:/lib*/libc-*.so
+ obj:/lib*/libc-*.so
+ obj:/lib*/libc-*.so
+ fun:exit
+}
+{
librt
drd:ConflictingAccess
fun:__librt_enable_asynccancel
|
|
From: <sv...@va...> - 2008-10-11 19:25:26
|
Author: bart Date: 2008-10-11 20:25:18 +0100 (Sat, 11 Oct 2008) New Revision: 8662 Log: Removed #define _IO_MTSAFE_IO again. Modified: trunk/drd/drd_pthread_intercepts.c Modified: trunk/drd/drd_pthread_intercepts.c =================================================================== --- trunk/drd/drd_pthread_intercepts.c 2008-10-11 19:04:40 UTC (rev 8661) +++ trunk/drd/drd_pthread_intercepts.c 2008-10-11 19:25:18 UTC (rev 8662) @@ -44,7 +44,6 @@ // versions (2.3 or before). #ifndef _GNU_SOURCE #define _GNU_SOURCE -#define _IO_MTSAFE_IO #endif #include <assert.h> |
|
From: <sv...@va...> - 2008-10-11 19:04:52
|
Author: bart Date: 2008-10-11 20:04:40 +0100 (Sat, 11 Oct 2008) New Revision: 8661 Log: Removed inclusion of <bits/libc-lock.h>. Modified: trunk/drd/drd_pthread_intercepts.c Modified: trunk/drd/drd_pthread_intercepts.c =================================================================== --- trunk/drd/drd_pthread_intercepts.c 2008-10-11 18:47:54 UTC (rev 8660) +++ trunk/drd/drd_pthread_intercepts.c 2008-10-11 19:04:40 UTC (rev 8661) @@ -54,9 +54,6 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> // confstr() -#if defined(HAVE_BITS_LIBC_LOCK_H) -#include <bits/libc-lock.h> -#endif #include "config.h" #include "drd_clientreq.h" #include "pub_tool_redir.h" @@ -108,8 +105,8 @@ DRD_IGNORE_VAR(*stdout); DRD_IGNORE_VAR(*stderr); #if defined(HAVE_BITS_LIBC_LOCK_H) - DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stdout->_lock)); - DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stderr->_lock)); + DRD_IGNORE_VAR(*(pthread_mutex_t*)(stdout->_lock)); + DRD_IGNORE_VAR(*(pthread_mutex_t*)(stderr->_lock)); #endif } |
|
From: <sv...@va...> - 2008-10-11 18:48:02
|
Author: bart Date: 2008-10-11 19:47:54 +0100 (Sat, 11 Oct 2008) New Revision: 8660 Log: Make regression test output independent of the presence of glibc debug information. Modified: trunk/drd/tests/filter_stderr Modified: trunk/drd/tests/filter_stderr =================================================================== --- trunk/drd/tests/filter_stderr 2008-10-11 18:30:20 UTC (rev 8659) +++ trunk/drd/tests/filter_stderr 2008-10-11 18:47:54 UTC (rev 8660) @@ -14,10 +14,9 @@ -e "/^warning: evaluate_Dwarf3_Expr: unhandled DW_OP_.*/d" \ -e "s/, in frame #[0-9]* of thread /, in frame #? of thread /" \ -e "s/(tc20_verifywrap.c:261)/(tc20_verifywrap.c:262)/" \ --e "/^NOTE: This is an Experimental-Class Valgrind Tool.$/d" \ -e "/^Copyright (C) 2006-200., and GNU GPL'd, by Bart Van Assche.$/d" \ --e "s/\(pthread_create.c:[0-9]*\)/in libpthread-?.?.so/" \ --e "s:[A-Za-z_]* (in [^ ]*libpthread-[0-9.]*\.so):(within libpthread-?.?.so):" \ +-e "s/[A-Za-z_]* (pthread_create.c:[0-9]*)/(within libpthread-?.?.so)/" \ +-e "s/[A-Za-z_]* (in [^ ]*libpthread-[0-9.]*\.so)/(within libpthread-?.?.so)/" \ -e "s:(within /lib[0-9]*/ld-[0-9.]*\.so):(within ld-?.?.so):" \ -e "s/was held during [0-9][0-9]*/was held during .../" \ -e "s/ (\([a-zA-Z_]*\.c\):[0-9]*)/ (\1:?)/" \ |
|
From: <sv...@va...> - 2008-10-11 18:30:26
|
Author: bart
Date: 2008-10-11 19:30:20 +0100 (Sat, 11 Oct 2008)
New Revision: 8659
Log:
Added check for the include file <bits/libc-lock.h>
Modified:
trunk/configure.in
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2008-10-11 18:29:46 UTC (rev 8658)
+++ trunk/configure.in 2008-10-11 18:30:20 UTC (rev 8659)
@@ -1261,6 +1261,7 @@
AC_CHECK_HEADERS([ \
endian.h \
mqueue.h \
+ bits/libc-lock.h \
sys/endian.h \
sys/epoll.h \
sys/eventfd.h \
|
|
From: <sv...@va...> - 2008-10-11 18:29:56
|
Author: bart
Date: 2008-10-11 19:29:46 +0100 (Sat, 11 Oct 2008)
New Revision: 8658
Log:
Suppress race reports triggered by glibc's _IO_flockfile(FILE*) on stdout and stderr.
Modified:
trunk/drd/drd_pthread_intercepts.c
Modified: trunk/drd/drd_pthread_intercepts.c
===================================================================
--- trunk/drd/drd_pthread_intercepts.c 2008-10-11 18:28:34 UTC (rev 8657)
+++ trunk/drd/drd_pthread_intercepts.c 2008-10-11 18:29:46 UTC (rev 8658)
@@ -44,6 +44,7 @@
// versions (2.3 or before).
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
+#define _IO_MTSAFE_IO
#endif
#include <assert.h>
@@ -53,6 +54,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // confstr()
+#if defined(HAVE_BITS_LIBC_LOCK_H)
+#include <bits/libc-lock.h>
+#endif
#include "config.h"
#include "drd_clientreq.h"
#include "pub_tool_redir.h"
@@ -98,11 +102,15 @@
{
check_threading_library();
vg_set_main_thread_state();
- /* glibc up to and including version 2.7 triggers conflicting accesses */
+ /* glibc up to and including version 2.8 triggers conflicting accesses */
/* on stdout and stderr when sending output to one of these streams from */
/* more than one thread. Suppress data race reports on these objects. */
DRD_IGNORE_VAR(*stdout);
DRD_IGNORE_VAR(*stderr);
+#if defined(HAVE_BITS_LIBC_LOCK_H)
+ DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stdout->_lock));
+ DRD_IGNORE_VAR(*(__libc_lock_recursive_t*)(stderr->_lock));
+#endif
}
static MutexT pthread_to_drd_mutex_type(const int kind)
|
|
From: <sv...@va...> - 2008-10-11 18:28:41
|
Author: bart Date: 2008-10-11 19:28:34 +0100 (Sat, 11 Oct 2008) New Revision: 8657 Log: Increased gcc version to 4.3.2. Modified: trunk/drd/scripts/download-and-build-gcc Modified: trunk/drd/scripts/download-and-build-gcc =================================================================== --- trunk/drd/scripts/download-and-build-gcc 2008-10-11 18:28:12 UTC (rev 8656) +++ trunk/drd/scripts/download-and-build-gcc 2008-10-11 18:28:34 UTC (rev 8657) @@ -6,7 +6,7 @@ # are called gmp-devel and mpfr-devel. -GCC_VERSION=4.3.1 +GCC_VERSION=4.3.2 FSF_MIRROR=ftp://ftp.easynet.be/gnu SRCDIR=$HOME/software DOWNLOADS=$SRCDIR/downloads |
|
From: <sv...@va...> - 2008-10-11 18:28:20
|
Author: bart Date: 2008-10-11 19:28:12 +0100 (Sat, 11 Oct 2008) New Revision: 8656 Log: Added paragraph "Using the POSIX Threads API Effectively." Modified: trunk/drd/docs/drd-manual.xml Modified: trunk/drd/docs/drd-manual.xml =================================================================== --- trunk/drd/docs/drd-manual.xml 2008-10-11 18:04:52 UTC (rev 8655) +++ trunk/drd/docs/drd-manual.xml 2008-10-11 18:28:12 UTC (rev 8656) @@ -993,12 +993,12 @@ following to your shell startup script: </para> <programlisting><![CDATA[ -export LD_LIBRARY_PATH=~/gcc-4.3.1/lib64:~/gcc-4.3.1/lib: +export LD_LIBRARY_PATH=~/gcc-4.3.2/lib64:~/gcc-4.3.2/lib: ]]></programlisting> <para> As an example, the test OpenMP test program -<literal>drd/scripts/omp_matinv</literal> triggers a data race +<literal>drd/tests/omp_matinv</literal> triggers a data race when the option -r has been specified on the command line. The data race is triggered by the following code: </para> @@ -1046,7 +1046,7 @@ <para> Note: DRD reports errors on the <literal>libgomp</literal> library -included with gcc 4.2.0 up to and including 4.3.1. This might indicate +included with gcc 4.2.0 up to and including 4.3.2. This might indicate a race condition in the POSIX version of <literal>libgomp</literal>. </para> @@ -1238,6 +1238,165 @@ </sect1> +<sect1 id="drd-manual.Pthreads" xreflabel="Pthreads"> +<title>Using the POSIX Threads API Effectively</title> + +<sect2 id="drd-manual.mutex-types" xreflabel="mutex-types"> +<title>Mutex types</title> + +<para> +The Single UNIX Specification version two defines the following four +mutex types (see also the documentation of <ulink +url="http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_mutexattr_settype.html"><function>pthread_mutexattr_settype()</function></ulink>): +<itemizedlist> + <listitem> + <para> + <emphasis>normal</emphasis>, which means that no error checking + is performed, and that the mutex is non-recursive. + </para> + </listitem> + <listitem> + <para> + <emphasis>error checking</emphasis>, which means that the mutex + is non-recursive and that error checking is performed. + </para> + </listitem> + <listitem> + <para> + <emphasis>recursive</emphasis>, which means that a mutex may be + locked recursively. + </para> + </listitem> + <listitem> + <para> + <emphasis>default</emphasis>, which means that error checking + behavior is undefined, and that the behavior for recursive + locking is also undefined. Or: portable code must neither + trigger error conditions through the Pthreads API nor attempt to + lock a mutex of default type recursively. + </para> + </listitem> +</itemizedlist> +</para> + +<para> +In complex applications it is not always clear from beforehand which +mutex will be locked recursively and which mutex will not be locked +recursively. Attempts lock a non-recursive mutex recursively will +result in race conditions that are very hard to find without a thread +checking tool. So either use the error checking mutex type and +consistently check the return value of Pthread API mutex calls, or use +the recursive mutex type. +</para> + +</sect2> + +<sect2 id="drd-manual.condvar" xreflabel="condition-variables"> +<title>Condition variables</title> + +<para> +A condition variable allows one thread to wake up one or more other +threads. Condition variables are typically used to notify one or more +threads about state changes of shared data. Unfortunately it is very +easy to introduce race conditions by using condition variables as the +only means of state information propagation. A better approach is to +let threads poll for changes of a state variable that is protected by +a mutex, and to use condition variables only as a thread wakeup +mechanism. See also the source file +<computeroutput>drd/tests/monitor_example.cpp</computeroutput> for an +example of how to implement this concept in C++. The monitor concept +used in this example is a well known concept in computer science -- +see also Wikipedia for more information about the <ulink +url="http://en.wikipedia.org/wiki/Monitor_(synchronization)">monitor</ulink> +concept. +</para> + +</sect2> + +<sect2 id="drd-manual.pctw" xreflabel="pthread_cond_timedwait"> +<title>pthread_cond_timedwait() and timeouts</title> + +<para> +Historically the function +<function>pthread_cond_timedwait()</function> only allowed the +specification of an absolute timeout, that is a timeout independent of +the time when this function was called. However, almost every call to +this function expresses a relative timeout. This typically happens by +passing the sum of +<computeroutput>clock_gettime(CLOCK_REALTIME)</computeroutput> and a +relative timeout as the third argument. This approach is incorrect +since forward or backward clock adjustments by e.g. ntpd will affect +the timeout. A more reliable approach is as follows: +<itemizedlist> + <listitem> + <para> + When initializing a condition variable through + pthread_cond_init(), specify that the timeout of + pthread_cond_timedwait() will use the clock + <literal>CLOCK_MONOTONIC</literal> instead of + <literal>CLOCK_REALTIME</literal>. You can do this via + <computeroutput>pthread_condattr_setclock(..., + CLOCK_MONOTONIC)</computeroutput>. See also + <computeroutput>drd/tests/monitor_example.cpp</computeroutput> + for an example. + </para> + </listitem> + <listitem> + <para> + When calling <function>pthread_cond_timedwait()</function>, pass + the sum of + <computeroutput>clock_gettime(CLOCK_MONOTONIC)</computeroutput> + and a relative timeout as the third argument. + </para> + </listitem> +</itemizedlist> +</para> + +</sect2> + +<sect2 id="drd-manual.naming-threads" xreflabel="naming threads"> +<title>Assigning names to threads</title> + +<para> +Many applications log information about changes in internal or +external state to a file. When analyzing log files of a multithreaded +application it can be very convenient to know which thread logged +which information. One possible approach is to identify threads in +logging output by including the result of +<function>pthread_self()</function> in every log line. However, this approach +has two disadvantages: there is no direct relationship between these +values and the source code and these values can be different in each +run. A better approach is to assign a brief name to each thread and to +include the assigned thread name in each log line. One possible +approach for managing thread names is as follows: +<itemizedlist> + <listitem> + <para> + Allocate a key for the pointer to the thread name through + <function>pthread_key_create()</function>. + </para> + </listitem> + <listitem> + <para> + Just after thread creation, set the thread name through + <function>pthread_setspecific()</function>. + </para> + </listitem> + <listitem> + <para> + In the code that generates the logging information, query the thread + name by calling <function>pthread_getspecific()</function>. + </para> + </listitem> +</itemizedlist> + +</para> + +</sect2> + +</sect1> + + <sect1 id="drd-manual.limitations" xreflabel="Limitations"> <title>Limitations</title> |
|
From: <sv...@va...> - 2008-10-11 18:05:03
|
Author: bart
Date: 2008-10-11 19:04:52 +0100 (Sat, 11 Oct 2008)
New Revision: 8655
Log:
Added omp_printf regression test.
Added:
trunk/drd/tests/omp_printf.c
trunk/drd/tests/omp_printf.stderr.exp
trunk/drd/tests/omp_printf.vgtest
Modified:
trunk/drd/tests/
trunk/drd/tests/Makefile.am
Property changes on: trunk/drd/tests
___________________________________________________________________
Name: svn:ignore
- *.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
atomic_var
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
Makefile
Makefile.in
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
pth_barrier
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cond_race
pth_create_chain
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_spinlock
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
sem_as_mutex
sigalrm
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
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
trylock
vg_regtest.tmp*
+ *.stderr.diff*
*.stderr.out
*.stdout.diff*
*.stdout.out
.deps
atomic_var
drd_bitmap_test
fp_race
hg01_all_ok
hg02_deadlock
hg03_inherit
hg04_race
hg05_race2
hg06_readshared
hold_lock
linuxthreads_det
Makefile
Makefile.in
matinv
memory_allocation
monitor_example
new_delete
omp_matinv
omp_prime
omp_printf
pth_barrier
pth_barrier_reinit
pth_broadcast
pth_cancel_locked
pth_cond_race
pth_create_chain
pth_detached
pth_detached_sem
pth_inconsistent_cond_wait
pth_spinlock
qt4_mutex
qt4_rwlock
qt4_semaphore
recursive_mutex
rwlock_race
rwlock_test
sem_as_mutex
sigalrm
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
tc11_XCHG
tc12_rwl_trivial
tc13_laog1
tc15_laog_lockdel
tc16_byterace
tc17_sembar
tc18_semabuse
tc19_shadowmem
tc20_verifywrap
tc21_pthonce
tc22_exit_w_lock
tc23_bogus_condwait
tc24_nonzero_sem
trylock
vg_regtest.tmp*
Modified: trunk/drd/tests/Makefile.am
===================================================================
--- trunk/drd/tests/Makefile.am 2008-10-11 18:03:27 UTC (rev 8654)
+++ trunk/drd/tests/Makefile.am 2008-10-11 18:04:52 UTC (rev 8655)
@@ -66,6 +66,8 @@
omp_matinv_racy.vgtest \
omp_prime_racy.stderr.exp \
omp_prime_racy.vgtest \
+ omp_printf.stderr.exp \
+ omp_printf.vgtest \
pth_barrier.stderr.exp \
pth_barrier.vgtest \
pth_barrier2.stderr.exp \
@@ -250,7 +252,7 @@
endif
if HAVE_OPENMP
-check_PROGRAMS += omp_matinv omp_prime
+check_PROGRAMS += omp_matinv omp_prime omp_printf
endif
@@ -440,4 +442,9 @@
omp_prime_CFLAGS = $(AM_CFLAGS) -fopenmp
omp_prime_LDFLAGS = -fopenmp
omp_prime_LDADD = -lm
+
+omp_printf_SOURCES = omp_printf.c
+omp_printf_CFLAGS = $(AM_CFLAGS) -fopenmp
+omp_printf_LDFLAGS = -fopenmp
+omp_printf_LDADD = -lm
endif
Added: trunk/drd/tests/omp_printf.c
===================================================================
--- trunk/drd/tests/omp_printf.c (rev 0)
+++ trunk/drd/tests/omp_printf.c 2008-10-11 18:04:52 UTC (rev 8655)
@@ -0,0 +1,50 @@
+/* Simple OpenMP test program that calls printf() from a parallel section. */
+
+#include <omp.h>
+#include <stdio.h>
+#include <unistd.h> // getopt()
+
+static void usage(const char* const exe)
+{
+ printf("Usage: %s [-h] [-q] [-r] [-t<n>] <m>\n"
+ "-h: display this information.\n"
+ "-q: quiet mode -- do not print computed error.\n",
+ exe);
+}
+
+int main(int argc, char** argv)
+{
+ int i;
+ int optchar;
+ int silent = 0;
+ int tid;
+
+ while ((optchar = getopt(argc, argv, "hq")) != EOF)
+ {
+ switch (optchar)
+ {
+ case 'h': usage(argv[0]); return 1;
+ case 'q': silent = 1; break;
+ default:
+ return 1;
+ }
+ }
+
+#pragma omp parallel private(tid)
+ for (i = 0; i < 2; i++)
+ {
+ tid = omp_get_thread_num();
+ if (! silent)
+ {
+ printf("omp_get_thread_num() = %d/%d\n", tid, omp_get_num_threads());
+ }
+ else
+ {
+ printf("%s", "");
+ }
+ }
+
+ fprintf(stderr, "Finished.\n");
+
+ return 0;
+}
Added: trunk/drd/tests/omp_printf.stderr.exp
===================================================================
--- trunk/drd/tests/omp_printf.stderr.exp (rev 0)
+++ trunk/drd/tests/omp_printf.stderr.exp 2008-10-11 18:04:52 UTC (rev 8655)
@@ -0,0 +1 @@
+ERROR SUMMARY: 8 errors from 8 contexts
Added: trunk/drd/tests/omp_printf.vgtest
===================================================================
--- trunk/drd/tests/omp_printf.vgtest (rev 0)
+++ trunk/drd/tests/omp_printf.vgtest 2008-10-11 18:04:52 UTC (rev 8655)
@@ -0,0 +1,5 @@
+prereq: ./run_openmp_test ./omp_printf
+prog: omp_printf
+vgopts: --check-stack-var=yes --var-info=yes
+args: -q
+stderr_filter: filter_error_summary
|
|
From: <sv...@va...> - 2008-10-11 18:03:35
|
Author: bart
Date: 2008-10-11 19:03:27 +0100 (Sat, 11 Oct 2008)
New Revision: 8654
Log:
Added command-line option -h.
Modified:
trunk/drd/tests/omp_matinv.c
Modified: trunk/drd/tests/omp_matinv.c
===================================================================
--- trunk/drd/tests/omp_matinv.c 2008-10-11 10:18:16 UTC (rev 8653)
+++ trunk/drd/tests/omp_matinv.c 2008-10-11 18:03:27 UTC (rev 8654)
@@ -272,6 +272,17 @@
return 2 * eps;
}
+static void usage(const char* const exe)
+{
+ printf("Usage: %s [-h] [-q] [-r] [-t<n>] <m>\n"
+ "-h: display this information.\n"
+ "-q: quiet mode -- do not print computed error.\n"
+ "-r: trigger a race condition.\n"
+ "-t<n>: use <n> threads.\n"
+ "<m>: matrix size.\n",
+ exe);
+}
+
int main(int argc, char** argv)
{
int matrix_size;
@@ -283,15 +294,15 @@
double error;
double ratio;
- while ((optchar = getopt(argc, argv, "qrt:")) != EOF)
+ while ((optchar = getopt(argc, argv, "hqrt:")) != EOF)
{
switch (optchar)
{
+ case 'h': usage(argv[0]); return 1;
case 'q': silent = 1; break;
case 'r': s_trigger_race = 1; break;
case 't': nthread = atoi(optarg); break;
default:
- fprintf(stderr, "Error: unknown option '%c'.\n", optchar);
return 1;
}
}
|
|
From: Julian S. <js...@ac...> - 2008-10-11 11:05:15
|
> > > What should I specifically do to get Helgrind working with OpenMP? > > > > See the attached files. Note that they are for valgrind-3.3.1. > > Thank you. I've tried to locate those files (or at least the README) in > the tar.bz2 package without success. Are they in some specific place, or > only you developers have them? :-) Just sitting around in my tree somewhere :-( A better solution would be to make Helgrind aware of the required GNU OpenMP primitives, so it supports GNU OpenMP directly, like drd. Another thing you might want to do is try the "YARD" branch Helgrind with those files. It has a lower false error rate and better error messages than the trunk or 3.3.1 Helgrind, in that it shows you tracebacks for both memory accesses involved in a race. It may also behave better on ppc (maybe; am not sure about that). svn co svn://svn.valgrind.org/valgrind/branches/YARD yard cd yard ./autogen.sh then configure/build as usual. > By the way, is there an IRC channel or something where I can get in > touch with you, guys? I've tried #valgrind on Freenode, but apparently > it's not even registered. Er, no. We've never had an irc channel. J |
|
From: <sv...@va...> - 2008-10-11 10:18:28
|
Author: sewardj
Date: 2008-10-11 11:18:16 +0100 (Sat, 11 Oct 2008)
New Revision: 8653
Log:
get_IntRegInfo(x86): handle missing %bh case (Jim Clause)
Modified:
trunk/exp-ptrcheck/h_main.c
Modified: trunk/exp-ptrcheck/h_main.c
===================================================================
--- trunk/exp-ptrcheck/h_main.c 2008-10-08 23:03:00 UTC (rev 8652)
+++ trunk/exp-ptrcheck/h_main.c 2008-10-11 10:18:16 UTC (rev 8653)
@@ -1258,7 +1258,7 @@
if (o == GOF(ECX) && is21) { o -= 0; goto contains_o; }
if (o == GOF(ECX)+1 && is21) { o -= 1; o -= 0; goto contains_o; }
if (o == GOF(EBX) && is21) { o -= 0; goto contains_o; }
- // bl case
+ if (o == GOF(EBX)+1 && is21) { o -= 1; o -= 0; goto contains_o; }
if (o == GOF(EDX) && is21) { o -= 0; goto contains_o; }
if (o == GOF(EDX)+1 && is21) { o -= 1; o -= 0; goto contains_o; }
if (o == GOF(ESI) && is21) { o -= 0; goto contains_o; }
|
|
From: <sv...@va...> - 2008-10-11 10:08:39
|
Author: sewardj
Date: 2008-10-11 11:07:55 +0100 (Sat, 11 Oct 2008)
New Revision: 1865
Log:
Support FPREM1 on amd64. Fixes #172563.
Modified:
trunk/priv/guest-amd64/toIR.c
trunk/priv/host-amd64/hdefs.c
trunk/priv/host-amd64/hdefs.h
trunk/priv/host-amd64/isel.c
Modified: trunk/priv/guest-amd64/toIR.c
===================================================================
--- trunk/priv/guest-amd64/toIR.c 2008-08-19 11:15:10 UTC (rev 1864)
+++ trunk/priv/guest-amd64/toIR.c 2008-10-11 10:07:55 UTC (rev 1865)
@@ -4937,19 +4937,27 @@
break;
}
-//.. case 0xF5: { /* FPREM1 -- IEEE compliant */
-//.. IRTemp a1 = newTemp(Ity_F64);
-//.. IRTemp a2 = newTemp(Ity_F64);
-//.. DIP("fprem1\n");
-//.. /* Do FPREM1 twice, once to get the remainder, and once
-//.. to get the C3210 flag values. */
-//.. assign( a1, get_ST(0) );
-//.. assign( a2, get_ST(1) );
-//.. put_ST_UNCHECKED(0, binop(Iop_PRem1F64,
-//.. mkexpr(a1), mkexpr(a2)));
-//.. put_C3210( binop(Iop_PRem1C3210F64, mkexpr(a1), mkexpr(a2)) );
-//.. break;
-//.. }
+ case 0xF5: { /* FPREM1 -- IEEE compliant */
+ IRTemp a1 = newTemp(Ity_F64);
+ IRTemp a2 = newTemp(Ity_F64);
+ DIP("fprem1\n");
+ /* Do FPREM1 twice, once to get the remainder, and once
+ to get the C3210 flag values. */
+ assign( a1, get_ST(0) );
+ assign( a2, get_ST(1) );
+ put_ST_UNCHECKED(0,
+ triop(Iop_PRem1F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),
+ mkexpr(a2)));
+ put_C3210(
+ unop(Iop_32Uto64,
+ triop(Iop_PRem1C3210F64,
+ get_FAKE_roundingmode(), /* XXXROUNDINGFIXME */
+ mkexpr(a1),
+ mkexpr(a2)) ));
+ break;
+ }
case 0xF7: /* FINCSTP */
DIP("fincstp\n");
Modified: trunk/priv/host-amd64/hdefs.c
===================================================================
--- trunk/priv/host-amd64/hdefs.c 2008-08-19 11:15:10 UTC (rev 1864)
+++ trunk/priv/host-amd64/hdefs.c 2008-10-11 10:07:55 UTC (rev 1865)
@@ -549,7 +549,7 @@
case Afp_YL2X: return "yl2x";
case Afp_YL2XP1: return "yl2xp1";
case Afp_PREM: return "prem";
-//.. case Xfp_PREM1: return "prem1";
+ case Afp_PREM1: return "prem1";
case Afp_SQRT: return "sqrt";
//.. case Xfp_ABS: return "abs";
//.. case Xfp_NEG: return "chs";
@@ -2885,6 +2885,7 @@
case Afp_YL2X: *p++ = 0xD9; *p++ = 0xF1; break;
case Afp_YL2XP1: *p++ = 0xD9; *p++ = 0xF9; break;
case Afp_PREM: *p++ = 0xD9; *p++ = 0xF8; break;
+ case Afp_PREM1: *p++ = 0xD9; *p++ = 0xF5; break;
default: goto bad;
}
goto done;
Modified: trunk/priv/host-amd64/hdefs.h
===================================================================
--- trunk/priv/host-amd64/hdefs.h 2008-08-19 11:15:10 UTC (rev 1864)
+++ trunk/priv/host-amd64/hdefs.h 2008-10-11 10:07:55 UTC (rev 1865)
@@ -307,7 +307,7 @@
enum {
Afp_INVALID,
/* Binary */
- Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM,
+ Afp_SCALE, Afp_ATAN, Afp_YL2X, Afp_YL2XP1, Afp_PREM, Afp_PREM1,
/* Unary */
Afp_SQRT,
Afp_SIN, Afp_COS, Afp_TAN,
Modified: trunk/priv/host-amd64/isel.c
===================================================================
--- trunk/priv/host-amd64/isel.c 2008-08-19 11:15:10 UTC (rev 1864)
+++ trunk/priv/host-amd64/isel.c 2008-10-11 10:07:55 UTC (rev 1865)
@@ -1761,7 +1761,8 @@
case Iex_Triop: {
/* C3210 flags following FPU partial remainder (fprem), both
IEEE compliant (PREM1) and non-IEEE compliant (PREM). */
- if (e->Iex.Triop.op == Iop_PRemC3210F64) {
+ if (e->Iex.Triop.op == Iop_PRemC3210F64
+ || e->Iex.Triop.op == Iop_PRem1C3210F64) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
@@ -1780,6 +1781,9 @@
case Iop_PRemC3210F64:
addInstr(env, AMD64Instr_A87FpOp(Afp_PREM));
break;
+ case Iop_PRem1C3210F64:
+ addInstr(env, AMD64Instr_A87FpOp(Afp_PREM1));
+ break;
default:
vassert(0);
}
@@ -2936,14 +2940,16 @@
|| e->Iex.Triop.op == Iop_AtanF64
|| e->Iex.Triop.op == Iop_Yl2xF64
|| e->Iex.Triop.op == Iop_Yl2xp1F64
- || e->Iex.Triop.op == Iop_PRemF64)
+ || e->Iex.Triop.op == Iop_PRemF64
+ || e->Iex.Triop.op == Iop_PRem1F64)
) {
AMD64AMode* m8_rsp = AMD64AMode_IR(-8, hregAMD64_RSP());
HReg arg1 = iselDblExpr(env, e->Iex.Triop.arg2);
HReg arg2 = iselDblExpr(env, e->Iex.Triop.arg3);
HReg dst = newVRegV(env);
Bool arg2first = toBool(e->Iex.Triop.op == Iop_ScaleF64
- || e->Iex.Triop.op == Iop_PRemF64);
+ || e->Iex.Triop.op == Iop_PRemF64
+ || e->Iex.Triop.op == Iop_PRem1F64);
addInstr(env, AMD64Instr_A87Free(2));
/* one arg -> top of x87 stack */
@@ -2975,6 +2981,9 @@
case Iop_PRemF64:
addInstr(env, AMD64Instr_A87FpOp(Afp_PREM));
break;
+ case Iop_PRem1F64:
+ addInstr(env, AMD64Instr_A87FpOp(Afp_PREM1));
+ break;
default:
vassert(0);
}
|
|
From: Julian S. <js...@ac...> - 2008-10-11 09:40:35
|
> I've written a tool that piggy backs onto of exp-ptrcheck and it seems
> to be working pretty well.
Sounds interesting. What does it do?
> if (o == GOF(EBX)+1 && is21) { o -= 1; o -= 0; goto contains_o; }
>
> and it seems to fix the crash. Does that look correct? or is there
> some other reason why this case was missing.
Yes, that looks right. I added those cases on-demand, so as to always
have at least one test example for each case (if you see what I mean)
and I guess this case never happened. It corresponds to an access to
the byte register %bh. Strange though, since I tested on some very
large applications.
J
|
|
From: Tom H. <th...@cy...> - 2008-10-11 03:28:11
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2008-10-11 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 == 366 tests, 80 stderr failures, 2 stdout failures, 29 post failures == exp-ptrcheck/tests/bad_percentify (stderr) exp-ptrcheck/tests/base (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/fp (stderr) exp-ptrcheck/tests/globalerr (stderr) exp-ptrcheck/tests/hackedbz2 (stderr) exp-ptrcheck/tests/hp_bounds (stderr) exp-ptrcheck/tests/hp_dangle (stderr) exp-ptrcheck/tests/justify (stderr) exp-ptrcheck/tests/partial_bad (stderr) exp-ptrcheck/tests/partial_good (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) exp-ptrcheck/tests/realloc (stderr) exp-ptrcheck/tests/stackerr (stderr) exp-ptrcheck/tests/strcpy (stderr) exp-ptrcheck/tests/supp (stderr) exp-ptrcheck/tests/tricky (stderr) exp-ptrcheck/tests/unaligned (stderr) exp-ptrcheck/tests/zero (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/hg06_readshared (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc02_simple_tls (stderr) helgrind/tests/tc03_re_excl (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc07_hbl1 (stderr) helgrind/tests/tc08_hbl2 (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc11_XCHG (stderr) helgrind/tests/tc12_rwl_trivial (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) helgrind/tests/tc24_nonzero_sem (stderr) massif/tests/alloc-fns-A (post) massif/tests/alloc-fns-B (post) massif/tests/basic (post) massif/tests/basic2 (post) massif/tests/big-alloc (post) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/custom_alloc (post) massif/tests/deep-A (post) massif/tests/deep-B (stderr) massif/tests/deep-B (post) massif/tests/deep-C (stderr) massif/tests/deep-C (post) massif/tests/deep-D (post) massif/tests/ignoring (post) massif/tests/insig (post) massif/tests/long-names (post) massif/tests/long-time (post) massif/tests/new-cpp (post) massif/tests/null (post) massif/tests/one (post) massif/tests/overloaded-new (post) massif/tests/peak (post) massif/tests/peak2 (stderr) massif/tests/peak2 (post) massif/tests/realloc (stderr) massif/tests/realloc (post) massif/tests/thresholds_0_0 (post) massif/tests/thresholds_0_10 (post) massif/tests/thresholds_10_0 (post) massif/tests/thresholds_10_10 (post) massif/tests/thresholds_5_0 (post) massif/tests/thresholds_5_10 (post) massif/tests/zero1 (post) massif/tests/zero2 (post) memcheck/tests/file_locking (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/origin1-yes (stderr) memcheck/tests/origin4-many (stderr) memcheck/tests/origin5-bz2 (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/varinfo1 (stderr) memcheck/tests/varinfo2 (stderr) memcheck/tests/varinfo3 (stderr) memcheck/tests/varinfo4 (stderr) memcheck/tests/varinfo5 (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/bug152022 (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/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) none/tests/shell (stderr) none/tests/shell_valid1 (stderr) none/tests/shell_valid2 (stderr) none/tests/shell_valid3 (stderr) |
|
From: Tom H. <th...@cy...> - 2008-10-11 03:05:44
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2008-10-11 03:05:08 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 == 460 tests, 11 stderr failures, 3 stdout failures, 0 post failures == exp-ptrcheck/tests/base (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) |
|
From: Tom H. <th...@cy...> - 2008-10-11 02:47:30
|
Nightly build on trojan ( x86_64, Fedora Core 6 ) started at 2008-10-11 03:25:09 BST Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 464 tests, 12 stderr failures, 5 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/bug133694 (stdout) memcheck/tests/x86/bug133694 (stderr) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/cmdline1 (stdout) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 464 tests, 13 stderr failures, 5 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/pth_create (stderr) exp-ptrcheck/tests/pth_specific (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/bug133694 (stdout) memcheck/tests/x86/bug133694 (stderr) memcheck/tests/x86/scalar (stderr) none/tests/blockfault (stderr) none/tests/cmdline1 (stdout) none/tests/cmdline2 (stdout) none/tests/mremap2 (stdout) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Sat Oct 11 03:36:18 2008 --- new.short Sat Oct 11 03:47:16 2008 *************** *** 8,10 **** ! == 464 tests, 13 stderr failures, 5 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) --- 8,10 ---- ! == 464 tests, 12 stderr failures, 5 stdout failures, 0 post failures == exp-ptrcheck/tests/ccc (stderr) *************** *** 12,14 **** exp-ptrcheck/tests/pth_specific (stderr) - helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc20_verifywrap (stderr) --- 12,13 ---- |
|
From: Tom H. <th...@cy...> - 2008-10-11 02:27:31
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2008-10-11 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 == 466 tests, 34 stderr failures, 4 stdout failures, 0 post failures == drd/tests/pth_cancel_locked (stderr) exp-ptrcheck/tests/ccc (stderr) exp-ptrcheck/tests/hackedbz2 (stderr) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) memcheck/tests/file_locking (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/origin5-bz2 (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/amd64/insn_ssse3 (stdout) none/tests/amd64/insn_ssse3 (stderr) none/tests/amd64/ssse3_misaligned (stderr) none/tests/blockfault (stderr) none/tests/cmdline2 (stdout) none/tests/fdleak_fcntl (stderr) none/tests/mremap2 (stdout) none/tests/x86/insn_ssse3 (stdout) none/tests/x86/insn_ssse3 (stderr) none/tests/x86/ssse3_misaligned (stderr) |