1af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/* 286562bd89ac23ce795d19c71fabcb9d1c8f956d3bart This file is part of drd, a thread error detector. 3af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 4d4bab99f83dbc53665c5769c3f6b50ffcd2a9a7dbart Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>. 5af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 6af44c8236f7a73e71b16b707bba56f33af4d01cesewardj This program is free software; you can redistribute it and/or 7af44c8236f7a73e71b16b707bba56f33af4d01cesewardj modify it under the terms of the GNU General Public License as 8af44c8236f7a73e71b16b707bba56f33af4d01cesewardj published by the Free Software Foundation; either version 2 of the 9af44c8236f7a73e71b16b707bba56f33af4d01cesewardj License, or (at your option) any later version. 10af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 11af44c8236f7a73e71b16b707bba56f33af4d01cesewardj This program is distributed in the hope that it will be useful, but 12af44c8236f7a73e71b16b707bba56f33af4d01cesewardj WITHOUT ANY WARRANTY; without even the implied warranty of 13af44c8236f7a73e71b16b707bba56f33af4d01cesewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14af44c8236f7a73e71b16b707bba56f33af4d01cesewardj General Public License for more details. 15af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 16af44c8236f7a73e71b16b707bba56f33af4d01cesewardj You should have received a copy of the GNU General Public License 17af44c8236f7a73e71b16b707bba56f33af4d01cesewardj along with this program; if not, write to the Free Software 18af44c8236f7a73e71b16b707bba56f33af4d01cesewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 02111-1307, USA. 20af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 21af44c8236f7a73e71b16b707bba56f33af4d01cesewardj The GNU General Public License is contained in the file COPYING. 22af44c8236f7a73e71b16b707bba56f33af4d01cesewardj*/ 23af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 24af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 25af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_error.h" 2609dc13f324a19f1bebf58c7f197a581dc8fb528bbart#include "drd_barrier.h" 27d2c5eae561040706a7eb45c0f3988dcd538c8d7ebart#include "drd_clientobj.h" 2809dc13f324a19f1bebf58c7f197a581dc8fb528bbart#include "drd_cond.h" 2909dc13f324a19f1bebf58c7f197a581dc8fb528bbart#include "drd_mutex.h" 30af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_segment.h" 3109dc13f324a19f1bebf58c7f197a581dc8fb528bbart#include "drd_semaphore.h" 32af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_suppression.h" 33af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "drd_thread.h" 3482195c18d79b2e8c0e33d3c9e1b73cfa2e33c6c1bart#include "pub_tool_vki.h" 35af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_basics.h" // Addr, SizeT 36af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_libcassert.h" // tl_assert() 37af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_libcbase.h" // VG_(strlen)() 38af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_libcprint.h" // VG_(printf)() 39af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_machine.h" 40af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)() 418564292ac4b9adf51c45517cca2878732feb5bb4sewardj#include "pub_tool_options.h" // VG_(clo_backtrace_size) 42af44c8236f7a73e71b16b707bba56f33af4d01cesewardj#include "pub_tool_threadstate.h" // VG_(get_pthread_id)() 43af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 4432ba208a4ad813d2045a75e813ac8658390595f7bart 45af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 46324a23bea57e0bfc27d9442ec00a8eee8294f01abart/* Local functions. */ 47af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 4886a87df5949beb1f89ebbed923068faed08d048cbartstatic void thread_append_segment(const DrdThreadId tid, Segment* const sg); 4986a87df5949beb1f89ebbed923068faed08d048cbartstatic void thread_discard_segment(const DrdThreadId tid, Segment* const sg); 5086a87df5949beb1f89ebbed923068faed08d048cbartstatic void thread_compute_conflict_set(struct bitmap** conflict_set, 5186a87df5949beb1f89ebbed923068faed08d048cbart const DrdThreadId tid); 528f822af9b234e7c553c408eba65a641c4773457fbartstatic Bool thread_conflict_set_up_to_date(const DrdThreadId tid); 53af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 54af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 55324a23bea57e0bfc27d9442ec00a8eee8294f01abart/* Local variables. */ 56af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 5786a87df5949beb1f89ebbed923068faed08d048cbartstatic ULong s_context_switch_count; 5886a87df5949beb1f89ebbed923068faed08d048cbartstatic ULong s_discard_ordered_segments_count; 5954803feb0b92e4708d3cee92e7449f802be70197bartstatic ULong s_compute_conflict_set_count; 6086a87df5949beb1f89ebbed923068faed08d048cbartstatic ULong s_update_conflict_set_count; 61e5214666ead5aebb79ad662deacff0a952cba70dbartstatic ULong s_update_conflict_set_new_sg_count; 62e5214666ead5aebb79ad662deacff0a952cba70dbartstatic ULong s_update_conflict_set_sync_count; 63e5214666ead5aebb79ad662deacff0a952cba70dbartstatic ULong s_update_conflict_set_join_count; 6486a87df5949beb1f89ebbed923068faed08d048cbartstatic ULong s_conflict_set_bitmap_creation_count; 6586a87df5949beb1f89ebbed923068faed08d048cbartstatic ULong s_conflict_set_bitmap2_creation_count; 6686a87df5949beb1f89ebbed923068faed08d048cbartstatic ThreadId s_vg_running_tid = VG_INVALID_THREADID; 67324a23bea57e0bfc27d9442ec00a8eee8294f01abartDrdThreadId DRD_(g_drd_running_tid) = DRD_INVALID_THREADID; 681e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianThreadInfo* DRD_(g_threadinfo); 69324a23bea57e0bfc27d9442ec00a8eee8294f01abartstruct bitmap* DRD_(g_conflict_set); 709cdc08368068d746e42d40c8f3a3dca5db5caee4bartBool DRD_(verify_conflict_set); 7186a87df5949beb1f89ebbed923068faed08d048cbartstatic Bool s_trace_context_switches = False; 7286a87df5949beb1f89ebbed923068faed08d048cbartstatic Bool s_trace_conflict_set = False; 738f822af9b234e7c553c408eba65a641c4773457fbartstatic Bool s_trace_conflict_set_bm = False; 7486a87df5949beb1f89ebbed923068faed08d048cbartstatic Bool s_trace_fork_join = False; 7586a87df5949beb1f89ebbed923068faed08d048cbartstatic Bool s_segment_merging = True; 768f822af9b234e7c553c408eba65a641c4773457fbartstatic Bool s_new_segments_since_last_merge; 776f1d7165e418f1d8d255b5d4e93a5df3c1e5e659bartstatic int s_segment_merge_interval = 10; 786d956dc21b6a81f0c67ad18ac61867da0d5922a3bartstatic unsigned s_join_list_vol = 10; 796d956dc21b6a81f0c67ad18ac61867da0d5922a3bartstatic unsigned s_deletion_head; 806d956dc21b6a81f0c67ad18ac61867da0d5922a3bartstatic unsigned s_deletion_tail; 81af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 82af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 83324a23bea57e0bfc27d9442ec00a8eee8294f01abart/* Function definitions. */ 84af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 8586a87df5949beb1f89ebbed923068faed08d048cbart/** Enables/disables context switch tracing. */ 8662a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_trace_context_switches)(const Bool t) 8726f73e12ef03bb04ebee5cccd8da08cddb426341bart{ 88bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(t == False || t == True); 89bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_trace_context_switches = t; 9026f73e12ef03bb04ebee5cccd8da08cddb426341bart} 9126f73e12ef03bb04ebee5cccd8da08cddb426341bart 9286a87df5949beb1f89ebbed923068faed08d048cbart/** Enables/disables conflict set tracing. */ 9362a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_trace_conflict_set)(const Bool t) 9426f73e12ef03bb04ebee5cccd8da08cddb426341bart{ 95bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(t == False || t == True); 96bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_trace_conflict_set = t; 9726f73e12ef03bb04ebee5cccd8da08cddb426341bart} 9826f73e12ef03bb04ebee5cccd8da08cddb426341bart 998f822af9b234e7c553c408eba65a641c4773457fbart/** Enables/disables conflict set bitmap tracing. */ 1008f822af9b234e7c553c408eba65a641c4773457fbartvoid DRD_(thread_trace_conflict_set_bm)(const Bool t) 1018f822af9b234e7c553c408eba65a641c4773457fbart{ 1028f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(t == False || t == True); 1038f822af9b234e7c553c408eba65a641c4773457fbart s_trace_conflict_set_bm = t; 1048f822af9b234e7c553c408eba65a641c4773457fbart} 1058f822af9b234e7c553c408eba65a641c4773457fbart 10686a87df5949beb1f89ebbed923068faed08d048cbart/** Report whether fork/join tracing is enabled. */ 10709dc13f324a19f1bebf58c7f197a581dc8fb528bbartBool DRD_(thread_get_trace_fork_join)(void) 10809dc13f324a19f1bebf58c7f197a581dc8fb528bbart{ 109bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_trace_fork_join; 11009dc13f324a19f1bebf58c7f197a581dc8fb528bbart} 11109dc13f324a19f1bebf58c7f197a581dc8fb528bbart 11286a87df5949beb1f89ebbed923068faed08d048cbart/** Enables/disables fork/join tracing. */ 11309dc13f324a19f1bebf58c7f197a581dc8fb528bbartvoid DRD_(thread_set_trace_fork_join)(const Bool t) 11409dc13f324a19f1bebf58c7f197a581dc8fb528bbart{ 115bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(t == False || t == True); 116bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_trace_fork_join = t; 11709dc13f324a19f1bebf58c7f197a581dc8fb528bbart} 11809dc13f324a19f1bebf58c7f197a581dc8fb528bbart 11986a87df5949beb1f89ebbed923068faed08d048cbart/** Enables/disables segment merging. */ 12062a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_segment_merging)(const Bool m) 121a9c37398e4565280266ce663a6c38c3518af2812bart{ 122bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(m == False || m == True); 123bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_segment_merging = m; 124a9c37398e4565280266ce663a6c38c3518af2812bart} 125a9c37398e4565280266ce663a6c38c3518af2812bart 1268f822af9b234e7c553c408eba65a641c4773457fbart/** Get the segment merging interval. */ 1278f822af9b234e7c553c408eba65a641c4773457fbartint DRD_(thread_get_segment_merge_interval)(void) 1288f822af9b234e7c553c408eba65a641c4773457fbart{ 1298f822af9b234e7c553c408eba65a641c4773457fbart return s_segment_merge_interval; 1308f822af9b234e7c553c408eba65a641c4773457fbart} 1318f822af9b234e7c553c408eba65a641c4773457fbart 1328f822af9b234e7c553c408eba65a641c4773457fbart/** Set the segment merging interval. */ 1338f822af9b234e7c553c408eba65a641c4773457fbartvoid DRD_(thread_set_segment_merge_interval)(const int i) 1348f822af9b234e7c553c408eba65a641c4773457fbart{ 1358f822af9b234e7c553c408eba65a641c4773457fbart s_segment_merge_interval = i; 1368f822af9b234e7c553c408eba65a641c4773457fbart} 1378f822af9b234e7c553c408eba65a641c4773457fbart 1386d956dc21b6a81f0c67ad18ac61867da0d5922a3bartvoid DRD_(thread_set_join_list_vol)(const int jlv) 1396d956dc21b6a81f0c67ad18ac61867da0d5922a3bart{ 1406d956dc21b6a81f0c67ad18ac61867da0d5922a3bart s_join_list_vol = jlv; 1416d956dc21b6a81f0c67ad18ac61867da0d5922a3bart} 1426d956dc21b6a81f0c67ad18ac61867da0d5922a3bart 143e278ab506b9a73ef1c17a17077546b2de9a11d7cbartvoid DRD_(thread_init)(void) 144e278ab506b9a73ef1c17a17077546b2de9a11d7cbart{ 1451e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian DRD_(g_threadinfo) = VG_(malloc)("drd.main.ti.1", 1461e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian DRD_N_THREADS * sizeof DRD_(g_threadinfo)[0]); 1471e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian for (UInt i = 0; i < DRD_N_THREADS; ++i) { 1481e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian static ThreadInfo initval; 1491e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian DRD_(g_threadinfo)[i] = initval; 1501e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian } 151e278ab506b9a73ef1c17a17077546b2de9a11d7cbart} 152e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 153af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/** 15486a87df5949beb1f89ebbed923068faed08d048cbart * Convert Valgrind's ThreadId into a DrdThreadId. 15586a87df5949beb1f89ebbed923068faed08d048cbart * 15686a87df5949beb1f89ebbed923068faed08d048cbart * @return DRD thread ID upon success and DRD_INVALID_THREADID if the passed 15786a87df5949beb1f89ebbed923068faed08d048cbart * Valgrind ThreadId does not yet exist. 158324a23bea57e0bfc27d9442ec00a8eee8294f01abart */ 15962a784c9382fdf7184065ad76ae8d3b905605f21bartDrdThreadId DRD_(VgThreadIdToDrdThreadId)(const ThreadId tid) 160af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1611e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian UInt i; 162af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 163bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (tid == VG_INVALID_THREADID) 164bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_INVALID_THREADID; 165af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 166bedfd237fbdc80d0c917cfcb85a94b5561c92633bart for (i = 1; i < DRD_N_THREADS; i++) 167bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 168bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (DRD_(g_threadinfo)[i].vg_thread_exists == True 169bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && DRD_(g_threadinfo)[i].vg_threadid == tid) 170bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 171bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return i; 172bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 173bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 174af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 175bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_INVALID_THREADID; 176af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 177af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 17886a87df5949beb1f89ebbed923068faed08d048cbart/** Allocate a new DRD thread ID for the specified Valgrind thread ID. */ 17962a784c9382fdf7184065ad76ae8d3b905605f21bartstatic DrdThreadId DRD_(VgThreadIdToNewDrdThreadId)(const ThreadId tid) 180af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1811e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian UInt i; 182bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 183bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(VgThreadIdToDrdThreadId)(tid) == DRD_INVALID_THREADID); 184bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 185bedfd237fbdc80d0c917cfcb85a94b5561c92633bart for (i = 1; i < DRD_N_THREADS; i++) 186bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 1876d956dc21b6a81f0c67ad18ac61867da0d5922a3bart if (!DRD_(g_threadinfo)[i].valid) 188bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 189bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(! DRD_(IsValidDrdThreadId)(i)); 190bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1916d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[i].valid = True; 192bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].vg_thread_exists = True; 193bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].vg_threadid = tid; 194bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].pt_threadid = INVALID_POSIX_THREADID; 195bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].stack_min = 0; 196bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].stack_min_min = 0; 197bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].stack_startup = 0; 198bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].stack_max = 0; 199d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(thread_set_name)(i, ""); 200383d613d286501412f1760c8eaafaeb8c518b344bart DRD_(g_threadinfo)[i].on_alt_stack = False; 201d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(g_threadinfo)[i].is_recording_loads = True; 202d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(g_threadinfo)[i].is_recording_stores = True; 203dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart DRD_(g_threadinfo)[i].pthread_create_nesting_level = 0; 204bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].synchr_nesting = 0; 2056d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[i].deletion_seq = s_deletion_tail - 1; 20691b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[i].sg_first == NULL); 20791b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[i].sg_last == NULL); 208bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 209bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(i)); 210bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 211bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return i; 212bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 213bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 214bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 2153c9afb10ad9854fd81d20b3a4b4aba3e230ec196bart VG_(printf)( 2163c9afb10ad9854fd81d20b3a4b4aba3e230ec196bart"\nSorry, but the maximum number of threads supported by DRD has been exceeded." 2173c9afb10ad9854fd81d20b3a4b4aba3e230ec196bart"Aborting.\n"); 2183c9afb10ad9854fd81d20b3a4b4aba3e230ec196bart 219bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(False); 220bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 221bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_INVALID_THREADID; 222af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 223af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 22486a87df5949beb1f89ebbed923068faed08d048cbart/** Convert a POSIX thread ID into a DRD thread ID. */ 22562a784c9382fdf7184065ad76ae8d3b905605f21bartDrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid) 226af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 2271e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian UInt i; 228bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 229b48bde21f5107f74335b88cacee76c556ae22aa7bart if (tid != INVALID_POSIX_THREADID) 230bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 231b48bde21f5107f74335b88cacee76c556ae22aa7bart for (i = 1; i < DRD_N_THREADS; i++) 232bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 233b48bde21f5107f74335b88cacee76c556ae22aa7bart if (DRD_(g_threadinfo)[i].posix_thread_exists 234b48bde21f5107f74335b88cacee76c556ae22aa7bart && DRD_(g_threadinfo)[i].pt_threadid == tid) 235b48bde21f5107f74335b88cacee76c556ae22aa7bart { 236b48bde21f5107f74335b88cacee76c556ae22aa7bart return i; 237b48bde21f5107f74335b88cacee76c556ae22aa7bart } 238bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 239bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 240bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_INVALID_THREADID; 241af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 242af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 24386a87df5949beb1f89ebbed923068faed08d048cbart/** Convert a DRD thread ID into a Valgrind thread ID. */ 24462a784c9382fdf7184065ad76ae8d3b905605f21bartThreadId DRD_(DrdThreadIdToVgThreadId)(const DrdThreadId tid) 245af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 246bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 247bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 2488f822af9b234e7c553c408eba65a641c4773457fbart 249bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return (DRD_(g_threadinfo)[tid].vg_thread_exists 250bedfd237fbdc80d0c917cfcb85a94b5561c92633bart ? DRD_(g_threadinfo)[tid].vg_threadid 251bedfd237fbdc80d0c917cfcb85a94b5561c92633bart : VG_INVALID_THREADID); 252af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 253af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 2548f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 255324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 256324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Sanity check of the doubly linked list of segments referenced by a 257324a23bea57e0bfc27d9442ec00a8eee8294f01abart * ThreadInfo struct. 258324a23bea57e0bfc27d9442ec00a8eee8294f01abart * @return True if sane, False if not. 259af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 26062a784c9382fdf7184065ad76ae8d3b905605f21bartstatic Bool DRD_(sane_ThreadInfo)(const ThreadInfo* const ti) 261af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 262bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* p; 2638f822af9b234e7c553c408eba65a641c4773457fbart 2642bf4bb9d10c2a6d034226a6270c4249d5502325ebart for (p = ti->sg_first; p; p = p->thr_next) { 2652bf4bb9d10c2a6d034226a6270c4249d5502325ebart if (p->thr_next && p->thr_next->thr_prev != p) 266bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return False; 2672bf4bb9d10c2a6d034226a6270c4249d5502325ebart if (p->thr_next == 0 && p != ti->sg_last) 268bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return False; 269bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 2702bf4bb9d10c2a6d034226a6270c4249d5502325ebart for (p = ti->sg_last; p; p = p->thr_prev) { 2712bf4bb9d10c2a6d034226a6270c4249d5502325ebart if (p->thr_prev && p->thr_prev->thr_next != p) 272bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return False; 2732bf4bb9d10c2a6d034226a6270c4249d5502325ebart if (p->thr_prev == 0 && p != ti->sg_first) 274bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return False; 275bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 276bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return True; 277af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 27823d3a4ee2197365501050264eb55dddcd39034d5bart#endif 279af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 280439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart/** 281439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * Create the first segment for a newly started thread. 282439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * 283439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * This function is called from the handler installed via 284439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * VG_(track_pre_thread_ll_create)(). The Valgrind core invokes this handler 285439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * from the context of the creator thread, before the new thread has been 286439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * created. 28786a87df5949beb1f89ebbed923068faed08d048cbart * 28886a87df5949beb1f89ebbed923068faed08d048cbart * @param[in] creator DRD thread ID of the creator thread. 28986a87df5949beb1f89ebbed923068faed08d048cbart * @param[in] vg_created Valgrind thread ID of the created thread. 29086a87df5949beb1f89ebbed923068faed08d048cbart * 29186a87df5949beb1f89ebbed923068faed08d048cbart * @return DRD thread ID of the created thread. 292439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart */ 29362a784c9382fdf7184065ad76ae8d3b905605f21bartDrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator, 29462a784c9382fdf7184065ad76ae8d3b905605f21bart const ThreadId vg_created) 295af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 296bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DrdThreadId created; 297af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 298bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(VgThreadIdToDrdThreadId)(vg_created) == DRD_INVALID_THREADID); 299bedfd237fbdc80d0c917cfcb85a94b5561c92633bart created = DRD_(VgThreadIdToNewDrdThreadId)(vg_created); 300bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)created && created < DRD_N_THREADS 301bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && created != DRD_INVALID_THREADID); 302af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 30391b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[created].sg_first == NULL); 30491b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[created].sg_last == NULL); 3058f822af9b234e7c553c408eba65a641c4773457fbart /* Create an initial segment for the newly created thread. */ 306bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_append_segment(created, DRD_(sg_new)(creator, created)); 307af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 308bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return created; 309af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 310af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 311439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart/** 31286a87df5949beb1f89ebbed923068faed08d048cbart * Initialize DRD_(g_threadinfo)[] for a newly created thread. Must be called 31386a87df5949beb1f89ebbed923068faed08d048cbart * after the thread has been created and before any client instructions are run 314439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * on the newly created thread, e.g. from the handler installed via 315439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart * VG_(track_pre_thread_first_insn)(). 31686a87df5949beb1f89ebbed923068faed08d048cbart * 31786a87df5949beb1f89ebbed923068faed08d048cbart * @param[in] vg_created Valgrind thread ID of the newly created thread. 31886a87df5949beb1f89ebbed923068faed08d048cbart * 31986a87df5949beb1f89ebbed923068faed08d048cbart * @return DRD thread ID for the new thread. 320439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart */ 32162a784c9382fdf7184065ad76ae8d3b905605f21bartDrdThreadId DRD_(thread_post_create)(const ThreadId vg_created) 322439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart{ 323bedfd237fbdc80d0c917cfcb85a94b5561c92633bart const DrdThreadId created = DRD_(VgThreadIdToDrdThreadId)(vg_created); 324bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 325bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)created && created < DRD_N_THREADS 326bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && created != DRD_INVALID_THREADID); 327bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 328bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[created].stack_max 329bedfd237fbdc80d0c917cfcb85a94b5561c92633bart = VG_(thread_get_stack_max)(vg_created); 330bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[created].stack_startup 331bedfd237fbdc80d0c917cfcb85a94b5561c92633bart = DRD_(g_threadinfo)[created].stack_max; 332bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[created].stack_min 333bedfd237fbdc80d0c917cfcb85a94b5561c92633bart = DRD_(g_threadinfo)[created].stack_max; 334bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[created].stack_min_min 335bedfd237fbdc80d0c917cfcb85a94b5561c92633bart = DRD_(g_threadinfo)[created].stack_max; 336bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[created].stack_size 337bedfd237fbdc80d0c917cfcb85a94b5561c92633bart = VG_(thread_get_stack_size)(vg_created); 338bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[created].stack_max != 0); 339bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 340bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return created; 341439c55fe48f6b3d0e2622b45d0ad8d8acc383398bart} 34209dc13f324a19f1bebf58c7f197a581dc8fb528bbart 3436d956dc21b6a81f0c67ad18ac61867da0d5922a3bartstatic void DRD_(thread_delayed_delete)(const DrdThreadId tid) 3446d956dc21b6a81f0c67ad18ac61867da0d5922a3bart{ 3451e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian UInt j; 3466d956dc21b6a81f0c67ad18ac61867da0d5922a3bart 3476d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[tid].vg_thread_exists = False; 3486d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[tid].posix_thread_exists = False; 3496d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[tid].deletion_seq = s_deletion_head++; 3506d956dc21b6a81f0c67ad18ac61867da0d5922a3bart#if 0 3516d956dc21b6a81f0c67ad18ac61867da0d5922a3bart VG_(message)(Vg_DebugMsg, "Adding thread %d to the deletion list\n", tid); 3526d956dc21b6a81f0c67ad18ac61867da0d5922a3bart#endif 3536d956dc21b6a81f0c67ad18ac61867da0d5922a3bart if (s_deletion_head - s_deletion_tail >= s_join_list_vol) { 3546d956dc21b6a81f0c67ad18ac61867da0d5922a3bart for (j = 0; j < DRD_N_THREADS; ++j) { 3556d956dc21b6a81f0c67ad18ac61867da0d5922a3bart if (DRD_(IsValidDrdThreadId)(j) 3566d956dc21b6a81f0c67ad18ac61867da0d5922a3bart && DRD_(g_threadinfo)[j].deletion_seq == s_deletion_tail) 3576d956dc21b6a81f0c67ad18ac61867da0d5922a3bart { 3586d956dc21b6a81f0c67ad18ac61867da0d5922a3bart s_deletion_tail++; 3596d956dc21b6a81f0c67ad18ac61867da0d5922a3bart#if 0 3606d956dc21b6a81f0c67ad18ac61867da0d5922a3bart VG_(message)(Vg_DebugMsg, "Delayed delete of thread %d\n", j); 3616d956dc21b6a81f0c67ad18ac61867da0d5922a3bart#endif 3626d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(thread_delete)(j, False); 3636d956dc21b6a81f0c67ad18ac61867da0d5922a3bart break; 3646d956dc21b6a81f0c67ad18ac61867da0d5922a3bart } 3656d956dc21b6a81f0c67ad18ac61867da0d5922a3bart } 3666d956dc21b6a81f0c67ad18ac61867da0d5922a3bart } 3676d956dc21b6a81f0c67ad18ac61867da0d5922a3bart} 3686d956dc21b6a81f0c67ad18ac61867da0d5922a3bart 369324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 370324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Process VG_USERREQ__POST_THREAD_JOIN. This client request is invoked just 371324a23bea57e0bfc27d9442ec00a8eee8294f01abart * after thread drd_joiner joined thread drd_joinee. 372324a23bea57e0bfc27d9442ec00a8eee8294f01abart */ 37309dc13f324a19f1bebf58c7f197a581dc8fb528bbartvoid DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee) 37409dc13f324a19f1bebf58c7f197a581dc8fb528bbart{ 375bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(drd_joiner)); 376bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(drd_joinee)); 3777627be3e26162e4f59ccfd35eaf31495ddefdf9bbart 378bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(thread_new_segment)(drd_joiner); 3798f822af9b234e7c553c408eba65a641c4773457fbart DRD_(thread_combine_vc_join)(drd_joiner, drd_joinee); 3807627be3e26162e4f59ccfd35eaf31495ddefdf9bbart DRD_(thread_new_segment)(drd_joinee); 381bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 382bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (s_trace_fork_join) 383bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 384bedfd237fbdc80d0c917cfcb85a94b5561c92633bart const ThreadId joiner = DRD_(DrdThreadIdToVgThreadId)(drd_joiner); 385bedfd237fbdc80d0c917cfcb85a94b5561c92633bart const unsigned msg_size = 256; 38619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* msg; 387bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 388bedfd237fbdc80d0c917cfcb85a94b5561c92633bart msg = VG_(malloc)("drd.main.dptj.1", msg_size); 389f5d8e65f2c61c399420cde0afd70204e0c0f7c4cflorian 390bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(snprintf)(msg, msg_size, 39163c92ea799549976957f5b4d54ede744f762c56fbart "drd_post_thread_join joiner = %d, joinee = %d", 39263c92ea799549976957f5b4d54ede744f762c56fbart drd_joiner, drd_joinee); 393bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (joiner) 394bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 39519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* vc; 3968f822af9b234e7c553c408eba65a641c4773457fbart 3978f822af9b234e7c553c408eba65a641c4773457fbart vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(drd_joiner)); 398bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(snprintf)(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg), 3998f822af9b234e7c553c408eba65a641c4773457fbart ", new vc: %s", vc); 4008f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(vc); 401bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 402ad994e885caeb5241cbedf4e47e7821cf164f4e7bart DRD_(trace_msg)("%pS", msg); 403bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(free)(msg); 404bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 405bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 406bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (! DRD_(get_check_stack_accesses)()) 407bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 408bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(finish_suppression)(DRD_(thread_get_stack_max)(drd_joinee) 409bedfd237fbdc80d0c917cfcb85a94b5561c92633bart - DRD_(thread_get_stack_size)(drd_joinee), 410bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(thread_get_stack_max)(drd_joinee)); 411bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 412bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(clientobj_delete_thread)(drd_joinee); 4136d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(thread_delayed_delete)(drd_joinee); 41409dc13f324a19f1bebf58c7f197a581dc8fb528bbart} 41509dc13f324a19f1bebf58c7f197a581dc8fb528bbart 416324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 417324a23bea57e0bfc27d9442ec00a8eee8294f01abart * NPTL hack: NPTL allocates the 'struct pthread' on top of the stack, 418324a23bea57e0bfc27d9442ec00a8eee8294f01abart * and accesses this data structure from multiple threads without locking. 419324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Any conflicting accesses in the range stack_startup..stack_max will be 420324a23bea57e0bfc27d9442ec00a8eee8294f01abart * ignored. 421324a23bea57e0bfc27d9442ec00a8eee8294f01abart */ 42262a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_stack_startup)(const DrdThreadId tid, 42362a784c9382fdf7184065ad76ae8d3b905605f21bart const Addr stack_startup) 424af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 425bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 426bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 427bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[tid].stack_min <= stack_startup); 428bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(stack_startup <= DRD_(g_threadinfo)[tid].stack_max); 429bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].stack_startup = stack_startup; 430af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 431af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 43286a87df5949beb1f89ebbed923068faed08d048cbart/** Return the stack pointer for the specified thread. */ 43362a784c9382fdf7184065ad76ae8d3b905605f21bartAddr DRD_(thread_get_stack_min)(const DrdThreadId tid) 434af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 435bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 436bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 437bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].stack_min; 438af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 439af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 44086a87df5949beb1f89ebbed923068faed08d048cbart/** 44186a87df5949beb1f89ebbed923068faed08d048cbart * Return the lowest value that was ever assigned to the stack pointer 44286a87df5949beb1f89ebbed923068faed08d048cbart * for the specified thread. 44386a87df5949beb1f89ebbed923068faed08d048cbart */ 44462a784c9382fdf7184065ad76ae8d3b905605f21bartAddr DRD_(thread_get_stack_min_min)(const DrdThreadId tid) 445cac5346ef470359941b12d879608e5f3386b44febart{ 446bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 447bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 448bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].stack_min_min; 449cac5346ef470359941b12d879608e5f3386b44febart} 450cac5346ef470359941b12d879608e5f3386b44febart 45186a87df5949beb1f89ebbed923068faed08d048cbart/** Return the top address for the stack of the specified thread. */ 45262a784c9382fdf7184065ad76ae8d3b905605f21bartAddr DRD_(thread_get_stack_max)(const DrdThreadId tid) 453af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 454bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 455bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 456bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].stack_max; 457af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 458af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 45986a87df5949beb1f89ebbed923068faed08d048cbart/** Return the maximum stack size for the specified thread. */ 46062a784c9382fdf7184065ad76ae8d3b905605f21bartSizeT DRD_(thread_get_stack_size)(const DrdThreadId tid) 461cac5346ef470359941b12d879608e5f3386b44febart{ 462bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 463bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 464bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].stack_size; 465cac5346ef470359941b12d879608e5f3386b44febart} 466cac5346ef470359941b12d879608e5f3386b44febart 467383d613d286501412f1760c8eaafaeb8c518b344bartBool DRD_(thread_get_on_alt_stack)(const DrdThreadId tid) 468383d613d286501412f1760c8eaafaeb8c518b344bart{ 469383d613d286501412f1760c8eaafaeb8c518b344bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 470383d613d286501412f1760c8eaafaeb8c518b344bart && tid != DRD_INVALID_THREADID); 471383d613d286501412f1760c8eaafaeb8c518b344bart return DRD_(g_threadinfo)[tid].on_alt_stack; 472383d613d286501412f1760c8eaafaeb8c518b344bart} 473383d613d286501412f1760c8eaafaeb8c518b344bart 474383d613d286501412f1760c8eaafaeb8c518b344bartvoid DRD_(thread_set_on_alt_stack)(const DrdThreadId tid, 475383d613d286501412f1760c8eaafaeb8c518b344bart const Bool on_alt_stack) 476383d613d286501412f1760c8eaafaeb8c518b344bart{ 477383d613d286501412f1760c8eaafaeb8c518b344bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 478383d613d286501412f1760c8eaafaeb8c518b344bart && tid != DRD_INVALID_THREADID); 479383d613d286501412f1760c8eaafaeb8c518b344bart tl_assert(on_alt_stack == !!on_alt_stack); 480383d613d286501412f1760c8eaafaeb8c518b344bart DRD_(g_threadinfo)[tid].on_alt_stack = on_alt_stack; 481383d613d286501412f1760c8eaafaeb8c518b344bart} 482383d613d286501412f1760c8eaafaeb8c518b344bart 483383d613d286501412f1760c8eaafaeb8c518b344bartInt DRD_(thread_get_threads_on_alt_stack)(void) 484383d613d286501412f1760c8eaafaeb8c518b344bart{ 4851e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian int n = 0; 486383d613d286501412f1760c8eaafaeb8c518b344bart 4871e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florian for (UInt i = 1; i < DRD_N_THREADS; i++) 488383d613d286501412f1760c8eaafaeb8c518b344bart n += DRD_(g_threadinfo)[i].on_alt_stack; 489383d613d286501412f1760c8eaafaeb8c518b344bart return n; 490383d613d286501412f1760c8eaafaeb8c518b344bart} 491383d613d286501412f1760c8eaafaeb8c518b344bart 49209dc13f324a19f1bebf58c7f197a581dc8fb528bbart/** 4936d956dc21b6a81f0c67ad18ac61867da0d5922a3bart * Clean up thread-specific data structures. 494af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 4959194e93ab737439d653498ee43df4bae7989ad3dbartvoid DRD_(thread_delete)(const DrdThreadId tid, const Bool detached) 496af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 497bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* sg; 498bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* sg_prev; 499bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 500bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(tid)); 501bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 502bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[tid].synchr_nesting >= 0); 50391b7ec3660efe16790bc337190a1c948beaab0a5bart for (sg = DRD_(g_threadinfo)[tid].sg_last; sg; sg = sg_prev) { 50491b7ec3660efe16790bc337190a1c948beaab0a5bart sg_prev = sg->thr_prev; 50591b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_next = NULL; 50691b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_prev = NULL; 507bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(sg_put)(sg); 508bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 5096d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[tid].valid = False; 510bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].vg_thread_exists = False; 511bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].posix_thread_exists = False; 5129194e93ab737439d653498ee43df4bae7989ad3dbart if (detached) 5139194e93ab737439d653498ee43df4bae7989ad3dbart DRD_(g_threadinfo)[tid].detached_posix_thread = False; 5149194e93ab737439d653498ee43df4bae7989ad3dbart else 5159194e93ab737439d653498ee43df4bae7989ad3dbart tl_assert(!DRD_(g_threadinfo)[tid].detached_posix_thread); 51691b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_first = NULL; 51791b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_last = NULL; 518bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 51991b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(!DRD_(IsValidDrdThreadId)(tid)); 520af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 521af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 522324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 523324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Called after a thread performed its last memory access and before 524324a23bea57e0bfc27d9442ec00a8eee8294f01abart * thread_delete() is called. Note: thread_delete() is only called for 525324a23bea57e0bfc27d9442ec00a8eee8294f01abart * joinable threads, not for detached threads. 526324a23bea57e0bfc27d9442ec00a8eee8294f01abart */ 52762a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_finished)(const DrdThreadId tid) 528af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 529bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 530bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 531bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 532bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].vg_thread_exists = False; 533bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 534bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (DRD_(g_threadinfo)[tid].detached_posix_thread) 535bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 536bedfd237fbdc80d0c917cfcb85a94b5561c92633bart /* 537bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * Once a detached thread has finished, its stack is deallocated and 538bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * should no longer be taken into account when computing the conflict set. 539bedfd237fbdc80d0c917cfcb85a94b5561c92633bart */ 540bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].stack_min = DRD_(g_threadinfo)[tid].stack_max; 541bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 542bedfd237fbdc80d0c917cfcb85a94b5561c92633bart /* 543bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * For a detached thread, calling pthread_exit() invalidates the 544bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * POSIX thread ID associated with the detached thread. For joinable 545bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * POSIX threads however, the POSIX thread ID remains live after the 546bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * pthread_exit() call until pthread_join() is called. 547bedfd237fbdc80d0c917cfcb85a94b5561c92633bart */ 548bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].posix_thread_exists = False; 549bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 550af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 551af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 5525c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart/** Called just after fork() in the child process. */ 5535c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bartvoid DRD_(drd_thread_atfork_child)(const DrdThreadId tid) 5545c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart{ 5555c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart unsigned i; 5565c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart 5575c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart for (i = 1; i < DRD_N_THREADS; i++) 5585c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart { 5595c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart if (i == tid) 5605c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart continue; 5615c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart if (DRD_(IsValidDrdThreadId(i))) 5629194e93ab737439d653498ee43df4bae7989ad3dbart DRD_(thread_delete)(i, True); 5635c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart tl_assert(!DRD_(IsValidDrdThreadId(i))); 564f7a5b3fb7545645c47e3ee5d8fc1d66ea09f679cbart } 5657692f169aa556ea177b8e949abff2d3e224580e1bart 5667692f169aa556ea177b8e949abff2d3e224580e1bart DRD_(bm_cleanup)(DRD_(g_conflict_set)); 5677692f169aa556ea177b8e949abff2d3e224580e1bart DRD_(bm_init)(DRD_(g_conflict_set)); 5685c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart} 5695c7e6b69ccaecc32ff43d7f3cb9573f3901d19f0bart 5709b2974ad8c14abb2a0cbcbc66e43f9d97d3deaccbart/** Called just before pthread_cancel(). */ 57162a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_pre_cancel)(const DrdThreadId tid) 572af0691b41efd73639efbeaddf9c6238a77089f77bart{ 573bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 574bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 575bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID); 576af0691b41efd73639efbeaddf9c6238a77089f77bart 5770c0cd77a6ffda2fd1abf4877ef125889c2e07f9ebart if (DRD_(thread_get_trace_fork_join)()) 578ad994e885caeb5241cbedf4e47e7821cf164f4e7bart DRD_(trace_msg)("[%d] drd_thread_pre_cancel %d", 579b92ff0fd192dd05700f7d20db00795965e20b5c5bart DRD_(g_drd_running_tid), tid); 580af0691b41efd73639efbeaddf9c6238a77089f77bart} 581af0691b41efd73639efbeaddf9c6238a77089f77bart 582e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart/** 583e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart * Store the POSIX thread ID for the specified thread. 584e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart * 585e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart * @note This function can be called two times for the same thread -- see also 586e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart * the comment block preceding the pthread_create() wrapper in 587e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart * drd_pthread_intercepts.c. 588e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart */ 58962a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_pthreadid)(const DrdThreadId tid, const PThreadId ptid) 590af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 591bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 592bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 593e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart tl_assert(DRD_(g_threadinfo)[tid].pt_threadid == INVALID_POSIX_THREADID 594e7dff2479d4d1e0024f0889c54c4578d427ab0a2bart || DRD_(g_threadinfo)[tid].pt_threadid == ptid); 595bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(ptid != INVALID_POSIX_THREADID); 596bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].posix_thread_exists = True; 597bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].pt_threadid = ptid; 598af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 599af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 60086a87df5949beb1f89ebbed923068faed08d048cbart/** Returns true for joinable threads and false for detached threads. */ 60162a784c9382fdf7184065ad76ae8d3b905605f21bartBool DRD_(thread_get_joinable)(const DrdThreadId tid) 602af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 603bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 604bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 605bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return ! DRD_(g_threadinfo)[tid].detached_posix_thread; 606af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 607af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 60886a87df5949beb1f89ebbed923068faed08d048cbart/** Store the thread mode: joinable or detached. */ 6094df0bfc0614379192c780c944415dc420d9cfe8epetarj#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux) 6105db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* There is a cse related issue in gcc for MIPS. Optimization level 6115db15403e889d4db339b342bc2a824ef0bfaa654sewardj has to be lowered, so cse related optimizations are not 6125db15403e889d4db339b342bc2a824ef0bfaa654sewardj included.*/ 6135db15403e889d4db339b342bc2a824ef0bfaa654sewardj __attribute__((optimize("O1"))) 6145db15403e889d4db339b342bc2a824ef0bfaa654sewardj#endif 61562a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_joinable)(const DrdThreadId tid, const Bool joinable) 616af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 617bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 618bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 619d56b7e2bd0e7b56f99c0e2805e6c1cd57bd31427sewardj tl_assert((!! joinable) == joinable); 620bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID); 6218f822af9b234e7c553c408eba65a641c4773457fbart 622bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[tid].detached_posix_thread = ! joinable; 623af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 624af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 625dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart/** Tells DRD that the calling thread is about to enter pthread_create(). */ 626dd75cdfe7612f58bdba8e3a16d34ee32eef85980bartvoid DRD_(thread_entering_pthread_create)(const DrdThreadId tid) 627dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart{ 628dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 629dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart && tid != DRD_INVALID_THREADID); 630dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID); 631dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(DRD_(g_threadinfo)[tid].pthread_create_nesting_level >= 0); 632dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart 633dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart DRD_(g_threadinfo)[tid].pthread_create_nesting_level++; 634dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart} 635dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart 636dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart/** Tells DRD that the calling thread has left pthread_create(). */ 637dd75cdfe7612f58bdba8e3a16d34ee32eef85980bartvoid DRD_(thread_left_pthread_create)(const DrdThreadId tid) 638dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart{ 639dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 640dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart && tid != DRD_INVALID_THREADID); 641dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID); 642dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart tl_assert(DRD_(g_threadinfo)[tid].pthread_create_nesting_level > 0); 643dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart 644dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart DRD_(g_threadinfo)[tid].pthread_create_nesting_level--; 645dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart} 646dd75cdfe7612f58bdba8e3a16d34ee32eef85980bart 647d45d99553c15a361bb797d21ec6afb9bad22d2d4bart/** Obtain the thread number and the user-assigned thread name. */ 64819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* DRD_(thread_get_name)(const DrdThreadId tid) 649d45d99553c15a361bb797d21ec6afb9bad22d2d4bart{ 650d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 651d45d99553c15a361bb797d21ec6afb9bad22d2d4bart && tid != DRD_INVALID_THREADID); 652d45d99553c15a361bb797d21ec6afb9bad22d2d4bart 653d45d99553c15a361bb797d21ec6afb9bad22d2d4bart return DRD_(g_threadinfo)[tid].name; 654d45d99553c15a361bb797d21ec6afb9bad22d2d4bart} 655d45d99553c15a361bb797d21ec6afb9bad22d2d4bart 656d45d99553c15a361bb797d21ec6afb9bad22d2d4bart/** Set the name of the specified thread. */ 65719f91bbaedb4caef8a60ce94b0f507193cc0bc10florianvoid DRD_(thread_set_name)(const DrdThreadId tid, const HChar* const name) 658d45d99553c15a361bb797d21ec6afb9bad22d2d4bart{ 659d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 660d45d99553c15a361bb797d21ec6afb9bad22d2d4bart && tid != DRD_INVALID_THREADID); 66131b983d29affe6c30a2283be8824c6d75c74d848bart 662d45d99553c15a361bb797d21ec6afb9bad22d2d4bart if (name == NULL || name[0] == 0) 663d45d99553c15a361bb797d21ec6afb9bad22d2d4bart VG_(snprintf)(DRD_(g_threadinfo)[tid].name, 664d45d99553c15a361bb797d21ec6afb9bad22d2d4bart sizeof(DRD_(g_threadinfo)[tid].name), 665d45d99553c15a361bb797d21ec6afb9bad22d2d4bart "Thread %d", 666d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tid); 667d45d99553c15a361bb797d21ec6afb9bad22d2d4bart else 668d45d99553c15a361bb797d21ec6afb9bad22d2d4bart VG_(snprintf)(DRD_(g_threadinfo)[tid].name, 669d45d99553c15a361bb797d21ec6afb9bad22d2d4bart sizeof(DRD_(g_threadinfo)[tid].name), 670d45d99553c15a361bb797d21ec6afb9bad22d2d4bart "Thread %d (%s)", 671d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tid, name); 672d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(g_threadinfo)[tid].name[sizeof(DRD_(g_threadinfo)[tid].name) - 1] = 0; 673d45d99553c15a361bb797d21ec6afb9bad22d2d4bart} 674d45d99553c15a361bb797d21ec6afb9bad22d2d4bart 67586a87df5949beb1f89ebbed923068faed08d048cbart/** 67686a87df5949beb1f89ebbed923068faed08d048cbart * Update s_vg_running_tid, DRD_(g_drd_running_tid) and recalculate the 67786a87df5949beb1f89ebbed923068faed08d048cbart * conflict set. 67886a87df5949beb1f89ebbed923068faed08d048cbart */ 67962a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_vg_running_tid)(const ThreadId vg_tid) 6808b09d4f037c6399658b610228c7bbc0c6133d9dasewardj{ 681bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(vg_tid != VG_INVALID_THREADID); 6828b09d4f037c6399658b610228c7bbc0c6133d9dasewardj 683bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (vg_tid != s_vg_running_tid) 684bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 685bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(thread_set_running_tid)(vg_tid, 686bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(VgThreadIdToDrdThreadId)(vg_tid)); 687bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 6888b09d4f037c6399658b610228c7bbc0c6133d9dasewardj 689bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(s_vg_running_tid != VG_INVALID_THREADID); 690bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 691af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 692af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 69386a87df5949beb1f89ebbed923068faed08d048cbart/** 69486a87df5949beb1f89ebbed923068faed08d048cbart * Update s_vg_running_tid, DRD_(g_drd_running_tid) and recalculate the 69586a87df5949beb1f89ebbed923068faed08d048cbart * conflict set. 69686a87df5949beb1f89ebbed923068faed08d048cbart */ 69762a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_set_running_tid)(const ThreadId vg_tid, 69862a784c9382fdf7184065ad76ae8d3b905605f21bart const DrdThreadId drd_tid) 699af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 700bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(vg_tid != VG_INVALID_THREADID); 701bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(drd_tid != DRD_INVALID_THREADID); 70231b983d29affe6c30a2283be8824c6d75c74d848bart 703bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (vg_tid != s_vg_running_tid) 704bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 705bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (s_trace_context_switches 706bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID) 707bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 708bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(message)(Vg_DebugMsg, 70963c92ea799549976957f5b4d54ede744f762c56fbart "Context switch from thread %d to thread %d;" 7101e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj " segments: %llu\n", 71163c92ea799549976957f5b4d54ede744f762c56fbart DRD_(g_drd_running_tid), drd_tid, 712bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(sg_get_segments_alive_count)()); 713bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 714bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_vg_running_tid = vg_tid; 715bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_drd_running_tid) = drd_tid; 716bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_compute_conflict_set(&DRD_(g_conflict_set), drd_tid); 717bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_context_switch_count++; 718bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 719bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 720bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(s_vg_running_tid != VG_INVALID_THREADID); 721bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 722af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 723af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 72486a87df5949beb1f89ebbed923068faed08d048cbart/** 72586a87df5949beb1f89ebbed923068faed08d048cbart * Increase the synchronization nesting counter. Must be called before the 72686a87df5949beb1f89ebbed923068faed08d048cbart * client calls a synchronization function. 72786a87df5949beb1f89ebbed923068faed08d048cbart */ 72862a784c9382fdf7184065ad76ae8d3b905605f21bartint DRD_(thread_enter_synchr)(const DrdThreadId tid) 7290268dfacec38138a01a58d05a038826e26b6c436bart{ 730bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(tid)); 731bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].synchr_nesting++; 7320268dfacec38138a01a58d05a038826e26b6c436bart} 7330268dfacec38138a01a58d05a038826e26b6c436bart 73486a87df5949beb1f89ebbed923068faed08d048cbart/** 73586a87df5949beb1f89ebbed923068faed08d048cbart * Decrease the synchronization nesting counter. Must be called after the 73686a87df5949beb1f89ebbed923068faed08d048cbart * client left a synchronization function. 73786a87df5949beb1f89ebbed923068faed08d048cbart */ 73862a784c9382fdf7184065ad76ae8d3b905605f21bartint DRD_(thread_leave_synchr)(const DrdThreadId tid) 7390268dfacec38138a01a58d05a038826e26b6c436bart{ 740bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(tid)); 741bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(g_threadinfo)[tid].synchr_nesting >= 1); 742bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return --DRD_(g_threadinfo)[tid].synchr_nesting; 7430268dfacec38138a01a58d05a038826e26b6c436bart} 7440268dfacec38138a01a58d05a038826e26b6c436bart 74586a87df5949beb1f89ebbed923068faed08d048cbart/** Returns the synchronization nesting counter. */ 74662a784c9382fdf7184065ad76ae8d3b905605f21bartint DRD_(thread_get_synchr_nesting_count)(const DrdThreadId tid) 7470268dfacec38138a01a58d05a038826e26b6c436bart{ 748bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(DRD_(IsValidDrdThreadId)(tid)); 749bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return DRD_(g_threadinfo)[tid].synchr_nesting; 7500268dfacec38138a01a58d05a038826e26b6c436bart} 7510268dfacec38138a01a58d05a038826e26b6c436bart 7521a473c757cae99f11477440d5473be6e5c95e0cebart/** Append a new segment at the end of the segment list. */ 75362a784c9382fdf7184065ad76ae8d3b905605f21bartstatic 75486a87df5949beb1f89ebbed923068faed08d048cbartvoid thread_append_segment(const DrdThreadId tid, Segment* const sg) 755af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 756bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 757bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 7588f822af9b234e7c553c408eba65a641c4773457fbart 7598f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 7608f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); 7618f822af9b234e7c553c408eba65a641c4773457fbart#endif 7628f822af9b234e7c553c408eba65a641c4773457fbart 76391b7ec3660efe16790bc337190a1c948beaab0a5bart // add at tail 76491b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_prev = DRD_(g_threadinfo)[tid].sg_last; 76591b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_next = NULL; 76691b7ec3660efe16790bc337190a1c948beaab0a5bart if (DRD_(g_threadinfo)[tid].sg_last) 76791b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_last->thr_next = sg; 76891b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_last = sg; 76991b7ec3660efe16790bc337190a1c948beaab0a5bart if (DRD_(g_threadinfo)[tid].sg_first == NULL) 77091b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_first = sg; 7718f822af9b234e7c553c408eba65a641c4773457fbart 7728f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 7738f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); 7748f822af9b234e7c553c408eba65a641c4773457fbart#endif 775af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 776af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 777324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 778324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Remove a segment from the segment list of thread threadid, and free the 779324a23bea57e0bfc27d9442ec00a8eee8294f01abart * associated memory. 780af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 78162a784c9382fdf7184065ad76ae8d3b905605f21bartstatic 78286a87df5949beb1f89ebbed923068faed08d048cbartvoid thread_discard_segment(const DrdThreadId tid, Segment* const sg) 783af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 784bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 785bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 7868f822af9b234e7c553c408eba65a641c4773457fbart 7878f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 7888f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); 7898f822af9b234e7c553c408eba65a641c4773457fbart#endif 790bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 79191b7ec3660efe16790bc337190a1c948beaab0a5bart if (sg->thr_prev) 79291b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_prev->thr_next = sg->thr_next; 79391b7ec3660efe16790bc337190a1c948beaab0a5bart if (sg->thr_next) 79491b7ec3660efe16790bc337190a1c948beaab0a5bart sg->thr_next->thr_prev = sg->thr_prev; 79591b7ec3660efe16790bc337190a1c948beaab0a5bart if (sg == DRD_(g_threadinfo)[tid].sg_first) 79691b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_first = sg->thr_next; 79791b7ec3660efe16790bc337190a1c948beaab0a5bart if (sg == DRD_(g_threadinfo)[tid].sg_last) 79891b7ec3660efe16790bc337190a1c948beaab0a5bart DRD_(g_threadinfo)[tid].sg_last = sg->thr_prev; 799bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(sg_put)(sg); 800bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 8018f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 8028f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); 8038f822af9b234e7c553c408eba65a641c4773457fbart#endif 804af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 805af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 80686a87df5949beb1f89ebbed923068faed08d048cbart/** 80786a87df5949beb1f89ebbed923068faed08d048cbart * Returns a pointer to the vector clock of the most recent segment associated 80886a87df5949beb1f89ebbed923068faed08d048cbart * with thread 'tid'. 80986a87df5949beb1f89ebbed923068faed08d048cbart */ 81062a784c9382fdf7184065ad76ae8d3b905605f21bartVectorClock* DRD_(thread_get_vc)(const DrdThreadId tid) 811af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 81291b7ec3660efe16790bc337190a1c948beaab0a5bart Segment* latest_sg; 813e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 814bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 815bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 81691b7ec3660efe16790bc337190a1c948beaab0a5bart latest_sg = DRD_(g_threadinfo)[tid].sg_last; 81791b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(latest_sg); 81891b7ec3660efe16790bc337190a1c948beaab0a5bart return &latest_sg->vc; 819af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 820af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 821324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 822324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Return the latest segment of thread 'tid' and increment its reference count. 823a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart */ 82462a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid) 825a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart{ 82691b7ec3660efe16790bc337190a1c948beaab0a5bart Segment* latest_sg; 827e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 828bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(sg); 829bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 830bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 83191b7ec3660efe16790bc337190a1c948beaab0a5bart latest_sg = DRD_(g_threadinfo)[tid].sg_last; 83291b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(latest_sg); 833a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart 834bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(sg_put)(*sg); 83591b7ec3660efe16790bc337190a1c948beaab0a5bart *sg = DRD_(sg_get)(latest_sg); 836a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart} 837a2b6e1bbcc45fcb42ac0441a2e5b4d40c3671ec6bart 838af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/** 839af44c8236f7a73e71b16b707bba56f33af4d01cesewardj * Compute the minimum of all latest vector clocks of all threads 840af44c8236f7a73e71b16b707bba56f33af4d01cesewardj * (Michiel Ronsse calls this "clock snooping" in his papers about DIOTA). 84186a87df5949beb1f89ebbed923068faed08d048cbart * 842af44c8236f7a73e71b16b707bba56f33af4d01cesewardj * @param vc pointer to a vectorclock, holds result upon return. 843af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 84462a784c9382fdf7184065ad76ae8d3b905605f21bartstatic void DRD_(thread_compute_minimum_vc)(VectorClock* vc) 845af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 846bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 847bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Bool first; 848bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* latest_sg; 849bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 850bedfd237fbdc80d0c917cfcb85a94b5561c92633bart first = True; 8518f822af9b234e7c553c408eba65a641c4773457fbart for (i = 0; i < DRD_N_THREADS; i++) 852bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 85391b7ec3660efe16790bc337190a1c948beaab0a5bart latest_sg = DRD_(g_threadinfo)[i].sg_last; 85491b7ec3660efe16790bc337190a1c948beaab0a5bart if (latest_sg) { 855bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (first) 856bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_assign)(vc, &latest_sg->vc); 857bedfd237fbdc80d0c917cfcb85a94b5561c92633bart else 858bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_min)(vc, &latest_sg->vc); 859bedfd237fbdc80d0c917cfcb85a94b5561c92633bart first = False; 860bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 861bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 862af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 863af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 86486a87df5949beb1f89ebbed923068faed08d048cbart/** 86586a87df5949beb1f89ebbed923068faed08d048cbart * Compute the maximum of all latest vector clocks of all threads. 86686a87df5949beb1f89ebbed923068faed08d048cbart * 86786a87df5949beb1f89ebbed923068faed08d048cbart * @param vc pointer to a vectorclock, holds result upon return. 86886a87df5949beb1f89ebbed923068faed08d048cbart */ 86962a784c9382fdf7184065ad76ae8d3b905605f21bartstatic void DRD_(thread_compute_maximum_vc)(VectorClock* vc) 870af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 871bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 872bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Bool first; 873bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* latest_sg; 874bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 875bedfd237fbdc80d0c917cfcb85a94b5561c92633bart first = True; 8768f822af9b234e7c553c408eba65a641c4773457fbart for (i = 0; i < DRD_N_THREADS; i++) 877bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 87891b7ec3660efe16790bc337190a1c948beaab0a5bart latest_sg = DRD_(g_threadinfo)[i].sg_last; 87991b7ec3660efe16790bc337190a1c948beaab0a5bart if (latest_sg) { 880bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (first) 881bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_assign)(vc, &latest_sg->vc); 882bedfd237fbdc80d0c917cfcb85a94b5561c92633bart else 883bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_combine)(vc, &latest_sg->vc); 884bedfd237fbdc80d0c917cfcb85a94b5561c92633bart first = False; 885bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 886bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 887af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 888af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 889af44c8236f7a73e71b16b707bba56f33af4d01cesewardj/** 8905bd9f2d42ba9440b528b1f926dd57b4652cb0583bart * Discard all segments that have a defined order against the latest vector 89186a87df5949beb1f89ebbed923068faed08d048cbart * clock of all threads -- these segments can no longer be involved in a 892af44c8236f7a73e71b16b707bba56f33af4d01cesewardj * data race. 893af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 8948f822af9b234e7c553c408eba65a641c4773457fbartstatic void thread_discard_ordered_segments(void) 895af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 896bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 897bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VectorClock thread_vc_min; 898bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 899bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_discard_ordered_segments_count++; 900bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 901bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_init)(&thread_vc_min, 0, 0); 902bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(thread_compute_minimum_vc)(&thread_vc_min); 903bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (DRD_(sg_get_trace)()) 904bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 90519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar *vc_min, *vc_max; 906bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VectorClock thread_vc_max; 907bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 908bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_init)(&thread_vc_max, 0, 0); 909bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(thread_compute_maximum_vc)(&thread_vc_max); 9108f822af9b234e7c553c408eba65a641c4773457fbart vc_min = DRD_(vc_aprint)(&thread_vc_min); 9118f822af9b234e7c553c408eba65a641c4773457fbart vc_max = DRD_(vc_aprint)(&thread_vc_max); 9128f822af9b234e7c553c408eba65a641c4773457fbart VG_(message)(Vg_DebugMsg, 9131e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj "Discarding ordered segments -- min vc is %s, max vc is %s\n", 9148f822af9b234e7c553c408eba65a641c4773457fbart vc_min, vc_max); 9158f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(vc_min); 9168f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(vc_max); 917bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_cleanup)(&thread_vc_max); 918bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 919bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 92091b7ec3660efe16790bc337190a1c948beaab0a5bart for (i = 0; i < DRD_N_THREADS; i++) { 921bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* sg; 922bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* sg_next; 923e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 92491b7ec3660efe16790bc337190a1c948beaab0a5bart for (sg = DRD_(g_threadinfo)[i].sg_first; 92591b7ec3660efe16790bc337190a1c948beaab0a5bart sg && (sg_next = sg->thr_next) 92691b7ec3660efe16790bc337190a1c948beaab0a5bart && DRD_(vc_lte)(&sg->vc, &thread_vc_min); 92791b7ec3660efe16790bc337190a1c948beaab0a5bart sg = sg_next) 92891b7ec3660efe16790bc337190a1c948beaab0a5bart { 929bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_discard_segment(i, sg); 930bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 931bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 932bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(vc_cleanup)(&thread_vc_min); 933af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 934af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 935324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 9368f822af9b234e7c553c408eba65a641c4773457fbart * An implementation of the property 'equiv(sg1, sg2)' as defined in the paper 9378f822af9b234e7c553c408eba65a641c4773457fbart * by Mark Christiaens e.a. The property equiv(sg1, sg2) holds if and only if 9388f822af9b234e7c553c408eba65a641c4773457fbart * all segments in the set CS are ordered consistently against both sg1 and 9398f822af9b234e7c553c408eba65a641c4773457fbart * sg2. The set CS is defined as the set of segments that can immediately 9408f822af9b234e7c553c408eba65a641c4773457fbart * precede future segments via inter-thread synchronization operations. In 9418f822af9b234e7c553c408eba65a641c4773457fbart * DRD the set CS consists of the latest segment of each thread combined with 9428f822af9b234e7c553c408eba65a641c4773457fbart * all segments for which the reference count is strictly greater than one. 9438f822af9b234e7c553c408eba65a641c4773457fbart * The code below is an optimized version of the following: 9448f822af9b234e7c553c408eba65a641c4773457fbart * 9458f822af9b234e7c553c408eba65a641c4773457fbart * for (i = 0; i < DRD_N_THREADS; i++) 9468f822af9b234e7c553c408eba65a641c4773457fbart * { 9478f822af9b234e7c553c408eba65a641c4773457fbart * Segment* sg; 9488f822af9b234e7c553c408eba65a641c4773457fbart * 9498f822af9b234e7c553c408eba65a641c4773457fbart * for (sg = DRD_(g_threadinfo)[i].first; sg; sg = sg->next) 9508f822af9b234e7c553c408eba65a641c4773457fbart * { 9518f822af9b234e7c553c408eba65a641c4773457fbart * if (sg == DRD_(g_threadinfo)[i].last || DRD_(sg_get_refcnt)(sg) > 1) 9528f822af9b234e7c553c408eba65a641c4773457fbart * { 9538f822af9b234e7c553c408eba65a641c4773457fbart * if ( DRD_(vc_lte)(&sg1->vc, &sg->vc) 9548f822af9b234e7c553c408eba65a641c4773457fbart * != DRD_(vc_lte)(&sg2->vc, &sg->vc) 9558f822af9b234e7c553c408eba65a641c4773457fbart * || DRD_(vc_lte)(&sg->vc, &sg1->vc) 9568f822af9b234e7c553c408eba65a641c4773457fbart * != DRD_(vc_lte)(&sg->vc, &sg2->vc)) 9578f822af9b234e7c553c408eba65a641c4773457fbart * { 9588f822af9b234e7c553c408eba65a641c4773457fbart * return False; 9598f822af9b234e7c553c408eba65a641c4773457fbart * } 9608f822af9b234e7c553c408eba65a641c4773457fbart * } 9618f822af9b234e7c553c408eba65a641c4773457fbart * } 9628f822af9b234e7c553c408eba65a641c4773457fbart * } 9638f822af9b234e7c553c408eba65a641c4773457fbart */ 9648f822af9b234e7c553c408eba65a641c4773457fbartstatic Bool thread_consistent_segment_ordering(const DrdThreadId tid, 9658f822af9b234e7c553c408eba65a641c4773457fbart Segment* const sg1, 9668f822af9b234e7c553c408eba65a641c4773457fbart Segment* const sg2) 9678f822af9b234e7c553c408eba65a641c4773457fbart{ 9688f822af9b234e7c553c408eba65a641c4773457fbart unsigned i; 9698f822af9b234e7c553c408eba65a641c4773457fbart 97091b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(sg1->thr_next); 97191b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(sg2->thr_next); 97291b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(sg1->thr_next == sg2); 9738f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(vc_lte)(&sg1->vc, &sg2->vc)); 9748f822af9b234e7c553c408eba65a641c4773457fbart 9758f822af9b234e7c553c408eba65a641c4773457fbart for (i = 0; i < DRD_N_THREADS; i++) 9768f822af9b234e7c553c408eba65a641c4773457fbart { 9778f822af9b234e7c553c408eba65a641c4773457fbart Segment* sg; 9788f822af9b234e7c553c408eba65a641c4773457fbart 97991b7ec3660efe16790bc337190a1c948beaab0a5bart for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) { 98091b7ec3660efe16790bc337190a1c948beaab0a5bart if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) { 9818f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(vc_lte)(&sg2->vc, &sg->vc)) 9828f822af9b234e7c553c408eba65a641c4773457fbart break; 9838f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(vc_lte)(&sg1->vc, &sg->vc)) 9848f822af9b234e7c553c408eba65a641c4773457fbart return False; 9858f822af9b234e7c553c408eba65a641c4773457fbart } 9868f822af9b234e7c553c408eba65a641c4773457fbart } 98791b7ec3660efe16790bc337190a1c948beaab0a5bart for (sg = DRD_(g_threadinfo)[i].sg_last; sg; sg = sg->thr_prev) { 98891b7ec3660efe16790bc337190a1c948beaab0a5bart if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) { 9898f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(vc_lte)(&sg->vc, &sg1->vc)) 9908f822af9b234e7c553c408eba65a641c4773457fbart break; 9918f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(vc_lte)(&sg->vc, &sg2->vc)) 9928f822af9b234e7c553c408eba65a641c4773457fbart return False; 9938f822af9b234e7c553c408eba65a641c4773457fbart } 9948f822af9b234e7c553c408eba65a641c4773457fbart } 9958f822af9b234e7c553c408eba65a641c4773457fbart } 9968f822af9b234e7c553c408eba65a641c4773457fbart return True; 9978f822af9b234e7c553c408eba65a641c4773457fbart} 9988f822af9b234e7c553c408eba65a641c4773457fbart 9998f822af9b234e7c553c408eba65a641c4773457fbart/** 1000324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Merge all segments that may be merged without triggering false positives 1001324a23bea57e0bfc27d9442ec00a8eee8294f01abart * or discarding real data races. For the theoretical background of segment 10028f822af9b234e7c553c408eba65a641c4773457fbart * merging, see also the following paper: Mark Christiaens, Michiel Ronsse 10038f822af9b234e7c553c408eba65a641c4773457fbart * and Koen De Bosschere. Bounding the number of segment histories during 10048f822af9b234e7c553c408eba65a641c4773457fbart * data race detection. Parallel Computing archive, Volume 28, Issue 9, 10058f822af9b234e7c553c408eba65a641c4773457fbart * pp 1221-1238, September 2002. This paper contains a proof that merging 10068f822af9b234e7c553c408eba65a641c4773457fbart * consecutive segments for which the property equiv(s1,s2) holds can be 10078f822af9b234e7c553c408eba65a641c4773457fbart * merged without reducing the accuracy of datarace detection. Furthermore 10088f822af9b234e7c553c408eba65a641c4773457fbart * it is also proven that the total number of all segments will never grow 10098f822af9b234e7c553c408eba65a641c4773457fbart * unbounded if all segments s1, s2 for which equiv(s1, s2) holds are merged 10108f822af9b234e7c553c408eba65a641c4773457fbart * every time a new segment is created. The property equiv(s1, s2) is defined 10118f822af9b234e7c553c408eba65a641c4773457fbart * as follows: equiv(s1, s2) <=> for all segments in the set CS, the vector 10128f822af9b234e7c553c408eba65a641c4773457fbart * clocks of segments s and s1 are ordered in the same way as those of segments 10138f822af9b234e7c553c408eba65a641c4773457fbart * s and s2. The set CS is defined as the set of existing segments s that have 10148f822af9b234e7c553c408eba65a641c4773457fbart * the potential to conflict with not yet created segments, either because the 10158f822af9b234e7c553c408eba65a641c4773457fbart * segment s is the latest segment of a thread or because it can become the 10168f822af9b234e7c553c408eba65a641c4773457fbart * immediate predecessor of a new segment due to a synchronization operation. 1017a9c37398e4565280266ce663a6c38c3518af2812bart */ 1018a9c37398e4565280266ce663a6c38c3518af2812bartstatic void thread_merge_segments(void) 1019a9c37398e4565280266ce663a6c38c3518af2812bart{ 1020bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 1021a9c37398e4565280266ce663a6c38c3518af2812bart 10228f822af9b234e7c553c408eba65a641c4773457fbart s_new_segments_since_last_merge = 0; 10238f822af9b234e7c553c408eba65a641c4773457fbart 10248f822af9b234e7c553c408eba65a641c4773457fbart for (i = 0; i < DRD_N_THREADS; i++) 1025bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 1026bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* sg; 1027a9c37398e4565280266ce663a6c38c3518af2812bart 10288f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 10298f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[i])); 10308f822af9b234e7c553c408eba65a641c4773457fbart#endif 1031a9c37398e4565280266ce663a6c38c3518af2812bart 103291b7ec3660efe16790bc337190a1c948beaab0a5bart for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) { 103391b7ec3660efe16790bc337190a1c948beaab0a5bart if (DRD_(sg_get_refcnt)(sg) == 1 && sg->thr_next) { 103491b7ec3660efe16790bc337190a1c948beaab0a5bart Segment* const sg_next = sg->thr_next; 1035e278ab506b9a73ef1c17a17077546b2de9a11d7cbart if (DRD_(sg_get_refcnt)(sg_next) == 1 103691b7ec3660efe16790bc337190a1c948beaab0a5bart && sg_next->thr_next 1037e278ab506b9a73ef1c17a17077546b2de9a11d7cbart && thread_consistent_segment_ordering(i, sg, sg_next)) 1038e278ab506b9a73ef1c17a17077546b2de9a11d7cbart { 1039e278ab506b9a73ef1c17a17077546b2de9a11d7cbart /* Merge sg and sg_next into sg. */ 1040e278ab506b9a73ef1c17a17077546b2de9a11d7cbart DRD_(sg_merge)(sg, sg_next); 1041e278ab506b9a73ef1c17a17077546b2de9a11d7cbart thread_discard_segment(i, sg_next); 1042e278ab506b9a73ef1c17a17077546b2de9a11d7cbart } 1043bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1044a9c37398e4565280266ce663a6c38c3518af2812bart } 1045a9c37398e4565280266ce663a6c38c3518af2812bart 10468f822af9b234e7c553c408eba65a641c4773457fbart#ifdef ENABLE_DRD_CONSISTENCY_CHECKS 10478f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[i])); 10488f822af9b234e7c553c408eba65a641c4773457fbart#endif 1049bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1050a9c37398e4565280266ce663a6c38c3518af2812bart} 1051a9c37398e4565280266ce663a6c38c3518af2812bart 1052324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 1053324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Create a new segment for the specified thread, and discard any segments 1054324a23bea57e0bfc27d9442ec00a8eee8294f01abart * that cannot cause races anymore. 1055af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 105662a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_new_segment)(const DrdThreadId tid) 1057af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 10588f822af9b234e7c553c408eba65a641c4773457fbart Segment* last_sg; 1059bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* new_sg; 1060d66e3a8e8c42b7c933c5e6ea0d9a9b4c8ac4cf49bart 1061bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1062bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 10638f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid))); 1064af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 106591b7ec3660efe16790bc337190a1c948beaab0a5bart last_sg = DRD_(g_threadinfo)[tid].sg_last; 1066bedfd237fbdc80d0c917cfcb85a94b5561c92633bart new_sg = DRD_(sg_new)(tid, tid); 1067bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_append_segment(tid, new_sg); 10688f822af9b234e7c553c408eba65a641c4773457fbart if (tid == DRD_(g_drd_running_tid) && last_sg) 1069e5214666ead5aebb79ad662deacff0a952cba70dbart { 10708f822af9b234e7c553c408eba65a641c4773457fbart DRD_(thread_update_conflict_set)(tid, &last_sg->vc); 1071e5214666ead5aebb79ad662deacff0a952cba70dbart s_update_conflict_set_new_sg_count++; 1072e5214666ead5aebb79ad662deacff0a952cba70dbart } 1073d66e3a8e8c42b7c933c5e6ea0d9a9b4c8ac4cf49bart 10748f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid))); 107526f73e12ef03bb04ebee5cccd8da08cddb426341bart 10768f822af9b234e7c553c408eba65a641c4773457fbart if (s_segment_merging 10778f822af9b234e7c553c408eba65a641c4773457fbart && ++s_new_segments_since_last_merge >= s_segment_merge_interval) 1078bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 10798f822af9b234e7c553c408eba65a641c4773457fbart thread_discard_ordered_segments(); 1080bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_merge_segments(); 1081bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1082af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1083af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 108426f73e12ef03bb04ebee5cccd8da08cddb426341bart/** Call this function after thread 'joiner' joined thread 'joinee'. */ 10858f822af9b234e7c553c408eba65a641c4773457fbartvoid DRD_(thread_combine_vc_join)(DrdThreadId joiner, DrdThreadId joinee) 1086af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1087bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(joiner != joinee); 1088bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)joiner && joiner < DRD_N_THREADS 1089bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && joiner != DRD_INVALID_THREADID); 1090bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)joinee && joinee < DRD_N_THREADS 1091bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && joinee != DRD_INVALID_THREADID); 109291b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[joiner].sg_first); 109391b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[joiner].sg_last); 109491b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[joinee].sg_first); 109591b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[joinee].sg_last); 10968f822af9b234e7c553c408eba65a641c4773457fbart 10978f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(sg_get_trace)()) 10988f822af9b234e7c553c408eba65a641c4773457fbart { 109919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar *str1, *str2; 1100c6bf1846c7604390f777f88b63710702686086d9bart str1 = DRD_(vc_aprint)(DRD_(thread_get_vc)(joiner)); 1101c6bf1846c7604390f777f88b63710702686086d9bart str2 = DRD_(vc_aprint)(DRD_(thread_get_vc)(joinee)); 11021e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "Before join: joiner %s, joinee %s\n", 11038f822af9b234e7c553c408eba65a641c4773457fbart str1, str2); 11048f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str1); 11058f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str2); 11068f822af9b234e7c553c408eba65a641c4773457fbart } 1107ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (joiner == DRD_(g_drd_running_tid)) { 1108e5214666ead5aebb79ad662deacff0a952cba70dbart VectorClock old_vc; 1109e5214666ead5aebb79ad662deacff0a952cba70dbart 1110c6bf1846c7604390f777f88b63710702686086d9bart DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(joiner)); 1111c6bf1846c7604390f777f88b63710702686086d9bart DRD_(vc_combine)(DRD_(thread_get_vc)(joiner), 1112c6bf1846c7604390f777f88b63710702686086d9bart DRD_(thread_get_vc)(joinee)); 1113e5214666ead5aebb79ad662deacff0a952cba70dbart DRD_(thread_update_conflict_set)(joiner, &old_vc); 1114e5214666ead5aebb79ad662deacff0a952cba70dbart s_update_conflict_set_join_count++; 1115e5214666ead5aebb79ad662deacff0a952cba70dbart DRD_(vc_cleanup)(&old_vc); 1116ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart } else { 1117c6bf1846c7604390f777f88b63710702686086d9bart DRD_(vc_combine)(DRD_(thread_get_vc)(joiner), 1118c6bf1846c7604390f777f88b63710702686086d9bart DRD_(thread_get_vc)(joinee)); 1119e5214666ead5aebb79ad662deacff0a952cba70dbart } 1120e5214666ead5aebb79ad662deacff0a952cba70dbart 1121e5214666ead5aebb79ad662deacff0a952cba70dbart thread_discard_ordered_segments(); 1122e5214666ead5aebb79ad662deacff0a952cba70dbart 1123ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (DRD_(sg_get_trace)()) { 112419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 1125ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart 1126c6bf1846c7604390f777f88b63710702686086d9bart str = DRD_(vc_aprint)(DRD_(thread_get_vc)(joiner)); 11271e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "After join: %s\n", str); 11288f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str); 11298f822af9b234e7c553c408eba65a641c4773457fbart } 1130af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1131af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 1132324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 11338f822af9b234e7c553c408eba65a641c4773457fbart * Update the vector clock of the last segment of thread tid with the 1134f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart * the vector clock of segment sg. 113526f73e12ef03bb04ebee5cccd8da08cddb426341bart */ 1136f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bartstatic void thread_combine_vc_sync(DrdThreadId tid, const Segment* sg) 1137af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 11388f822af9b234e7c553c408eba65a641c4773457fbart const VectorClock* const vc = &sg->vc; 11398f822af9b234e7c553c408eba65a641c4773457fbart 1140bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1141bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 114291b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[tid].sg_first); 114391b7ec3660efe16790bc337190a1c948beaab0a5bart tl_assert(DRD_(g_threadinfo)[tid].sg_last); 11448f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(sg); 1145bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(vc); 11468f822af9b234e7c553c408eba65a641c4773457fbart 1147ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (tid != sg->tid) { 11488f822af9b234e7c553c408eba65a641c4773457fbart VectorClock old_vc; 11498f822af9b234e7c553c408eba65a641c4773457fbart 1150c6bf1846c7604390f777f88b63710702686086d9bart DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(tid)); 1151c6bf1846c7604390f777f88b63710702686086d9bart DRD_(vc_combine)(DRD_(thread_get_vc)(tid), vc); 1152ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (DRD_(sg_get_trace)()) { 115319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar *str1, *str2; 11548f822af9b234e7c553c408eba65a641c4773457fbart str1 = DRD_(vc_aprint)(&old_vc); 1155c6bf1846c7604390f777f88b63710702686086d9bart str2 = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid)); 11561e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "thread %d: vc %s -> %s\n", tid, str1, str2); 11578f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str1); 11588f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str2); 11598f822af9b234e7c553c408eba65a641c4773457fbart } 1160e5214666ead5aebb79ad662deacff0a952cba70dbart 11618f822af9b234e7c553c408eba65a641c4773457fbart thread_discard_ordered_segments(); 1162e5214666ead5aebb79ad662deacff0a952cba70dbart 11638f822af9b234e7c553c408eba65a641c4773457fbart DRD_(thread_update_conflict_set)(tid, &old_vc); 1164e5214666ead5aebb79ad662deacff0a952cba70dbart s_update_conflict_set_sync_count++; 1165e5214666ead5aebb79ad662deacff0a952cba70dbart 11668f822af9b234e7c553c408eba65a641c4773457fbart DRD_(vc_cleanup)(&old_vc); 1167ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart } else { 1168c6bf1846c7604390f777f88b63710702686086d9bart tl_assert(DRD_(vc_lte)(vc, DRD_(thread_get_vc)(tid))); 11698f822af9b234e7c553c408eba65a641c4773457fbart } 1170af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1171af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 1172324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 1173f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart * Create a new segment for thread tid and update the vector clock of the last 1174f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart * segment of this thread with the the vector clock of segment sg. Call this 1175f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart * function after thread tid had to wait because of thread synchronization 1176f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart * until the memory accesses in the segment sg finished. 1177f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart */ 1178f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bartvoid DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid, const Segment* sg) 1179f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart{ 1180f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1181f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart && tid != DRD_INVALID_THREADID); 1182f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid))); 1183f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart tl_assert(sg); 1184f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart 1185f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart thread_append_segment(tid, DRD_(sg_new)(tid, tid)); 1186f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart 1187f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart thread_combine_vc_sync(tid, sg); 1188f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart 1189f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart if (s_segment_merging 1190f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart && ++s_new_segments_since_last_merge >= s_segment_merge_interval) 1191f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart { 1192f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart thread_discard_ordered_segments(); 1193f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart thread_merge_segments(); 1194f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart } 1195f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart} 1196f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart 1197f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart/** 1198324a23bea57e0bfc27d9442ec00a8eee8294f01abart * Call this function whenever a thread is no longer using the memory 1199324a23bea57e0bfc27d9442ec00a8eee8294f01abart * [ a1, a2 [, e.g. because of a call to free() or a stack pointer 1200324a23bea57e0bfc27d9442ec00a8eee8294f01abart * increase. 120126f73e12ef03bb04ebee5cccd8da08cddb426341bart */ 120223ef19de837854c360809e59833513360dc1cce2bartvoid DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2) 1203af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1204178b686b4886b7c196df3b5fdd1187113c4e547dbart Segment* p; 1205bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 120691b7ec3660efe16790bc337190a1c948beaab0a5bart for (p = DRD_(g_sg_list); p; p = p->g_next) 1207e278ab506b9a73ef1c17a17077546b2de9a11d7cbart DRD_(bm_clear)(DRD_(sg_bm)(p), a1, a2); 1208bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1209178b686b4886b7c196df3b5fdd1187113c4e547dbart DRD_(bm_clear)(DRD_(g_conflict_set), a1, a2); 1210af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1211af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 1212d45d99553c15a361bb797d21ec6afb9bad22d2d4bart/** Specify whether memory loads should be recorded. */ 1213d45d99553c15a361bb797d21ec6afb9bad22d2d4bartvoid DRD_(thread_set_record_loads)(const DrdThreadId tid, const Bool enabled) 12140268dfacec38138a01a58d05a038826e26b6c436bart{ 1215bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1216bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 1217d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tl_assert(enabled == !! enabled); 1218d45d99553c15a361bb797d21ec6afb9bad22d2d4bart 1219d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(g_threadinfo)[tid].is_recording_loads = enabled; 12200268dfacec38138a01a58d05a038826e26b6c436bart} 12210268dfacec38138a01a58d05a038826e26b6c436bart 1222d45d99553c15a361bb797d21ec6afb9bad22d2d4bart/** Specify whether memory stores should be recorded. */ 1223d45d99553c15a361bb797d21ec6afb9bad22d2d4bartvoid DRD_(thread_set_record_stores)(const DrdThreadId tid, const Bool enabled) 12240268dfacec38138a01a58d05a038826e26b6c436bart{ 1225bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1226bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 1227d45d99553c15a361bb797d21ec6afb9bad22d2d4bart tl_assert(enabled == !! enabled); 1228d45d99553c15a361bb797d21ec6afb9bad22d2d4bart 1229d45d99553c15a361bb797d21ec6afb9bad22d2d4bart DRD_(g_threadinfo)[tid].is_recording_stores = enabled; 12300268dfacec38138a01a58d05a038826e26b6c436bart} 12310268dfacec38138a01a58d05a038826e26b6c436bart 123286a87df5949beb1f89ebbed923068faed08d048cbart/** 123386a87df5949beb1f89ebbed923068faed08d048cbart * Print the segment information for all threads. 123486a87df5949beb1f89ebbed923068faed08d048cbart * 123586a87df5949beb1f89ebbed923068faed08d048cbart * This function is only used for debugging purposes. 123686a87df5949beb1f89ebbed923068faed08d048cbart */ 123762a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_print_all)(void) 1238af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1239bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 1240bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* p; 1241bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 12428f822af9b234e7c553c408eba65a641c4773457fbart for (i = 0; i < DRD_N_THREADS; i++) 1243bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 124491b7ec3660efe16790bc337190a1c948beaab0a5bart p = DRD_(g_threadinfo)[i].sg_first; 124591b7ec3660efe16790bc337190a1c948beaab0a5bart if (p) { 1246bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(printf)("**************\n" 12476d956dc21b6a81f0c67ad18ac61867da0d5922a3bart "* thread %3d (%d/%d/%d/%d/0x%lx/%d) *\n" 1248bedfd237fbdc80d0c917cfcb85a94b5561c92633bart "**************\n", 1249bedfd237fbdc80d0c917cfcb85a94b5561c92633bart i, 12506d956dc21b6a81f0c67ad18ac61867da0d5922a3bart DRD_(g_threadinfo)[i].valid, 1251bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].vg_thread_exists, 1252bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].vg_threadid, 1253bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].posix_thread_exists, 1254bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].pt_threadid, 1255bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(g_threadinfo)[i].detached_posix_thread); 125691b7ec3660efe16790bc337190a1c948beaab0a5bart for ( ; p; p = p->thr_next) 1257bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(sg_print)(p); 1258af44c8236f7a73e71b16b707bba56f33af4d01cesewardj } 1259bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1260af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1261af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 126286a87df5949beb1f89ebbed923068faed08d048cbart/** Show a call stack involved in a data race. */ 1263e7086000dc09e5486e42206ad524fefe09f7cc72bartstatic void show_call_stack(const DrdThreadId tid, ExeContext* const callstack) 1264af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1265bedfd237fbdc80d0c917cfcb85a94b5561c92633bart const ThreadId vg_tid = DRD_(DrdThreadIdToVgThreadId)(tid); 1266bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1267e7086000dc09e5486e42206ad524fefe09f7cc72bart if (vg_tid != VG_INVALID_THREADID) { 1268bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (callstack) 1269bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(pp_ExeContext)(callstack); 1270bedfd237fbdc80d0c917cfcb85a94b5561c92633bart else 1271bedfd237fbdc80d0c917cfcb85a94b5561c92633bart VG_(get_and_pp_StackTrace)(vg_tid, VG_(clo_backtrace_size)); 1272e7086000dc09e5486e42206ad524fefe09f7cc72bart } else { 1273e7086000dc09e5486e42206ad524fefe09f7cc72bart if (!VG_(clo_xml)) 1274e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(message)(Vg_UserMsg, 1275e7086000dc09e5486e42206ad524fefe09f7cc72bart " (thread finished, call stack no longer available)\n"); 1276bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1277af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1278af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 127986a87df5949beb1f89ebbed923068faed08d048cbart/** Print information about the segments involved in a data race. */ 1280af44c8236f7a73e71b16b707bba56f33af4d01cesewardjstatic void 1281af44c8236f7a73e71b16b707bba56f33af4d01cesewardjthread_report_conflicting_segments_segment(const DrdThreadId tid, 1282af44c8236f7a73e71b16b707bba56f33af4d01cesewardj const Addr addr, 1283af44c8236f7a73e71b16b707bba56f33af4d01cesewardj const SizeT size, 1284af44c8236f7a73e71b16b707bba56f33af4d01cesewardj const BmAccessTypeT access_type, 1285af44c8236f7a73e71b16b707bba56f33af4d01cesewardj const Segment* const p) 1286af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1287bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned i; 1288bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1289bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1290bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 1291bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(p); 1292bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 129391b7ec3660efe16790bc337190a1c948beaab0a5bart for (i = 0; i < DRD_N_THREADS; i++) { 129491b7ec3660efe16790bc337190a1c948beaab0a5bart if (i != tid) { 1295bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* q; 1296e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 129791b7ec3660efe16790bc337190a1c948beaab0a5bart for (q = DRD_(g_threadinfo)[i].sg_last; q; q = q->thr_prev) { 1298bedfd237fbdc80d0c917cfcb85a94b5561c92633bart /* 129931b983d29affe6c30a2283be8824c6d75c74d848bart * Since q iterates over the segments of thread i in order of 130031b983d29affe6c30a2283be8824c6d75c74d848bart * decreasing vector clocks, if q->vc <= p->vc, then 1301bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * q->next->vc <= p->vc will also hold. Hence, break out of the 1302bedfd237fbdc80d0c917cfcb85a94b5561c92633bart * loop once this condition is met. 1303bedfd237fbdc80d0c917cfcb85a94b5561c92633bart */ 1304bedfd237fbdc80d0c917cfcb85a94b5561c92633bart if (DRD_(vc_lte)(&q->vc, &p->vc)) 1305bedfd237fbdc80d0c917cfcb85a94b5561c92633bart break; 130691b7ec3660efe16790bc337190a1c948beaab0a5bart if (!DRD_(vc_lte)(&p->vc, &q->vc)) { 13078f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(bm_has_conflict_with)(DRD_(sg_bm)(q), addr, addr + size, 130891b7ec3660efe16790bc337190a1c948beaab0a5bart access_type)) { 1309e278ab506b9a73ef1c17a17077546b2de9a11d7cbart Segment* q_next; 1310e278ab506b9a73ef1c17a17077546b2de9a11d7cbart 1311bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(q->stacktrace); 1312e7086000dc09e5486e42206ad524fefe09f7cc72bart if (VG_(clo_xml)) 1313e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(printf_xml)(" <other_segment_start>\n"); 1314e7086000dc09e5486e42206ad524fefe09f7cc72bart else 1315e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(message)(Vg_UserMsg, 1316e7086000dc09e5486e42206ad524fefe09f7cc72bart "Other segment start (thread %d)\n", i); 1317e7086000dc09e5486e42206ad524fefe09f7cc72bart show_call_stack(i, q->stacktrace); 1318e7086000dc09e5486e42206ad524fefe09f7cc72bart if (VG_(clo_xml)) 1319e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(printf_xml)(" </other_segment_start>\n" 1320e7086000dc09e5486e42206ad524fefe09f7cc72bart " <other_segment_end>\n"); 1321e7086000dc09e5486e42206ad524fefe09f7cc72bart else 1322e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(message)(Vg_UserMsg, 1323e7086000dc09e5486e42206ad524fefe09f7cc72bart "Other segment end (thread %d)\n", i); 132491b7ec3660efe16790bc337190a1c948beaab0a5bart q_next = q->thr_next; 1325e278ab506b9a73ef1c17a17077546b2de9a11d7cbart show_call_stack(i, q_next ? q_next->stacktrace : 0); 1326e7086000dc09e5486e42206ad524fefe09f7cc72bart if (VG_(clo_xml)) 1327e7086000dc09e5486e42206ad524fefe09f7cc72bart VG_(printf_xml)(" </other_segment_end>\n"); 1328bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1329bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1330bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1331af44c8236f7a73e71b16b707bba56f33af4d01cesewardj } 1332bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1333af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1334af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 133586a87df5949beb1f89ebbed923068faed08d048cbart/** Print information about all segments involved in a data race. */ 133662a784c9382fdf7184065ad76ae8d3b905605f21bartvoid DRD_(thread_report_conflicting_segments)(const DrdThreadId tid, 133762a784c9382fdf7184065ad76ae8d3b905605f21bart const Addr addr, 133862a784c9382fdf7184065ad76ae8d3b905605f21bart const SizeT size, 133962a784c9382fdf7184065ad76ae8d3b905605f21bart const BmAccessTypeT access_type) 1340af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1341bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* p; 1342bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1343bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1344bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 1345bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 134691b7ec3660efe16790bc337190a1c948beaab0a5bart for (p = DRD_(g_threadinfo)[tid].sg_first; p; p = p->thr_next) { 13478f822af9b234e7c553c408eba65a641c4773457fbart if (DRD_(bm_has)(DRD_(sg_bm)(p), addr, addr + size, access_type)) 1348bedfd237fbdc80d0c917cfcb85a94b5561c92633bart thread_report_conflicting_segments_segment(tid, addr, size, 1349bedfd237fbdc80d0c917cfcb85a94b5561c92633bart access_type, p); 1350bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1351af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1352af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 1353324a23bea57e0bfc27d9442ec00a8eee8294f01abart/** 13548f822af9b234e7c553c408eba65a641c4773457fbart * Verify whether the conflict set for thread tid is up to date. Only perform 13558f822af9b234e7c553c408eba65a641c4773457fbart * the check if the environment variable DRD_VERIFY_CONFLICT_SET has been set. 13568f822af9b234e7c553c408eba65a641c4773457fbart */ 13578f822af9b234e7c553c408eba65a641c4773457fbartstatic Bool thread_conflict_set_up_to_date(const DrdThreadId tid) 13588f822af9b234e7c553c408eba65a641c4773457fbart{ 13598f822af9b234e7c553c408eba65a641c4773457fbart Bool result; 13608f822af9b234e7c553c408eba65a641c4773457fbart struct bitmap* computed_conflict_set = 0; 13618f822af9b234e7c553c408eba65a641c4773457fbart 13629cdc08368068d746e42d40c8f3a3dca5db5caee4bart if (!DRD_(verify_conflict_set)) 13638f822af9b234e7c553c408eba65a641c4773457fbart return True; 13648f822af9b234e7c553c408eba65a641c4773457fbart 13658f822af9b234e7c553c408eba65a641c4773457fbart thread_compute_conflict_set(&computed_conflict_set, tid); 13668f822af9b234e7c553c408eba65a641c4773457fbart result = DRD_(bm_equal)(DRD_(g_conflict_set), computed_conflict_set); 13678f822af9b234e7c553c408eba65a641c4773457fbart if (! result) 13688f822af9b234e7c553c408eba65a641c4773457fbart { 13698f822af9b234e7c553c408eba65a641c4773457fbart VG_(printf)("actual conflict set:\n"); 13708f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_print)(DRD_(g_conflict_set)); 13718f822af9b234e7c553c408eba65a641c4773457fbart VG_(printf)("\n"); 13728f822af9b234e7c553c408eba65a641c4773457fbart VG_(printf)("computed conflict set:\n"); 13738f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_print)(computed_conflict_set); 13748f822af9b234e7c553c408eba65a641c4773457fbart VG_(printf)("\n"); 13758f822af9b234e7c553c408eba65a641c4773457fbart } 13768f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_delete)(computed_conflict_set); 13778f822af9b234e7c553c408eba65a641c4773457fbart return result; 13788f822af9b234e7c553c408eba65a641c4773457fbart} 13798f822af9b234e7c553c408eba65a641c4773457fbart 13808f822af9b234e7c553c408eba65a641c4773457fbart/** 13818f822af9b234e7c553c408eba65a641c4773457fbart * Compute the conflict set: a bitmap that represents the union of all memory 13828f822af9b234e7c553c408eba65a641c4773457fbart * accesses of all segments that are unordered to the current segment of the 13838f822af9b234e7c553c408eba65a641c4773457fbart * thread tid. 1384af44c8236f7a73e71b16b707bba56f33af4d01cesewardj */ 138586a87df5949beb1f89ebbed923068faed08d048cbartstatic void thread_compute_conflict_set(struct bitmap** conflict_set, 138686a87df5949beb1f89ebbed923068faed08d048cbart const DrdThreadId tid) 1387af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1388bedfd237fbdc80d0c917cfcb85a94b5561c92633bart Segment* p; 1389bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1390bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 1391bedfd237fbdc80d0c917cfcb85a94b5561c92633bart && tid != DRD_INVALID_THREADID); 1392bedfd237fbdc80d0c917cfcb85a94b5561c92633bart tl_assert(tid == DRD_(g_drd_running_tid)); 1393bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 139454803feb0b92e4708d3cee92e7449f802be70197bart s_compute_conflict_set_count++; 1395bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_conflict_set_bitmap_creation_count 1396bedfd237fbdc80d0c917cfcb85a94b5561c92633bart -= DRD_(bm_get_bitmap_creation_count)(); 1397bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_conflict_set_bitmap2_creation_count 1398bedfd237fbdc80d0c917cfcb85a94b5561c92633bart -= DRD_(bm_get_bitmap2_creation_count)(); 1399bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1400ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (*conflict_set) { 1401f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart DRD_(bm_cleanup)(*conflict_set); 1402f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart DRD_(bm_init)(*conflict_set); 1403ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart } else { 1404f6ec1fe18f1fc1222fb274d7dfd4343c16048fb1bart *conflict_set = DRD_(bm_new)(); 1405bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1406bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1407ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (s_trace_conflict_set) { 140819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 14098f822af9b234e7c553c408eba65a641c4773457fbart 1410c6bf1846c7604390f777f88b63710702686086d9bart str = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid)); 14118f822af9b234e7c553c408eba65a641c4773457fbart VG_(message)(Vg_DebugMsg, 141263c92ea799549976957f5b4d54ede744f762c56fbart "computing conflict set for thread %d with vc %s\n", 141363c92ea799549976957f5b4d54ede744f762c56fbart tid, str); 14148f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str); 1415bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1416bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 141791b7ec3660efe16790bc337190a1c948beaab0a5bart p = DRD_(g_threadinfo)[tid].sg_last; 1418bedfd237fbdc80d0c917cfcb85a94b5561c92633bart { 1419bedfd237fbdc80d0c917cfcb85a94b5561c92633bart unsigned j; 1420af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 142191b7ec3660efe16790bc337190a1c948beaab0a5bart if (s_trace_conflict_set) { 142219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* vc; 14238f822af9b234e7c553c408eba65a641c4773457fbart 14248f822af9b234e7c553c408eba65a641c4773457fbart vc = DRD_(vc_aprint)(&p->vc); 14251e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "conflict set: thread [%d] at vc %s\n", 14268f822af9b234e7c553c408eba65a641c4773457fbart tid, vc); 14278f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(vc); 1428bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1429bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 143091b7ec3660efe16790bc337190a1c948beaab0a5bart for (j = 0; j < DRD_N_THREADS; j++) { 143191b7ec3660efe16790bc337190a1c948beaab0a5bart if (j != tid && DRD_(IsValidDrdThreadId)(j)) { 14328f822af9b234e7c553c408eba65a641c4773457fbart Segment* q; 143391b7ec3660efe16790bc337190a1c948beaab0a5bart 143491b7ec3660efe16790bc337190a1c948beaab0a5bart for (q = DRD_(g_threadinfo)[j].sg_last; q; q = q->thr_prev) { 143591b7ec3660efe16790bc337190a1c948beaab0a5bart if (!DRD_(vc_lte)(&q->vc, &p->vc) 143691b7ec3660efe16790bc337190a1c948beaab0a5bart && !DRD_(vc_lte)(&p->vc, &q->vc)) { 143791b7ec3660efe16790bc337190a1c948beaab0a5bart if (s_trace_conflict_set) { 143819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 14398f822af9b234e7c553c408eba65a641c4773457fbart 14408f822af9b234e7c553c408eba65a641c4773457fbart str = DRD_(vc_aprint)(&q->vc); 14418f822af9b234e7c553c408eba65a641c4773457fbart VG_(message)(Vg_DebugMsg, 14421e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj "conflict set: [%d] merging segment %s\n", 14438f822af9b234e7c553c408eba65a641c4773457fbart j, str); 14448f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str); 1445bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 14468f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_merge2)(*conflict_set, DRD_(sg_bm)(q)); 144791b7ec3660efe16790bc337190a1c948beaab0a5bart } else { 144891b7ec3660efe16790bc337190a1c948beaab0a5bart if (s_trace_conflict_set) { 144919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 14508f822af9b234e7c553c408eba65a641c4773457fbart 14518f822af9b234e7c553c408eba65a641c4773457fbart str = DRD_(vc_aprint)(&q->vc); 14528f822af9b234e7c553c408eba65a641c4773457fbart VG_(message)(Vg_DebugMsg, 14531e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj "conflict set: [%d] ignoring segment %s\n", 14548f822af9b234e7c553c408eba65a641c4773457fbart j, str); 14558f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str); 1456bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1457bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 145826f73e12ef03bb04ebee5cccd8da08cddb426341bart } 1459bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1460af44c8236f7a73e71b16b707bba56f33af4d01cesewardj } 1461bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 1462bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 1463bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_conflict_set_bitmap_creation_count 1464bedfd237fbdc80d0c917cfcb85a94b5561c92633bart += DRD_(bm_get_bitmap_creation_count)(); 1465bedfd237fbdc80d0c917cfcb85a94b5561c92633bart s_conflict_set_bitmap2_creation_count 1466bedfd237fbdc80d0c917cfcb85a94b5561c92633bart += DRD_(bm_get_bitmap2_creation_count)(); 1467bedfd237fbdc80d0c917cfcb85a94b5561c92633bart 146891b7ec3660efe16790bc337190a1c948beaab0a5bart if (s_trace_conflict_set_bm) { 14691e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "[%d] new conflict set:\n", tid); 1470bedfd237fbdc80d0c917cfcb85a94b5561c92633bart DRD_(bm_print)(*conflict_set); 14711e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "[%d] end of new conflict set.\n", tid); 14728f822af9b234e7c553c408eba65a641c4773457fbart } 14738f822af9b234e7c553c408eba65a641c4773457fbart} 14748f822af9b234e7c553c408eba65a641c4773457fbart 14758f822af9b234e7c553c408eba65a641c4773457fbart/** 14768f822af9b234e7c553c408eba65a641c4773457fbart * Update the conflict set after the vector clock of thread tid has been 14778f822af9b234e7c553c408eba65a641c4773457fbart * updated from old_vc to its current value, either because a new segment has 14788f822af9b234e7c553c408eba65a641c4773457fbart * been created or because of a synchronization operation. 14798f822af9b234e7c553c408eba65a641c4773457fbart */ 14808f822af9b234e7c553c408eba65a641c4773457fbartvoid DRD_(thread_update_conflict_set)(const DrdThreadId tid, 14818f822af9b234e7c553c408eba65a641c4773457fbart const VectorClock* const old_vc) 14828f822af9b234e7c553c408eba65a641c4773457fbart{ 14838f822af9b234e7c553c408eba65a641c4773457fbart const VectorClock* new_vc; 14848f822af9b234e7c553c408eba65a641c4773457fbart Segment* p; 14858f822af9b234e7c553c408eba65a641c4773457fbart unsigned j; 14868f822af9b234e7c553c408eba65a641c4773457fbart 14878f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 14888f822af9b234e7c553c408eba65a641c4773457fbart && tid != DRD_INVALID_THREADID); 14898f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(old_vc); 14908f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(tid == DRD_(g_drd_running_tid)); 14918f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(DRD_(g_conflict_set)); 14928f822af9b234e7c553c408eba65a641c4773457fbart 1493ae37e6d4c9ca1f400ef4c1636319be60f969b2afbart if (s_trace_conflict_set) { 149419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 14958f822af9b234e7c553c408eba65a641c4773457fbart 1496c6bf1846c7604390f777f88b63710702686086d9bart str = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid)); 14978f822af9b234e7c553c408eba65a641c4773457fbart VG_(message)(Vg_DebugMsg, 149863c92ea799549976957f5b4d54ede744f762c56fbart "updating conflict set for thread %d with vc %s\n", 149963c92ea799549976957f5b4d54ede744f762c56fbart tid, str); 15008f822af9b234e7c553c408eba65a641c4773457fbart VG_(free)(str); 15018f822af9b234e7c553c408eba65a641c4773457fbart } 15028f822af9b234e7c553c408eba65a641c4773457fbart 1503c6bf1846c7604390f777f88b63710702686086d9bart new_vc = DRD_(thread_get_vc)(tid); 1504f5fe4b66b06998f8fa0eaa2bb17eb34eb0e3bbdebart tl_assert(DRD_(vc_lte)(old_vc, new_vc)); 15058f822af9b234e7c553c408eba65a641c4773457fbart 15068f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_unmark)(DRD_(g_conflict_set)); 15078f822af9b234e7c553c408eba65a641c4773457fbart 15088f822af9b234e7c553c408eba65a641c4773457fbart for (j = 0; j < DRD_N_THREADS; j++) 15098f822af9b234e7c553c408eba65a641c4773457fbart { 15108f822af9b234e7c553c408eba65a641c4773457fbart Segment* q; 15118f822af9b234e7c553c408eba65a641c4773457fbart 15128f822af9b234e7c553c408eba65a641c4773457fbart if (j == tid || ! DRD_(IsValidDrdThreadId)(j)) 15138f822af9b234e7c553c408eba65a641c4773457fbart continue; 15148f822af9b234e7c553c408eba65a641c4773457fbart 151591b7ec3660efe16790bc337190a1c948beaab0a5bart for (q = DRD_(g_threadinfo)[j].sg_last; 151691b7ec3660efe16790bc337190a1c948beaab0a5bart q && !DRD_(vc_lte)(&q->vc, new_vc); 151791b7ec3660efe16790bc337190a1c948beaab0a5bart q = q->thr_prev) { 151891b7ec3660efe16790bc337190a1c948beaab0a5bart const Bool included_in_old_conflict_set 151991b7ec3660efe16790bc337190a1c948beaab0a5bart = !DRD_(vc_lte)(old_vc, &q->vc); 152091b7ec3660efe16790bc337190a1c948beaab0a5bart const Bool included_in_new_conflict_set 152191b7ec3660efe16790bc337190a1c948beaab0a5bart = !DRD_(vc_lte)(new_vc, &q->vc); 1522178b686b4886b7c196df3b5fdd1187113c4e547dbart 1523178b686b4886b7c196df3b5fdd1187113c4e547dbart if (UNLIKELY(s_trace_conflict_set)) { 152419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 1525178b686b4886b7c196df3b5fdd1187113c4e547dbart 1526178b686b4886b7c196df3b5fdd1187113c4e547dbart str = DRD_(vc_aprint)(&q->vc); 1527178b686b4886b7c196df3b5fdd1187113c4e547dbart VG_(message)(Vg_DebugMsg, 1528178b686b4886b7c196df3b5fdd1187113c4e547dbart "conflict set: [%d] %s segment %s\n", j, 1529178b686b4886b7c196df3b5fdd1187113c4e547dbart included_in_old_conflict_set 1530178b686b4886b7c196df3b5fdd1187113c4e547dbart != included_in_new_conflict_set 1531178b686b4886b7c196df3b5fdd1187113c4e547dbart ? "merging" : "ignoring", str); 1532178b686b4886b7c196df3b5fdd1187113c4e547dbart VG_(free)(str); 1533178b686b4886b7c196df3b5fdd1187113c4e547dbart } 1534178b686b4886b7c196df3b5fdd1187113c4e547dbart if (included_in_old_conflict_set != included_in_new_conflict_set) 1535178b686b4886b7c196df3b5fdd1187113c4e547dbart DRD_(bm_mark)(DRD_(g_conflict_set), DRD_(sg_bm)(q)); 1536178b686b4886b7c196df3b5fdd1187113c4e547dbart } 1537178b686b4886b7c196df3b5fdd1187113c4e547dbart 153891b7ec3660efe16790bc337190a1c948beaab0a5bart for ( ; q && !DRD_(vc_lte)(&q->vc, old_vc); q = q->thr_prev) { 153991b7ec3660efe16790bc337190a1c948beaab0a5bart const Bool included_in_old_conflict_set 154091b7ec3660efe16790bc337190a1c948beaab0a5bart = !DRD_(vc_lte)(old_vc, &q->vc); 154191b7ec3660efe16790bc337190a1c948beaab0a5bart const Bool included_in_new_conflict_set 154291b7ec3660efe16790bc337190a1c948beaab0a5bart = !DRD_(vc_lte)(&q->vc, new_vc) 154391b7ec3660efe16790bc337190a1c948beaab0a5bart && !DRD_(vc_lte)(new_vc, &q->vc); 1544178b686b4886b7c196df3b5fdd1187113c4e547dbart 1545178b686b4886b7c196df3b5fdd1187113c4e547dbart if (UNLIKELY(s_trace_conflict_set)) { 154619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian HChar* str; 1547ac5b95bcdf94a728d8a603712b371eab26df897dbart 1548ac5b95bcdf94a728d8a603712b371eab26df897dbart str = DRD_(vc_aprint)(&q->vc); 1549ac5b95bcdf94a728d8a603712b371eab26df897dbart VG_(message)(Vg_DebugMsg, 1550ac5b95bcdf94a728d8a603712b371eab26df897dbart "conflict set: [%d] %s segment %s\n", j, 1551ac5b95bcdf94a728d8a603712b371eab26df897dbart included_in_old_conflict_set 1552ac5b95bcdf94a728d8a603712b371eab26df897dbart != included_in_new_conflict_set 1553ac5b95bcdf94a728d8a603712b371eab26df897dbart ? "merging" : "ignoring", str); 1554ac5b95bcdf94a728d8a603712b371eab26df897dbart VG_(free)(str); 1555ac5b95bcdf94a728d8a603712b371eab26df897dbart } 15568f822af9b234e7c553c408eba65a641c4773457fbart if (included_in_old_conflict_set != included_in_new_conflict_set) 15578f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_mark)(DRD_(g_conflict_set), DRD_(sg_bm)(q)); 15588f822af9b234e7c553c408eba65a641c4773457fbart } 15598f822af9b234e7c553c408eba65a641c4773457fbart } 15608f822af9b234e7c553c408eba65a641c4773457fbart 15618f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_clear_marked)(DRD_(g_conflict_set)); 15628f822af9b234e7c553c408eba65a641c4773457fbart 156391b7ec3660efe16790bc337190a1c948beaab0a5bart p = DRD_(g_threadinfo)[tid].sg_last; 156491b7ec3660efe16790bc337190a1c948beaab0a5bart for (j = 0; j < DRD_N_THREADS; j++) { 156591b7ec3660efe16790bc337190a1c948beaab0a5bart if (j != tid && DRD_(IsValidDrdThreadId)(j)) { 15664b3fdb21a4e07b6f1d1b6753203703d7fdd9a785bart Segment* q; 156791b7ec3660efe16790bc337190a1c948beaab0a5bart for (q = DRD_(g_threadinfo)[j].sg_last; 156891b7ec3660efe16790bc337190a1c948beaab0a5bart q && !DRD_(vc_lte)(&q->vc, &p->vc); 156991b7ec3660efe16790bc337190a1c948beaab0a5bart q = q->thr_prev) { 1570178b686b4886b7c196df3b5fdd1187113c4e547dbart if (!DRD_(vc_lte)(&p->vc, &q->vc)) 15714b3fdb21a4e07b6f1d1b6753203703d7fdd9a785bart DRD_(bm_merge2_marked)(DRD_(g_conflict_set), DRD_(sg_bm)(q)); 15728f822af9b234e7c553c408eba65a641c4773457fbart } 15738f822af9b234e7c553c408eba65a641c4773457fbart } 1574bedfd237fbdc80d0c917cfcb85a94b5561c92633bart } 15758f822af9b234e7c553c408eba65a641c4773457fbart 15768f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_remove_cleared_marked)(DRD_(g_conflict_set)); 15778f822af9b234e7c553c408eba65a641c4773457fbart 157854803feb0b92e4708d3cee92e7449f802be70197bart s_update_conflict_set_count++; 15798f822af9b234e7c553c408eba65a641c4773457fbart 15808f822af9b234e7c553c408eba65a641c4773457fbart if (s_trace_conflict_set_bm) 15818f822af9b234e7c553c408eba65a641c4773457fbart { 15821e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "[%d] updated conflict set:\n", tid); 15838f822af9b234e7c553c408eba65a641c4773457fbart DRD_(bm_print)(DRD_(g_conflict_set)); 15841e29ebcf5a0d5d29434d112bda3a584b4a3f8066sewardj VG_(message)(Vg_DebugMsg, "[%d] end of updated conflict set.\n", tid); 15858f822af9b234e7c553c408eba65a641c4773457fbart } 15868f822af9b234e7c553c408eba65a641c4773457fbart 15878f822af9b234e7c553c408eba65a641c4773457fbart tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid))); 1588af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1589af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 159086a87df5949beb1f89ebbed923068faed08d048cbart/** Report the number of context switches performed. */ 159162a784c9382fdf7184065ad76ae8d3b905605f21bartULong DRD_(thread_get_context_switch_count)(void) 1592af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1593bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_context_switch_count; 1594af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1595af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 159686a87df5949beb1f89ebbed923068faed08d048cbart/** Report the number of ordered segments that have been discarded. */ 159762a784c9382fdf7184065ad76ae8d3b905605f21bartULong DRD_(thread_get_discard_ordered_segments_count)(void) 1598af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1599bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_discard_ordered_segments_count; 1600af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1601af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 160254803feb0b92e4708d3cee92e7449f802be70197bart/** Return how many times the conflict set has been updated entirely. */ 160354803feb0b92e4708d3cee92e7449f802be70197bartULong DRD_(thread_get_compute_conflict_set_count)() 160454803feb0b92e4708d3cee92e7449f802be70197bart{ 160554803feb0b92e4708d3cee92e7449f802be70197bart return s_compute_conflict_set_count; 160654803feb0b92e4708d3cee92e7449f802be70197bart} 160754803feb0b92e4708d3cee92e7449f802be70197bart 160854803feb0b92e4708d3cee92e7449f802be70197bart/** Return how many times the conflict set has been updated partially. */ 160954803feb0b92e4708d3cee92e7449f802be70197bartULong DRD_(thread_get_update_conflict_set_count)(void) 1610af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1611bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_update_conflict_set_count; 1612af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1613af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 161486a87df5949beb1f89ebbed923068faed08d048cbart/** 1615e5214666ead5aebb79ad662deacff0a952cba70dbart * Return how many times the conflict set has been updated partially 1616e5214666ead5aebb79ad662deacff0a952cba70dbart * because a new segment has been created. 1617e5214666ead5aebb79ad662deacff0a952cba70dbart */ 1618e5214666ead5aebb79ad662deacff0a952cba70dbartULong DRD_(thread_get_update_conflict_set_new_sg_count)(void) 1619e5214666ead5aebb79ad662deacff0a952cba70dbart{ 1620e5214666ead5aebb79ad662deacff0a952cba70dbart return s_update_conflict_set_new_sg_count; 1621e5214666ead5aebb79ad662deacff0a952cba70dbart} 1622e5214666ead5aebb79ad662deacff0a952cba70dbart 1623e5214666ead5aebb79ad662deacff0a952cba70dbart/** 1624e5214666ead5aebb79ad662deacff0a952cba70dbart * Return how many times the conflict set has been updated partially 1625e5214666ead5aebb79ad662deacff0a952cba70dbart * because of combining vector clocks due to synchronization operations 1626e5214666ead5aebb79ad662deacff0a952cba70dbart * other than reader/writer lock or barrier operations. 1627e5214666ead5aebb79ad662deacff0a952cba70dbart */ 1628e5214666ead5aebb79ad662deacff0a952cba70dbartULong DRD_(thread_get_update_conflict_set_sync_count)(void) 1629e5214666ead5aebb79ad662deacff0a952cba70dbart{ 1630e5214666ead5aebb79ad662deacff0a952cba70dbart return s_update_conflict_set_sync_count; 1631e5214666ead5aebb79ad662deacff0a952cba70dbart} 1632e5214666ead5aebb79ad662deacff0a952cba70dbart 1633e5214666ead5aebb79ad662deacff0a952cba70dbart/** 1634e5214666ead5aebb79ad662deacff0a952cba70dbart * Return how many times the conflict set has been updated partially 1635e5214666ead5aebb79ad662deacff0a952cba70dbart * because of thread joins. 1636e5214666ead5aebb79ad662deacff0a952cba70dbart */ 1637e5214666ead5aebb79ad662deacff0a952cba70dbartULong DRD_(thread_get_update_conflict_set_join_count)(void) 1638e5214666ead5aebb79ad662deacff0a952cba70dbart{ 1639e5214666ead5aebb79ad662deacff0a952cba70dbart return s_update_conflict_set_join_count; 1640e5214666ead5aebb79ad662deacff0a952cba70dbart} 1641e5214666ead5aebb79ad662deacff0a952cba70dbart 1642e5214666ead5aebb79ad662deacff0a952cba70dbart/** 164386a87df5949beb1f89ebbed923068faed08d048cbart * Return the number of first-level bitmaps that have been created during 164486a87df5949beb1f89ebbed923068faed08d048cbart * conflict set updates. 164586a87df5949beb1f89ebbed923068faed08d048cbart */ 164662a784c9382fdf7184065ad76ae8d3b905605f21bartULong DRD_(thread_get_conflict_set_bitmap_creation_count)(void) 1647af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1648bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_conflict_set_bitmap_creation_count; 1649af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1650af44c8236f7a73e71b16b707bba56f33af4d01cesewardj 165186a87df5949beb1f89ebbed923068faed08d048cbart/** 165286a87df5949beb1f89ebbed923068faed08d048cbart * Return the number of second-level bitmaps that have been created during 165386a87df5949beb1f89ebbed923068faed08d048cbart * conflict set updates. 165486a87df5949beb1f89ebbed923068faed08d048cbart */ 165562a784c9382fdf7184065ad76ae8d3b905605f21bartULong DRD_(thread_get_conflict_set_bitmap2_creation_count)(void) 1656af44c8236f7a73e71b16b707bba56f33af4d01cesewardj{ 1657bedfd237fbdc80d0c917cfcb85a94b5561c92633bart return s_conflict_set_bitmap2_creation_count; 1658af44c8236f7a73e71b16b707bba56f33af4d01cesewardj} 1659