1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of drd, a thread error detector. 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>. 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_clientobj.h" 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_hb.h" 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_error.h" 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_errormgr.h" /* VG_(maybe_record_error)() */ 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcassert.h" /* tl_assert() */ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcprint.h" /* VG_(printf)() */ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_machine.h" /* VG_(get_IP)() */ 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_mallocfree.h" /* VG_(malloc)(), VG_(free)()*/ 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_threadstate.h" /* VG_(get_running_tid)() */ 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Type definitions. */ 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** Per-thread hb information. */ 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct hb_thread_info 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tid; // A DrdThreadId declared as UWord because 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // this member variable is the key of an OSet. 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Segment* sg; // Segment created before most recent 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // ANNOTATE_HAPPENS_BEFORE(). 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Local functions. */ 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(hb_cleanup)(struct hb_info* p); 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Local variables. */ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool DRD_(s_trace_hb); 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Function definitions. */ 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_set_trace)(const Bool trace_hb) 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(s_trace_hb) = trace_hb; 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Initialize the structure *p with the specified thread ID. 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_thread_initialize)(struct hb_thread_info* const p, 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const DrdThreadId tid) 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p->tid = tid; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p->sg = 0; 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Deallocate the memory that is owned by members of struct hb_thread_info. 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(hb_thread_destroy)(struct hb_thread_info* const p) 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(p); 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(sg_put)(p->sg); 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_initialize)(struct hb_info* const p, const Addr hb) 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(hb != 0); 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(p->a1 == hb); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(p->type == ClientHbvar); 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p->cleanup = (void(*)(DrdClientobj*))(DRD_(hb_cleanup)); 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p->delete_thread = 0; 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), "drd.hb", 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free)); 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Free the memory that was allocated by hb_initialize(). Called by 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * DRD_(clientobj_remove)(). 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(hb_cleanup)(struct hb_info* p) 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_thread_info* r; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(p); 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(OSetGen_ResetIter)(p->oset); 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; ) 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(hb_thread_destroy)(r); 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(OSetGen_Destroy)(p->oset); 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Report that the synchronization object at address 'addr' is of the 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * wrong type. 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void wrong_type(const Addr addr) 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GenericErrInfo gei = { 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .tid = DRD_(thread_get_running_tid)(), 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .addr = addr, 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown }; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)(VG_(get_running_tid)(), 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GenericErr, 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_IP)(VG_(get_running_tid)()), 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "wrong type of synchronization object", 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &gei); 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct hb_info* DRD_(hb_get_or_allocate)(const Addr hb) 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_info *p; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(offsetof(DrdClientobj, hb) == 0); 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = &(DRD_(clientobj_get)(hb, ClientHbvar)->hb); 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (p) 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return p; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(clientobj_present)(hb, hb + 1)) 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrong_type(hb); 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = &(DRD_(clientobj_add)(hb, ClientHbvar)->hb); 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(hb_initialize)(p, hb); 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return p; 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct hb_info* DRD_(hb_get)(const Addr hb) 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(offsetof(DrdClientobj, hb) == 0); 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return &(DRD_(clientobj_get)(hb, ClientHbvar)->hb); 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** Called because of a happens-before annotation. */ 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_happens_before)(const DrdThreadId tid, Addr const hb) 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const ThreadId vg_tid = VG_(get_running_tid)(); 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const DrdThreadId drd_tid = DRD_(VgThreadIdToDrdThreadId)(vg_tid); 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const UWord word_tid = tid; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_info* p; 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_thread_info* q; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = DRD_(hb_get_or_allocate)(hb); 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(s_trace_hb)) 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("[%d] happens_before 0x%lx", 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_get_running_tid)(), hb); 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!p) 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Allocate the per-thread data structure if necessary. */ 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown q = VG_(OSetGen_Lookup)(p->oset, &word_tid); 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!q) 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q)); 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(hb_thread_initialize)(q, tid); 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(OSetGen_Insert)(p->oset, q); 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q); 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Store a pointer to the latest segment of the current thread in the 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * per-thread data structure. 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_latest_segment)(&q->sg, tid); 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_new_segment)(drd_tid); 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** Called because of a happens-after annotation. */ 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_happens_after)(const DrdThreadId tid, const Addr hb) 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_info* p; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_thread_info* q; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VectorClock old_vc; 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = DRD_(hb_get_or_allocate)(hb); 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(s_trace_hb)) 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("[%d] happens_after 0x%lx", 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_get_running_tid)(), hb); 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!p) 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_new_segment)(tid); 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Combine all vector clocks that were stored because of happens-before 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * annotations with the vector clock of the current thread. 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(tid)); 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(OSetGen_ResetIter)(p->oset); 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for ( ; (q = VG_(OSetGen_Next)(p->oset)) != 0; ) 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (q->tid != tid) 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(q->sg); 220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(vc_combine)(DRD_(thread_get_vc)(tid), &q->sg->vc); 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_update_conflict_set)(tid, &old_vc); 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(vc_cleanup)(&old_vc); 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** Called because of a happens-done annotation. */ 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(hb_happens_done)(const DrdThreadId tid, const Addr hb) 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct hb_info* p; 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(s_trace_hb)) 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("[%d] happens_done 0x%lx", 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_get_running_tid)(), hb); 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = DRD_(hb_get)(hb); 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!p) 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GenericErrInfo gei = { 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .tid = DRD_(thread_get_running_tid)(), 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .addr = hb, 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown }; 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)(VG_(get_running_tid)(), 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GenericErr, 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_IP)(VG_(get_running_tid)()), 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "missing happens-before annotation", 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &gei); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(clientobj_remove)(p->a1, ClientHbvar); 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 253