_VG_USERREQ__HG_CLIENTREQ_UNIMP, /* char* */
_VG_USERREQ__HG_USERSO_SEND_PRE, /* arbitrary UWord SO-tag */
_VG_USERREQ__HG_USERSO_RECV_POST, /* arbitrary UWord SO-tag */
- _VG_USERREQ__HG_RESERVED1, /* Do not use */
+ _VG_USERREQ__HG_USERSO_FORGET_ALL, /* arbitrary UWord SO-tag */
_VG_USERREQ__HG_RESERVED2, /* Do not use */
_VG_USERREQ__HG_RESERVED3, /* Do not use */
_VG_USERREQ__HG_RESERVED4, /* Do not use */
See also, extensive discussion on semantics of this in
https://bugs.kde.org/show_bug.cgi?id=243935
+
+ ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj) is interim until such time
+ as bug 243935 is fully resolved. It instructs Helgrind to forget
+ about any ANNOTATE_HAPPENS_BEFORE calls on the specified object, in
+ effect putting it back in its original state. Once in that state,
+ a use of ANNOTATE_HAPPENS_AFTER on it has no effect on the calling
+ thread.
+
+ An implementation may optionally release resources it has
+ associated with 'obj' when ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj)
+ happens. Users are recommended to use
+ ANNOTATE_HAPPENS_BEFORE_FORGET_ALL to indicate when a
+ synchronisation object is no longer needed, so as to avoid
+ potential indefinite resource leaks.
----------------------------------------------------------------
*/
#define ANNOTATE_HAPPENS_BEFORE(obj) \
#define ANNOTATE_HAPPENS_AFTER(obj) \
DO_CREQ_v_W(_VG_USERREQ__HG_USERSO_RECV_POST, void*,(obj))
+#define ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(obj) \
+ DO_CREQ_v_W(_VG_USERREQ__HG_USERSO_FORGET_ALL, void*,(obj))
/* ----------------------------------------------------------------
Memory publishing. The TSan sources say:
}
}
-// If it's ever needed (XXX check before use)
-//static void map_usertag_to_SO_delete ( UWord usertag ) {
-// UWord keyW, valW;
-// map_usertag_to_SO_INIT();
-// if (VG_(delFromFM)( map_usertag_to_SO, &keyW, &valW, usertag )) {
-// SO* so = (SO*)valW;
-// tl_assert(keyW == usertag);
-// tl_assert(so);
-// libhb_so_dealloc(so);
-// }
-//}
+static void map_usertag_to_SO_delete ( UWord usertag ) {
+ UWord keyW, valW;
+ map_usertag_to_SO_INIT();
+ if (VG_(delFromFM)( map_usertag_to_SO, &keyW, &valW, usertag )) {
+ SO* so = (SO*)valW;
+ tl_assert(keyW == usertag);
+ tl_assert(so);
+ libhb_so_dealloc(so);
+ }
+}
static
libhb_so_recv( thr->hbthr, so, True/*strong_recv*/ );
}
+static
+void evh__HG_USERSO_FORGET_ALL ( ThreadId tid, UWord usertag )
+{
+ /* TID declares that any happens-before edges notionally stored in
+ USERTAG can be deleted. If (as would normally be the case) a
+ SO is associated with USERTAG, then the assocation is removed
+ and all resources associated with SO are freed. Importantly,
+ that frees up any VTSs stored in SO. */
+ if (SHOW_EVENTS >= 1)
+ VG_(printf)("evh__HG_USERSO_FORGET_ALL(ctid=%d, usertag=%#lx)\n",
+ (Int)tid, usertag );
+
+ map_usertag_to_SO_delete( usertag );
+}
+
/*--------------------------------------------------------------*/
/*--- Lock acquisition order monitoring ---*/
evh__HG_USERSO_RECV_POST( tid, args[1] );
break;
+ case _VG_USERREQ__HG_USERSO_FORGET_ALL:
+ /* UWord arbitrary-SO-tag */
+ evh__HG_USERSO_FORGET_ALL( tid, args[1] );
+ break;
+
default:
/* Unhandled Helgrind client request! */
tl_assert2(0, "unhandled Helgrind client request 0x%lx",