drd_barrier.c revision 6bbefaf8418f3e225c4eefcc726b6874bef15d8c
18564292ac4b9adf51c45517cca2878732feb5bb4sewardj/* 28564292ac4b9adf51c45517cca2878732feb5bb4sewardj This file is part of drd, a data race detector. 38564292ac4b9adf51c45517cca2878732feb5bb4sewardj 48564292ac4b9adf51c45517cca2878732feb5bb4sewardj Copyright (C) 2006-2008 Bart Van Assche 58564292ac4b9adf51c45517cca2878732feb5bb4sewardj bart.vanassche@gmail.com 68564292ac4b9adf51c45517cca2878732feb5bb4sewardj 78564292ac4b9adf51c45517cca2878732feb5bb4sewardj This program is free software; you can redistribute it and/or 88564292ac4b9adf51c45517cca2878732feb5bb4sewardj modify it under the terms of the GNU General Public License as 98564292ac4b9adf51c45517cca2878732feb5bb4sewardj published by the Free Software Foundation; either version 2 of the 108564292ac4b9adf51c45517cca2878732feb5bb4sewardj License, or (at your option) any later version. 118564292ac4b9adf51c45517cca2878732feb5bb4sewardj 128564292ac4b9adf51c45517cca2878732feb5bb4sewardj This program is distributed in the hope that it will be useful, but 138564292ac4b9adf51c45517cca2878732feb5bb4sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 148564292ac4b9adf51c45517cca2878732feb5bb4sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 158564292ac4b9adf51c45517cca2878732feb5bb4sewardj General Public License for more details. 168564292ac4b9adf51c45517cca2878732feb5bb4sewardj 178564292ac4b9adf51c45517cca2878732feb5bb4sewardj You should have received a copy of the GNU General Public License 188564292ac4b9adf51c45517cca2878732feb5bb4sewardj along with this program; if not, write to the Free Software 198564292ac4b9adf51c45517cca2878732feb5bb4sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 208564292ac4b9adf51c45517cca2878732feb5bb4sewardj 02111-1307, USA. 218564292ac4b9adf51c45517cca2878732feb5bb4sewardj 228564292ac4b9adf51c45517cca2878732feb5bb4sewardj The GNU General Public License is contained in the file COPYING. 238564292ac4b9adf51c45517cca2878732feb5bb4sewardj*/ 248564292ac4b9adf51c45517cca2878732feb5bb4sewardj 258564292ac4b9adf51c45517cca2878732feb5bb4sewardj 268564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "drd_barrier.h" 2728230a3734e045791173aca660efc7d7aeef78cebart#include "drd_clientobj.h" 288564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "drd_error.h" 298564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "drd_suppression.h" 308564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "priv_drd_clientreq.h" 318564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_errormgr.h" // VG_(maybe_record_error)() 328564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_libcassert.h" // tl_assert() 338564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_libcprint.h" // VG_(printf)() 348564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_machine.h" // VG_(get_IP)() 358564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)() 368564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_oset.h" 378564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_threadstate.h" // VG_(get_running_tid)() 388564292ac4b9adf51c45517cca2878732feb5bb4sewardj 398564292ac4b9adf51c45517cca2878732feb5bb4sewardj 408564292ac4b9adf51c45517cca2878732feb5bb4sewardj// Type definitions. 418564292ac4b9adf51c45517cca2878732feb5bb4sewardj 428ddef8828240404bfcbd38651a53aa38be044ab6bart/** Information associated with one thread participating in a barrier. */ 43bebc5d668dc5a6df337011181debbf8d91c338e0bartstruct barrier_thread_info 44bebc5d668dc5a6df337011181debbf8d91c338e0bart{ 45bebc5d668dc5a6df337011181debbf8d91c338e0bart UWord tid; // A DrdThreadId 46bebc5d668dc5a6df337011181debbf8d91c338e0bart Word iteration; // iteration of last pthread_barrier_wait() 47bebc5d668dc5a6df337011181debbf8d91c338e0bart // call thread tid participated in. 48a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart Segment* sg[2]; // Segments of the last two 49bebc5d668dc5a6df337011181debbf8d91c338e0bart // pthread_barrier() calls by thread tid. 508564292ac4b9adf51c45517cca2878732feb5bb4sewardj}; 518564292ac4b9adf51c45517cca2878732feb5bb4sewardj 528564292ac4b9adf51c45517cca2878732feb5bb4sewardj 5328230a3734e045791173aca660efc7d7aeef78cebart// Local functions. 5428230a3734e045791173aca660efc7d7aeef78cebart 55306527d7413780873a05cf801c47f725fb60c310bartstatic void barrier_cleanup(struct barrier_info* p); 56306527d7413780873a05cf801c47f725fb60c310bartstatic const char* barrier_get_typename(struct barrier_info* const p); 57306527d7413780873a05cf801c47f725fb60c310bartstatic const char* barrier_type_name(const BarrierT bt); 5828230a3734e045791173aca660efc7d7aeef78cebart 5928230a3734e045791173aca660efc7d7aeef78cebart 608564292ac4b9adf51c45517cca2878732feb5bb4sewardj// Local variables. 618564292ac4b9adf51c45517cca2878732feb5bb4sewardj 628564292ac4b9adf51c45517cca2878732feb5bb4sewardjstatic Bool s_trace_barrier = False; 636bbefaf8418f3e225c4eefcc726b6874bef15d8cbartstatic ULong s_barrier_segment_creation_count; 648564292ac4b9adf51c45517cca2878732feb5bb4sewardj 658564292ac4b9adf51c45517cca2878732feb5bb4sewardj 668564292ac4b9adf51c45517cca2878732feb5bb4sewardj// Function definitions. 678564292ac4b9adf51c45517cca2878732feb5bb4sewardj 688564292ac4b9adf51c45517cca2878732feb5bb4sewardjvoid barrier_set_trace(const Bool trace_barrier) 698564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 708564292ac4b9adf51c45517cca2878732feb5bb4sewardj s_trace_barrier = trace_barrier; 718564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 728564292ac4b9adf51c45517cca2878732feb5bb4sewardj 73bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Initialize the structure *p with the specified thread ID and iteration 74bebc5d668dc5a6df337011181debbf8d91c338e0bart * information. */ 758564292ac4b9adf51c45517cca2878732feb5bb4sewardjstatic void barrier_thread_initialize(struct barrier_thread_info* const p, 768564292ac4b9adf51c45517cca2878732feb5bb4sewardj const DrdThreadId tid, 778564292ac4b9adf51c45517cca2878732feb5bb4sewardj const Word iteration) 788564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 798564292ac4b9adf51c45517cca2878732feb5bb4sewardj p->tid = tid; 808564292ac4b9adf51c45517cca2878732feb5bb4sewardj p->iteration = iteration; 81a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart p->sg[0] = 0; 82a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart p->sg[1] = 0; 838564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 848564292ac4b9adf51c45517cca2878732feb5bb4sewardj 85bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Deallocate the memory that was allocated in barrier_thread_initialize(). */ 868564292ac4b9adf51c45517cca2878732feb5bb4sewardjstatic void barrier_thread_destroy(struct barrier_thread_info* const p) 878564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 88a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart sg_put(p->sg[0]); 89a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart sg_put(p->sg[1]); 908564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 918564292ac4b9adf51c45517cca2878732feb5bb4sewardj 92bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Initialize the structure *p with the specified client-side barrier address, 93bebc5d668dc5a6df337011181debbf8d91c338e0bart * barrier object size and number of participants in each barrier. */ 948564292ac4b9adf51c45517cca2878732feb5bb4sewardjstatic 958564292ac4b9adf51c45517cca2878732feb5bb4sewardjvoid barrier_initialize(struct barrier_info* const p, 968564292ac4b9adf51c45517cca2878732feb5bb4sewardj const Addr barrier, 970268dfacec38138a01a58d05a038826e26b6c436bart const BarrierT barrier_type, 988564292ac4b9adf51c45517cca2878732feb5bb4sewardj const Word count) 998564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 1008564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(barrier != 0); 1010268dfacec38138a01a58d05a038826e26b6c436bart tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier); 1028564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(count > 0); 10328230a3734e045791173aca660efc7d7aeef78cebart tl_assert(p->a1 == barrier); 1048564292ac4b9adf51c45517cca2878732feb5bb4sewardj 10528230a3734e045791173aca660efc7d7aeef78cebart p->cleanup = (void(*)(DrdClientobj*))barrier_cleanup; 106306527d7413780873a05cf801c47f725fb60c310bart p->barrier_type = barrier_type; 107bebc5d668dc5a6df337011181debbf8d91c338e0bart p->count = count; 108bebc5d668dc5a6df337011181debbf8d91c338e0bart p->pre_iteration = 0; 109bebc5d668dc5a6df337011181debbf8d91c338e0bart p->post_iteration = 0; 110bebc5d668dc5a6df337011181debbf8d91c338e0bart p->pre_waiters_left = count; 111bebc5d668dc5a6df337011181debbf8d91c338e0bart p->post_waiters_left = count; 1128564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(sizeof(((struct barrier_thread_info*)0)->tid) == sizeof(Word)); 1138564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(sizeof(((struct barrier_thread_info*)0)->tid) 1148564292ac4b9adf51c45517cca2878732feb5bb4sewardj >= sizeof(DrdThreadId)); 1158564292ac4b9adf51c45517cca2878732feb5bb4sewardj p->oset = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free)); 1168564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 1178564292ac4b9adf51c45517cca2878732feb5bb4sewardj 11828230a3734e045791173aca660efc7d7aeef78cebart/** Deallocate the memory allocated by barrier_initialize() and in p->oset. 11972b751c3ba354f7069108d26b445310f0cf4a73cbart * Called by clientobj_destroy(). 12028230a3734e045791173aca660efc7d7aeef78cebart */ 12128230a3734e045791173aca660efc7d7aeef78cebartvoid barrier_cleanup(struct barrier_info* p) 1228564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 1238564292ac4b9adf51c45517cca2878732feb5bb4sewardj struct barrier_thread_info* q; 1248564292ac4b9adf51c45517cca2878732feb5bb4sewardj 1258564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(p); 1268564292ac4b9adf51c45517cca2878732feb5bb4sewardj 127306527d7413780873a05cf801c47f725fb60c310bart if (p->pre_waiters_left != p->count) 12828230a3734e045791173aca660efc7d7aeef78cebart { 1293b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart BarrierErrInfo bei = { p->a1 }; 1303b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(maybe_record_error)(VG_(get_running_tid)(), 1313b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart BarrierErr, 1323b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(get_IP)(VG_(get_running_tid)()), 1333b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart "Destruction of barrier that is being waited" 1343b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart " upon", 1353b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart &bei); 13628230a3734e045791173aca660efc7d7aeef78cebart } 1378564292ac4b9adf51c45517cca2878732feb5bb4sewardj 1388564292ac4b9adf51c45517cca2878732feb5bb4sewardj VG_(OSetGen_ResetIter)(p->oset); 1398564292ac4b9adf51c45517cca2878732feb5bb4sewardj for ( ; (q = VG_(OSetGen_Next)(p->oset)) != 0; ) 1408564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 1418564292ac4b9adf51c45517cca2878732feb5bb4sewardj barrier_thread_destroy(q); 1428564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 1438564292ac4b9adf51c45517cca2878732feb5bb4sewardj VG_(OSetGen_Destroy)(p->oset); 1448564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 1458564292ac4b9adf51c45517cca2878732feb5bb4sewardj 146bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Look up the client-side barrier address barrier in s_barrier[]. If not 147bebc5d668dc5a6df337011181debbf8d91c338e0bart * found, add it. */ 1488564292ac4b9adf51c45517cca2878732feb5bb4sewardjstatic 1498564292ac4b9adf51c45517cca2878732feb5bb4sewardjstruct barrier_info* 1500268dfacec38138a01a58d05a038826e26b6c436bartbarrier_get_or_allocate(const Addr barrier, 1510268dfacec38138a01a58d05a038826e26b6c436bart const BarrierT barrier_type, const Word count) 1528564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 15328230a3734e045791173aca660efc7d7aeef78cebart struct barrier_info *p; 1548564292ac4b9adf51c45517cca2878732feb5bb4sewardj 1550268dfacec38138a01a58d05a038826e26b6c436bart tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier); 1560268dfacec38138a01a58d05a038826e26b6c436bart 15728230a3734e045791173aca660efc7d7aeef78cebart tl_assert(offsetof(DrdClientobj, barrier) == 0); 15872b751c3ba354f7069108d26b445310f0cf4a73cbart p = &clientobj_get(barrier, ClientBarrier)->barrier; 15928230a3734e045791173aca660efc7d7aeef78cebart if (p == 0) 1608564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 1610268dfacec38138a01a58d05a038826e26b6c436bart p = &clientobj_add(barrier, ClientBarrier)->barrier; 1620268dfacec38138a01a58d05a038826e26b6c436bart barrier_initialize(p, barrier, barrier_type, count); 1638564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 16428230a3734e045791173aca660efc7d7aeef78cebart return p; 16528230a3734e045791173aca660efc7d7aeef78cebart} 16628230a3734e045791173aca660efc7d7aeef78cebart 16728230a3734e045791173aca660efc7d7aeef78cebart/** Look up the address of the information associated with the client-side 16828230a3734e045791173aca660efc7d7aeef78cebart * barrier object. */ 16972b751c3ba354f7069108d26b445310f0cf4a73cbartstatic struct barrier_info* barrier_get(const Addr barrier) 17028230a3734e045791173aca660efc7d7aeef78cebart{ 17128230a3734e045791173aca660efc7d7aeef78cebart tl_assert(offsetof(DrdClientobj, barrier) == 0); 17272b751c3ba354f7069108d26b445310f0cf4a73cbart return &clientobj_get(barrier, ClientBarrier)->barrier; 1738564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 1748564292ac4b9adf51c45517cca2878732feb5bb4sewardj 175bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Initialize a barrier with client address barrier, client size size, and 17628230a3734e045791173aca660efc7d7aeef78cebart * where count threads participate in each barrier. 17728230a3734e045791173aca660efc7d7aeef78cebart * Called before pthread_barrier_init(). 17828230a3734e045791173aca660efc7d7aeef78cebart */ 1790268dfacec38138a01a58d05a038826e26b6c436bartvoid barrier_init(const Addr barrier, 1800268dfacec38138a01a58d05a038826e26b6c436bart const BarrierT barrier_type, const Word count, 1810268dfacec38138a01a58d05a038826e26b6c436bart const Bool reinitialization) 1828564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 183306527d7413780873a05cf801c47f725fb60c310bart struct barrier_info* p; 184306527d7413780873a05cf801c47f725fb60c310bart 185306527d7413780873a05cf801c47f725fb60c310bart tl_assert(barrier_type == pthread_barrier || barrier_type == gomp_barrier); 186306527d7413780873a05cf801c47f725fb60c310bart 187306527d7413780873a05cf801c47f725fb60c310bart p = barrier_get_or_allocate(barrier, barrier_type, count); 188306527d7413780873a05cf801c47f725fb60c310bart 1893b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart if (s_trace_barrier) 1903b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart { 191306527d7413780873a05cf801c47f725fb60c310bart if (reinitialization) 192306527d7413780873a05cf801c47f725fb60c310bart { 193306527d7413780873a05cf801c47f725fb60c310bart VG_(message)(Vg_UserMsg, 194a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart "[%d/%d] barrier_reinit %s 0x%lx count %ld -> %ld", 195306527d7413780873a05cf801c47f725fb60c310bart VG_(get_running_tid)(), 196306527d7413780873a05cf801c47f725fb60c310bart thread_get_running_tid(), 197306527d7413780873a05cf801c47f725fb60c310bart barrier_get_typename(p), 198306527d7413780873a05cf801c47f725fb60c310bart barrier, 199306527d7413780873a05cf801c47f725fb60c310bart p->count, 200306527d7413780873a05cf801c47f725fb60c310bart count); 201306527d7413780873a05cf801c47f725fb60c310bart } 202306527d7413780873a05cf801c47f725fb60c310bart else 203306527d7413780873a05cf801c47f725fb60c310bart { 204306527d7413780873a05cf801c47f725fb60c310bart VG_(message)(Vg_UserMsg, 205306527d7413780873a05cf801c47f725fb60c310bart "[%d/%d] barrier_init %s 0x%lx", 206306527d7413780873a05cf801c47f725fb60c310bart VG_(get_running_tid)(), 207306527d7413780873a05cf801c47f725fb60c310bart thread_get_running_tid(), 208306527d7413780873a05cf801c47f725fb60c310bart barrier_get_typename(p), 209306527d7413780873a05cf801c47f725fb60c310bart barrier); 210306527d7413780873a05cf801c47f725fb60c310bart } 211306527d7413780873a05cf801c47f725fb60c310bart } 212306527d7413780873a05cf801c47f725fb60c310bart 213306527d7413780873a05cf801c47f725fb60c310bart if (reinitialization && p->count != count) 214306527d7413780873a05cf801c47f725fb60c310bart { 215306527d7413780873a05cf801c47f725fb60c310bart if (p->pre_waiters_left != p->count || p->post_waiters_left != p->count) 216306527d7413780873a05cf801c47f725fb60c310bart { 217306527d7413780873a05cf801c47f725fb60c310bart VG_(message)(Vg_UserMsg, "Error: reinitialization with active waiters"); 218306527d7413780873a05cf801c47f725fb60c310bart } 219306527d7413780873a05cf801c47f725fb60c310bart p->count = count; 2203b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart } 2218564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 2228564292ac4b9adf51c45517cca2878732feb5bb4sewardj 22328230a3734e045791173aca660efc7d7aeef78cebart/** Called after pthread_barrier_destroy(). */ 2240268dfacec38138a01a58d05a038826e26b6c436bartvoid barrier_destroy(const Addr barrier, const BarrierT barrier_type) 2258564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 22672b751c3ba354f7069108d26b445310f0cf4a73cbart struct barrier_info* p; 22772b751c3ba354f7069108d26b445310f0cf4a73cbart 228306527d7413780873a05cf801c47f725fb60c310bart p = barrier_get(barrier); 229306527d7413780873a05cf801c47f725fb60c310bart 2303b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart if (s_trace_barrier) 2313b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart { 2323b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(message)(Vg_UserMsg, 233306527d7413780873a05cf801c47f725fb60c310bart "[%d/%d] barrier_destroy %s 0x%lx", 2343b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(get_running_tid)(), 2353b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart thread_get_running_tid(), 236306527d7413780873a05cf801c47f725fb60c310bart barrier_get_typename(p), 23772b751c3ba354f7069108d26b445310f0cf4a73cbart barrier); 2383b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart } 23972b751c3ba354f7069108d26b445310f0cf4a73cbart 24072b751c3ba354f7069108d26b445310f0cf4a73cbart if (p == 0) 24172b751c3ba354f7069108d26b445310f0cf4a73cbart { 24272b751c3ba354f7069108d26b445310f0cf4a73cbart GenericErrInfo GEI; 24372b751c3ba354f7069108d26b445310f0cf4a73cbart VG_(maybe_record_error)(VG_(get_running_tid)(), 24472b751c3ba354f7069108d26b445310f0cf4a73cbart GenericErr, 24572b751c3ba354f7069108d26b445310f0cf4a73cbart VG_(get_IP)(VG_(get_running_tid)()), 24672b751c3ba354f7069108d26b445310f0cf4a73cbart "Not a barrier", 24772b751c3ba354f7069108d26b445310f0cf4a73cbart &GEI); 24872b751c3ba354f7069108d26b445310f0cf4a73cbart return; 24972b751c3ba354f7069108d26b445310f0cf4a73cbart } 25072b751c3ba354f7069108d26b445310f0cf4a73cbart 25172b751c3ba354f7069108d26b445310f0cf4a73cbart clientobj_remove(p->a1, ClientBarrier); 2528564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 2538564292ac4b9adf51c45517cca2878732feb5bb4sewardj 25428230a3734e045791173aca660efc7d7aeef78cebart/** Called before pthread_barrier_wait(). */ 2550268dfacec38138a01a58d05a038826e26b6c436bartvoid barrier_pre_wait(const DrdThreadId tid, const Addr barrier, 2560268dfacec38138a01a58d05a038826e26b6c436bart const BarrierT barrier_type) 2578564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 2588564292ac4b9adf51c45517cca2878732feb5bb4sewardj struct barrier_info* p; 2598564292ac4b9adf51c45517cca2878732feb5bb4sewardj struct barrier_thread_info* q; 2608564292ac4b9adf51c45517cca2878732feb5bb4sewardj const UWord word_tid = tid; 2618564292ac4b9adf51c45517cca2878732feb5bb4sewardj 2628564292ac4b9adf51c45517cca2878732feb5bb4sewardj p = barrier_get(barrier); 263c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart if (p == 0 && barrier_type == gomp_barrier) 264c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart { 265a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart VG_(message)(Vg_UserMsg, "%s", ""); 266c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart VG_(message)(Vg_UserMsg, 267c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart "Please verify whether gcc has been configured" 268c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart " with option --disable-linux-futex."); 269c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart VG_(message)(Vg_UserMsg, 270c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart "See also the section about OpenMP in the DRD manual."); 271a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart VG_(message)(Vg_UserMsg, "%s", ""); 272c68bd60a06673f81e2bf25fc2a049f5cb91fa545bart } 2738564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(p); 2748564292ac4b9adf51c45517cca2878732feb5bb4sewardj 2758564292ac4b9adf51c45517cca2878732feb5bb4sewardj if (s_trace_barrier) 2768564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 2773b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(message)(Vg_UserMsg, 278a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart "[%d/%d] barrier_pre_wait %s 0x%lx iteration %ld", 2793b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(get_running_tid)(), 2803b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart thread_get_running_tid(), 281306527d7413780873a05cf801c47f725fb60c310bart barrier_get_typename(p), 2823b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart barrier, 2833b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart p->pre_iteration); 2848564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 2858564292ac4b9adf51c45517cca2878732feb5bb4sewardj 2868564292ac4b9adf51c45517cca2878732feb5bb4sewardj q = VG_(OSetGen_Lookup)(p->oset, &word_tid); 2878564292ac4b9adf51c45517cca2878732feb5bb4sewardj if (q == 0) 2888564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 2898564292ac4b9adf51c45517cca2878732feb5bb4sewardj q = VG_(OSetGen_AllocNode)(p->oset, sizeof(*q)); 290bebc5d668dc5a6df337011181debbf8d91c338e0bart barrier_thread_initialize(q, tid, p->pre_iteration); 2918564292ac4b9adf51c45517cca2878732feb5bb4sewardj VG_(OSetGen_Insert)(p->oset, q); 2928564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(VG_(OSetGen_Lookup)(p->oset, &word_tid) == q); 2938564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 294a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart thread_get_latest_segment(&q->sg[p->pre_iteration], tid); 295bebc5d668dc5a6df337011181debbf8d91c338e0bart 296bebc5d668dc5a6df337011181debbf8d91c338e0bart if (--p->pre_waiters_left <= 0) 297bebc5d668dc5a6df337011181debbf8d91c338e0bart { 298bebc5d668dc5a6df337011181debbf8d91c338e0bart p->pre_iteration = 1 - p->pre_iteration; 299bebc5d668dc5a6df337011181debbf8d91c338e0bart p->pre_waiters_left = p->count; 300bebc5d668dc5a6df337011181debbf8d91c338e0bart } 3018564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 3028564292ac4b9adf51c45517cca2878732feb5bb4sewardj 30328230a3734e045791173aca660efc7d7aeef78cebart/** Called after pthread_barrier_wait(). */ 3048564292ac4b9adf51c45517cca2878732feb5bb4sewardjvoid barrier_post_wait(const DrdThreadId tid, const Addr barrier, 3050268dfacec38138a01a58d05a038826e26b6c436bart const BarrierT barrier_type, const Bool waited) 3068564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 3073b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart struct barrier_info* p; 3088564292ac4b9adf51c45517cca2878732feb5bb4sewardj 3093b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart p = barrier_get(barrier); 310bebc5d668dc5a6df337011181debbf8d91c338e0bart 3118564292ac4b9adf51c45517cca2878732feb5bb4sewardj if (s_trace_barrier) 3128564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 3133b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(message)(Vg_UserMsg, 314a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart "[%d/%d] barrier_post_wait %s 0x%lx iteration %ld", 3153b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart VG_(get_running_tid)(), 3163b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart tid, 317306527d7413780873a05cf801c47f725fb60c310bart p ? barrier_get_typename(p) : "(?)", 3183b1ee459c4a59f6479a7b2803f7ccd952aab44bbbart barrier, 319306527d7413780873a05cf801c47f725fb60c310bart p ? p->post_iteration : -1); 3208564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 3218564292ac4b9adf51c45517cca2878732feb5bb4sewardj 322306527d7413780873a05cf801c47f725fb60c310bart /* If p == 0, this means that the barrier has been destroyed after */ 323306527d7413780873a05cf801c47f725fb60c310bart /* *_barrier_wait() returned and before this function was called. Just */ 324306527d7413780873a05cf801c47f725fb60c310bart /* return in that case. */ 325306527d7413780873a05cf801c47f725fb60c310bart if (p == 0) 326306527d7413780873a05cf801c47f725fb60c310bart return; 327306527d7413780873a05cf801c47f725fb60c310bart 3288564292ac4b9adf51c45517cca2878732feb5bb4sewardj if (waited) 3298564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 3308564292ac4b9adf51c45517cca2878732feb5bb4sewardj const UWord word_tid = tid; 3318564292ac4b9adf51c45517cca2878732feb5bb4sewardj struct barrier_thread_info* q; 3328564292ac4b9adf51c45517cca2878732feb5bb4sewardj struct barrier_thread_info* r; 3338564292ac4b9adf51c45517cca2878732feb5bb4sewardj 3348564292ac4b9adf51c45517cca2878732feb5bb4sewardj q = VG_(OSetGen_Lookup)(p->oset, &word_tid); 3358564292ac4b9adf51c45517cca2878732feb5bb4sewardj tl_assert(q); 3368564292ac4b9adf51c45517cca2878732feb5bb4sewardj VG_(OSetGen_ResetIter)(p->oset); 3378564292ac4b9adf51c45517cca2878732feb5bb4sewardj for ( ; (r = VG_(OSetGen_Next)(p->oset)) != 0; ) 3388564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 3398564292ac4b9adf51c45517cca2878732feb5bb4sewardj if (r != q) 3408564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 341a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart tl_assert(r->sg[p->post_iteration]); 342a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart thread_combine_vc2(tid, &r->sg[p->post_iteration]->vc); 3438564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 3448564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 345bebc5d668dc5a6df337011181debbf8d91c338e0bart 346bebc5d668dc5a6df337011181debbf8d91c338e0bart thread_new_segment(tid); 3476bbefaf8418f3e225c4eefcc726b6874bef15d8cbart s_barrier_segment_creation_count++; 348bebc5d668dc5a6df337011181debbf8d91c338e0bart 349bebc5d668dc5a6df337011181debbf8d91c338e0bart if (--p->post_waiters_left <= 0) 350bebc5d668dc5a6df337011181debbf8d91c338e0bart { 351bebc5d668dc5a6df337011181debbf8d91c338e0bart p->post_iteration = 1 - p->post_iteration; 352bebc5d668dc5a6df337011181debbf8d91c338e0bart p->post_waiters_left = p->count; 353bebc5d668dc5a6df337011181debbf8d91c338e0bart } 3548564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 3558564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 3568564292ac4b9adf51c45517cca2878732feb5bb4sewardj 357bebc5d668dc5a6df337011181debbf8d91c338e0bart/** Call this function when thread tid stops to exist. */ 3588564292ac4b9adf51c45517cca2878732feb5bb4sewardjvoid barrier_thread_delete(const DrdThreadId tid) 3598564292ac4b9adf51c45517cca2878732feb5bb4sewardj{ 36028230a3734e045791173aca660efc7d7aeef78cebart struct barrier_info* p; 3618564292ac4b9adf51c45517cca2878732feb5bb4sewardj 36272b751c3ba354f7069108d26b445310f0cf4a73cbart clientobj_resetiter(); 36372b751c3ba354f7069108d26b445310f0cf4a73cbart for ( ; (p = &clientobj_next(ClientBarrier)->barrier) != 0; ) 3648564292ac4b9adf51c45517cca2878732feb5bb4sewardj { 36528230a3734e045791173aca660efc7d7aeef78cebart struct barrier_thread_info* q; 36628230a3734e045791173aca660efc7d7aeef78cebart const UWord word_tid = tid; 36728230a3734e045791173aca660efc7d7aeef78cebart q = VG_(OSetGen_Remove)(p->oset, &word_tid); 36828230a3734e045791173aca660efc7d7aeef78cebart barrier_thread_destroy(q); 36928230a3734e045791173aca660efc7d7aeef78cebart VG_(OSetGen_FreeNode)(p->oset, q); 3708564292ac4b9adf51c45517cca2878732feb5bb4sewardj } 3718564292ac4b9adf51c45517cca2878732feb5bb4sewardj} 372306527d7413780873a05cf801c47f725fb60c310bart 373306527d7413780873a05cf801c47f725fb60c310bartstatic const char* barrier_get_typename(struct barrier_info* const p) 374306527d7413780873a05cf801c47f725fb60c310bart{ 375306527d7413780873a05cf801c47f725fb60c310bart tl_assert(p); 376306527d7413780873a05cf801c47f725fb60c310bart 377306527d7413780873a05cf801c47f725fb60c310bart return barrier_type_name(p->barrier_type); 378306527d7413780873a05cf801c47f725fb60c310bart} 379306527d7413780873a05cf801c47f725fb60c310bart 380306527d7413780873a05cf801c47f725fb60c310bartstatic const char* barrier_type_name(const BarrierT bt) 381306527d7413780873a05cf801c47f725fb60c310bart{ 382306527d7413780873a05cf801c47f725fb60c310bart switch (bt) 383306527d7413780873a05cf801c47f725fb60c310bart { 384306527d7413780873a05cf801c47f725fb60c310bart case pthread_barrier: 385306527d7413780873a05cf801c47f725fb60c310bart return "pthread barrier"; 386306527d7413780873a05cf801c47f725fb60c310bart case gomp_barrier: 387306527d7413780873a05cf801c47f725fb60c310bart return "gomp barrier"; 388306527d7413780873a05cf801c47f725fb60c310bart } 389306527d7413780873a05cf801c47f725fb60c310bart return "?"; 390306527d7413780873a05cf801c47f725fb60c310bart} 3916bbefaf8418f3e225c4eefcc726b6874bef15d8cbart 3926bbefaf8418f3e225c4eefcc726b6874bef15d8cbartULong get_barrier_segment_creation_count(void) 3936bbefaf8418f3e225c4eefcc726b6874bef15d8cbart{ 3946bbefaf8418f3e225c4eefcc726b6874bef15d8cbart return s_barrier_segment_creation_count; 3956bbefaf8418f3e225c4eefcc726b6874bef15d8cbart} 396