1/*
2  This file is part of drd, a thread error detector.
3
4  Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>.
5
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License as
8  published by the Free Software Foundation; either version 2 of the
9  License, or (at your option) any later version.
10
11  This program is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19  02111-1307, USA.
20
21  The GNU General Public License is contained in the file COPYING.
22*/
23
24
25#include "drd_error.h"
26#include "drd_barrier.h"
27#include "drd_clientobj.h"
28#include "drd_cond.h"
29#include "drd_mutex.h"
30#include "drd_segment.h"
31#include "drd_semaphore.h"
32#include "drd_suppression.h"
33#include "drd_thread.h"
34#include "pub_tool_vki.h"
35#include "pub_tool_basics.h"      // Addr, SizeT
36#include "pub_tool_libcassert.h"  // tl_assert()
37#include "pub_tool_libcbase.h"    // VG_(strlen)()
38#include "pub_tool_libcprint.h"   // VG_(printf)()
39#include "pub_tool_machine.h"
40#include "pub_tool_mallocfree.h"  // VG_(malloc)(), VG_(free)()
41#include "pub_tool_options.h"     // VG_(clo_backtrace_size)
42#include "pub_tool_threadstate.h" // VG_(get_pthread_id)()
43
44
45
46/* Local functions. */
47
48static void thread_append_segment(const DrdThreadId tid, Segment* const sg);
49static void thread_discard_segment(const DrdThreadId tid, Segment* const sg);
50static void thread_compute_conflict_set(struct bitmap** conflict_set,
51                                        const DrdThreadId tid);
52static Bool thread_conflict_set_up_to_date(const DrdThreadId tid);
53
54
55/* Local variables. */
56
57static ULong    s_context_switch_count;
58static ULong    s_discard_ordered_segments_count;
59static ULong    s_compute_conflict_set_count;
60static ULong    s_update_conflict_set_count;
61static ULong    s_update_conflict_set_new_sg_count;
62static ULong    s_update_conflict_set_sync_count;
63static ULong    s_update_conflict_set_join_count;
64static ULong    s_conflict_set_bitmap_creation_count;
65static ULong    s_conflict_set_bitmap2_creation_count;
66static ThreadId s_vg_running_tid  = VG_INVALID_THREADID;
67DrdThreadId     DRD_(g_drd_running_tid) = DRD_INVALID_THREADID;
68ThreadInfo*     DRD_(g_threadinfo);
69struct bitmap*  DRD_(g_conflict_set);
70Bool DRD_(verify_conflict_set);
71static Bool     s_trace_context_switches = False;
72static Bool     s_trace_conflict_set = False;
73static Bool     s_trace_conflict_set_bm = False;
74static Bool     s_trace_fork_join = False;
75static Bool     s_segment_merging = True;
76static Bool     s_new_segments_since_last_merge;
77static int      s_segment_merge_interval = 10;
78static unsigned s_join_list_vol = 10;
79static unsigned s_deletion_head;
80static unsigned s_deletion_tail;
81
82
83/* Function definitions. */
84
85/** Enables/disables context switch tracing. */
86void DRD_(thread_trace_context_switches)(const Bool t)
87{
88   tl_assert(t == False || t == True);
89   s_trace_context_switches = t;
90}
91
92/** Enables/disables conflict set tracing. */
93void DRD_(thread_trace_conflict_set)(const Bool t)
94{
95   tl_assert(t == False || t == True);
96   s_trace_conflict_set = t;
97}
98
99/** Enables/disables conflict set bitmap tracing. */
100void DRD_(thread_trace_conflict_set_bm)(const Bool t)
101{
102   tl_assert(t == False || t == True);
103   s_trace_conflict_set_bm = t;
104}
105
106/** Report whether fork/join tracing is enabled. */
107Bool DRD_(thread_get_trace_fork_join)(void)
108{
109   return s_trace_fork_join;
110}
111
112/** Enables/disables fork/join tracing. */
113void DRD_(thread_set_trace_fork_join)(const Bool t)
114{
115   tl_assert(t == False || t == True);
116   s_trace_fork_join = t;
117}
118
119/** Enables/disables segment merging. */
120void DRD_(thread_set_segment_merging)(const Bool m)
121{
122   tl_assert(m == False || m == True);
123   s_segment_merging = m;
124}
125
126/** Get the segment merging interval. */
127int DRD_(thread_get_segment_merge_interval)(void)
128{
129   return s_segment_merge_interval;
130}
131
132/** Set the segment merging interval. */
133void DRD_(thread_set_segment_merge_interval)(const int i)
134{
135   s_segment_merge_interval = i;
136}
137
138void DRD_(thread_set_join_list_vol)(const int jlv)
139{
140   s_join_list_vol = jlv;
141}
142
143void DRD_(thread_init)(void)
144{
145   DRD_(g_threadinfo) = VG_(malloc)("drd.main.ti.1",
146                                DRD_N_THREADS * sizeof DRD_(g_threadinfo)[0]);
147   for (UInt i = 0; i < DRD_N_THREADS; ++i) {
148      static ThreadInfo initval;
149      DRD_(g_threadinfo)[i] = initval;
150   }
151}
152
153/**
154 * Convert Valgrind's ThreadId into a DrdThreadId.
155 *
156 * @return DRD thread ID upon success and DRD_INVALID_THREADID if the passed
157 *         Valgrind ThreadId does not yet exist.
158 */
159DrdThreadId DRD_(VgThreadIdToDrdThreadId)(const ThreadId tid)
160{
161   UInt i;
162
163   if (tid == VG_INVALID_THREADID)
164      return DRD_INVALID_THREADID;
165
166   for (i = 1; i < DRD_N_THREADS; i++)
167   {
168      if (DRD_(g_threadinfo)[i].vg_thread_exists == True
169          && DRD_(g_threadinfo)[i].vg_threadid == tid)
170      {
171         return i;
172      }
173   }
174
175   return DRD_INVALID_THREADID;
176}
177
178/** Allocate a new DRD thread ID for the specified Valgrind thread ID. */
179static DrdThreadId DRD_(VgThreadIdToNewDrdThreadId)(const ThreadId tid)
180{
181   UInt i;
182
183   tl_assert(DRD_(VgThreadIdToDrdThreadId)(tid) == DRD_INVALID_THREADID);
184
185   for (i = 1; i < DRD_N_THREADS; i++)
186   {
187      if (!DRD_(g_threadinfo)[i].valid)
188      {
189         tl_assert(! DRD_(IsValidDrdThreadId)(i));
190
191         DRD_(g_threadinfo)[i].valid         = True;
192         DRD_(g_threadinfo)[i].vg_thread_exists = True;
193         DRD_(g_threadinfo)[i].vg_threadid   = tid;
194         DRD_(g_threadinfo)[i].pt_threadid   = INVALID_POSIX_THREADID;
195         DRD_(g_threadinfo)[i].stack_min     = 0;
196         DRD_(g_threadinfo)[i].stack_min_min = 0;
197         DRD_(g_threadinfo)[i].stack_startup = 0;
198         DRD_(g_threadinfo)[i].stack_max     = 0;
199         DRD_(thread_set_name)(i, "");
200         DRD_(g_threadinfo)[i].on_alt_stack        = False;
201         DRD_(g_threadinfo)[i].is_recording_loads  = True;
202         DRD_(g_threadinfo)[i].is_recording_stores = True;
203         DRD_(g_threadinfo)[i].pthread_create_nesting_level = 0;
204         DRD_(g_threadinfo)[i].synchr_nesting = 0;
205         DRD_(g_threadinfo)[i].deletion_seq = s_deletion_tail - 1;
206         tl_assert(DRD_(g_threadinfo)[i].sg_first == NULL);
207         tl_assert(DRD_(g_threadinfo)[i].sg_last == NULL);
208
209         tl_assert(DRD_(IsValidDrdThreadId)(i));
210
211         return i;
212      }
213   }
214
215   VG_(printf)(
216"\nSorry, but the maximum number of threads supported by DRD has been exceeded."
217"Aborting.\n");
218
219   tl_assert(False);
220
221   return DRD_INVALID_THREADID;
222}
223
224/** Convert a POSIX thread ID into a DRD thread ID. */
225DrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid)
226{
227   UInt i;
228
229   if (tid != INVALID_POSIX_THREADID)
230   {
231      for (i = 1; i < DRD_N_THREADS; i++)
232      {
233         if (DRD_(g_threadinfo)[i].posix_thread_exists
234             && DRD_(g_threadinfo)[i].pt_threadid == tid)
235         {
236            return i;
237         }
238      }
239   }
240   return DRD_INVALID_THREADID;
241}
242
243/** Convert a DRD thread ID into a Valgrind thread ID. */
244ThreadId DRD_(DrdThreadIdToVgThreadId)(const DrdThreadId tid)
245{
246   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
247             && tid != DRD_INVALID_THREADID);
248
249   return (DRD_(g_threadinfo)[tid].vg_thread_exists
250           ? DRD_(g_threadinfo)[tid].vg_threadid
251           : VG_INVALID_THREADID);
252}
253
254#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
255/**
256 * Sanity check of the doubly linked list of segments referenced by a
257 * ThreadInfo struct.
258 * @return True if sane, False if not.
259 */
260static Bool DRD_(sane_ThreadInfo)(const ThreadInfo* const ti)
261{
262   Segment* p;
263
264   for (p = ti->sg_first; p; p = p->thr_next) {
265      if (p->thr_next && p->thr_next->thr_prev != p)
266         return False;
267      if (p->thr_next == 0 && p != ti->sg_last)
268         return False;
269   }
270   for (p = ti->sg_last; p; p = p->thr_prev) {
271      if (p->thr_prev && p->thr_prev->thr_next != p)
272         return False;
273      if (p->thr_prev == 0 && p != ti->sg_first)
274         return False;
275   }
276   return True;
277}
278#endif
279
280/**
281 * Create the first segment for a newly started thread.
282 *
283 * This function is called from the handler installed via
284 * VG_(track_pre_thread_ll_create)(). The Valgrind core invokes this handler
285 * from the context of the creator thread, before the new thread has been
286 * created.
287 *
288 * @param[in] creator    DRD thread ID of the creator thread.
289 * @param[in] vg_created Valgrind thread ID of the created thread.
290 *
291 * @return DRD thread ID of the created thread.
292 */
293DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator,
294                                    const ThreadId vg_created)
295{
296   DrdThreadId created;
297
298   tl_assert(DRD_(VgThreadIdToDrdThreadId)(vg_created) == DRD_INVALID_THREADID);
299   created = DRD_(VgThreadIdToNewDrdThreadId)(vg_created);
300   tl_assert(0 <= (int)created && created < DRD_N_THREADS
301             && created != DRD_INVALID_THREADID);
302
303   tl_assert(DRD_(g_threadinfo)[created].sg_first == NULL);
304   tl_assert(DRD_(g_threadinfo)[created].sg_last == NULL);
305   /* Create an initial segment for the newly created thread. */
306   thread_append_segment(created, DRD_(sg_new)(creator, created));
307
308   return created;
309}
310
311/**
312 * Initialize DRD_(g_threadinfo)[] for a newly created thread. Must be called
313 * after the thread has been created and before any client instructions are run
314 * on the newly created thread, e.g. from the handler installed via
315 * VG_(track_pre_thread_first_insn)().
316 *
317 * @param[in] vg_created Valgrind thread ID of the newly created thread.
318 *
319 * @return DRD thread ID for the new thread.
320 */
321DrdThreadId DRD_(thread_post_create)(const ThreadId vg_created)
322{
323   const DrdThreadId created = DRD_(VgThreadIdToDrdThreadId)(vg_created);
324
325   tl_assert(0 <= (int)created && created < DRD_N_THREADS
326             && created != DRD_INVALID_THREADID);
327
328   DRD_(g_threadinfo)[created].stack_max
329      = VG_(thread_get_stack_max)(vg_created);
330   DRD_(g_threadinfo)[created].stack_startup
331      = DRD_(g_threadinfo)[created].stack_max;
332   DRD_(g_threadinfo)[created].stack_min
333      = DRD_(g_threadinfo)[created].stack_max;
334   DRD_(g_threadinfo)[created].stack_min_min
335      = DRD_(g_threadinfo)[created].stack_max;
336   DRD_(g_threadinfo)[created].stack_size
337      = VG_(thread_get_stack_size)(vg_created);
338   tl_assert(DRD_(g_threadinfo)[created].stack_max != 0);
339
340   return created;
341}
342
343static void DRD_(thread_delayed_delete)(const DrdThreadId tid)
344{
345   UInt j;
346
347   DRD_(g_threadinfo)[tid].vg_thread_exists = False;
348   DRD_(g_threadinfo)[tid].posix_thread_exists = False;
349   DRD_(g_threadinfo)[tid].deletion_seq = s_deletion_head++;
350#if 0
351   VG_(message)(Vg_DebugMsg, "Adding thread %d to the deletion list\n", tid);
352#endif
353   if (s_deletion_head - s_deletion_tail >= s_join_list_vol) {
354      for (j = 0; j < DRD_N_THREADS; ++j) {
355         if (DRD_(IsValidDrdThreadId)(j)
356             && DRD_(g_threadinfo)[j].deletion_seq == s_deletion_tail)
357         {
358            s_deletion_tail++;
359#if 0
360            VG_(message)(Vg_DebugMsg, "Delayed delete of thread %d\n", j);
361#endif
362            DRD_(thread_delete)(j, False);
363            break;
364         }
365      }
366   }
367}
368
369/**
370 * Process VG_USERREQ__POST_THREAD_JOIN. This client request is invoked just
371 * after thread drd_joiner joined thread drd_joinee.
372 */
373void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee)
374{
375   tl_assert(DRD_(IsValidDrdThreadId)(drd_joiner));
376   tl_assert(DRD_(IsValidDrdThreadId)(drd_joinee));
377
378   DRD_(thread_new_segment)(drd_joiner);
379   DRD_(thread_combine_vc_join)(drd_joiner, drd_joinee);
380   DRD_(thread_new_segment)(drd_joinee);
381
382   if (s_trace_fork_join)
383   {
384      const ThreadId joiner = DRD_(DrdThreadIdToVgThreadId)(drd_joiner);
385      const unsigned msg_size = 256;
386      HChar* msg;
387
388      msg = VG_(malloc)("drd.main.dptj.1", msg_size);
389
390      VG_(snprintf)(msg, msg_size,
391                    "drd_post_thread_join joiner = %d, joinee = %d",
392                    drd_joiner, drd_joinee);
393      if (joiner)
394      {
395         HChar* vc;
396
397         vc = DRD_(vc_aprint)(DRD_(thread_get_vc)(drd_joiner));
398         VG_(snprintf)(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg),
399                       ", new vc: %s", vc);
400         VG_(free)(vc);
401      }
402      DRD_(trace_msg)("%pS", msg);
403      VG_(free)(msg);
404   }
405
406   if (!  DRD_(get_check_stack_accesses)())
407   {
408      DRD_(finish_suppression)(DRD_(thread_get_stack_max)(drd_joinee)
409                               - DRD_(thread_get_stack_size)(drd_joinee),
410                               DRD_(thread_get_stack_max)(drd_joinee));
411   }
412   DRD_(clientobj_delete_thread)(drd_joinee);
413   DRD_(thread_delayed_delete)(drd_joinee);
414}
415
416/**
417 * NPTL hack: NPTL allocates the 'struct pthread' on top of the stack,
418 * and accesses this data structure from multiple threads without locking.
419 * Any conflicting accesses in the range stack_startup..stack_max will be
420 * ignored.
421 */
422void DRD_(thread_set_stack_startup)(const DrdThreadId tid,
423                                    const Addr stack_startup)
424{
425   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
426             && tid != DRD_INVALID_THREADID);
427   tl_assert(DRD_(g_threadinfo)[tid].stack_min <= stack_startup);
428   tl_assert(stack_startup <= DRD_(g_threadinfo)[tid].stack_max);
429   DRD_(g_threadinfo)[tid].stack_startup = stack_startup;
430}
431
432/** Return the stack pointer for the specified thread. */
433Addr DRD_(thread_get_stack_min)(const DrdThreadId tid)
434{
435   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
436             && tid != DRD_INVALID_THREADID);
437   return DRD_(g_threadinfo)[tid].stack_min;
438}
439
440/**
441 * Return the lowest value that was ever assigned to the stack pointer
442 * for the specified thread.
443 */
444Addr DRD_(thread_get_stack_min_min)(const DrdThreadId tid)
445{
446   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
447             && tid != DRD_INVALID_THREADID);
448   return DRD_(g_threadinfo)[tid].stack_min_min;
449}
450
451/** Return the top address for the stack of the specified thread. */
452Addr DRD_(thread_get_stack_max)(const DrdThreadId tid)
453{
454   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
455             && tid != DRD_INVALID_THREADID);
456   return DRD_(g_threadinfo)[tid].stack_max;
457}
458
459/** Return the maximum stack size for the specified thread. */
460SizeT DRD_(thread_get_stack_size)(const DrdThreadId tid)
461{
462   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
463             && tid != DRD_INVALID_THREADID);
464   return DRD_(g_threadinfo)[tid].stack_size;
465}
466
467Bool DRD_(thread_get_on_alt_stack)(const DrdThreadId tid)
468{
469   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
470             && tid != DRD_INVALID_THREADID);
471   return DRD_(g_threadinfo)[tid].on_alt_stack;
472}
473
474void DRD_(thread_set_on_alt_stack)(const DrdThreadId tid,
475                                   const Bool on_alt_stack)
476{
477   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
478             && tid != DRD_INVALID_THREADID);
479   tl_assert(on_alt_stack == !!on_alt_stack);
480   DRD_(g_threadinfo)[tid].on_alt_stack = on_alt_stack;
481}
482
483Int DRD_(thread_get_threads_on_alt_stack)(void)
484{
485   int n = 0;
486
487   for (UInt i = 1; i < DRD_N_THREADS; i++)
488      n += DRD_(g_threadinfo)[i].on_alt_stack;
489   return n;
490}
491
492/**
493 * Clean up thread-specific data structures.
494 */
495void DRD_(thread_delete)(const DrdThreadId tid, const Bool detached)
496{
497   Segment* sg;
498   Segment* sg_prev;
499
500   tl_assert(DRD_(IsValidDrdThreadId)(tid));
501
502   tl_assert(DRD_(g_threadinfo)[tid].synchr_nesting >= 0);
503   for (sg = DRD_(g_threadinfo)[tid].sg_last; sg; sg = sg_prev) {
504      sg_prev = sg->thr_prev;
505      sg->thr_next = NULL;
506      sg->thr_prev = NULL;
507      DRD_(sg_put)(sg);
508   }
509   DRD_(g_threadinfo)[tid].valid = False;
510   DRD_(g_threadinfo)[tid].vg_thread_exists = False;
511   DRD_(g_threadinfo)[tid].posix_thread_exists = False;
512   if (detached)
513      DRD_(g_threadinfo)[tid].detached_posix_thread = False;
514   else
515      tl_assert(!DRD_(g_threadinfo)[tid].detached_posix_thread);
516   DRD_(g_threadinfo)[tid].sg_first = NULL;
517   DRD_(g_threadinfo)[tid].sg_last = NULL;
518
519   tl_assert(!DRD_(IsValidDrdThreadId)(tid));
520}
521
522/**
523 * Called after a thread performed its last memory access and before
524 * thread_delete() is called. Note: thread_delete() is only called for
525 * joinable threads, not for detached threads.
526 */
527void DRD_(thread_finished)(const DrdThreadId tid)
528{
529   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
530             && tid != DRD_INVALID_THREADID);
531
532   DRD_(g_threadinfo)[tid].vg_thread_exists = False;
533
534   if (DRD_(g_threadinfo)[tid].detached_posix_thread)
535   {
536      /*
537       * Once a detached thread has finished, its stack is deallocated and
538       * should no longer be taken into account when computing the conflict set.
539       */
540      DRD_(g_threadinfo)[tid].stack_min = DRD_(g_threadinfo)[tid].stack_max;
541
542      /*
543       * For a detached thread, calling pthread_exit() invalidates the
544       * POSIX thread ID associated with the detached thread. For joinable
545       * POSIX threads however, the POSIX thread ID remains live after the
546       * pthread_exit() call until pthread_join() is called.
547       */
548      DRD_(g_threadinfo)[tid].posix_thread_exists = False;
549   }
550}
551
552/** Called just after fork() in the child process. */
553void DRD_(drd_thread_atfork_child)(const DrdThreadId tid)
554{
555   unsigned i;
556
557   for (i = 1; i < DRD_N_THREADS; i++)
558   {
559      if (i == tid)
560	 continue;
561      if (DRD_(IsValidDrdThreadId(i)))
562	 DRD_(thread_delete)(i, True);
563      tl_assert(!DRD_(IsValidDrdThreadId(i)));
564   }
565
566   DRD_(bm_cleanup)(DRD_(g_conflict_set));
567   DRD_(bm_init)(DRD_(g_conflict_set));
568}
569
570/** Called just before pthread_cancel(). */
571void DRD_(thread_pre_cancel)(const DrdThreadId tid)
572{
573   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
574             && tid != DRD_INVALID_THREADID);
575   tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID);
576
577   if (DRD_(thread_get_trace_fork_join)())
578      DRD_(trace_msg)("[%d] drd_thread_pre_cancel %d",
579                      DRD_(g_drd_running_tid), tid);
580}
581
582/**
583 * Store the POSIX thread ID for the specified thread.
584 *
585 * @note This function can be called two times for the same thread -- see also
586 * the comment block preceding the pthread_create() wrapper in
587 * drd_pthread_intercepts.c.
588 */
589void DRD_(thread_set_pthreadid)(const DrdThreadId tid, const PThreadId ptid)
590{
591   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
592             && tid != DRD_INVALID_THREADID);
593   tl_assert(DRD_(g_threadinfo)[tid].pt_threadid == INVALID_POSIX_THREADID
594             || DRD_(g_threadinfo)[tid].pt_threadid == ptid);
595   tl_assert(ptid != INVALID_POSIX_THREADID);
596   DRD_(g_threadinfo)[tid].posix_thread_exists = True;
597   DRD_(g_threadinfo)[tid].pt_threadid         = ptid;
598}
599
600/** Returns true for joinable threads and false for detached threads. */
601Bool DRD_(thread_get_joinable)(const DrdThreadId tid)
602{
603   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
604             && tid != DRD_INVALID_THREADID);
605   return ! DRD_(g_threadinfo)[tid].detached_posix_thread;
606}
607
608/** Store the thread mode: joinable or detached. */
609#if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
610 /* There is a cse related issue in gcc for MIPS. Optimization level
611    has to be lowered, so cse related optimizations are not
612    included.*/
613 __attribute__((optimize("O1")))
614#endif
615void DRD_(thread_set_joinable)(const DrdThreadId tid, const Bool joinable)
616{
617   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
618             && tid != DRD_INVALID_THREADID);
619   tl_assert((!! joinable) == joinable);
620   tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID);
621
622   DRD_(g_threadinfo)[tid].detached_posix_thread = ! joinable;
623}
624
625/** Tells DRD that the calling thread is about to enter pthread_create(). */
626void DRD_(thread_entering_pthread_create)(const DrdThreadId tid)
627{
628   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
629             && tid != DRD_INVALID_THREADID);
630   tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID);
631   tl_assert(DRD_(g_threadinfo)[tid].pthread_create_nesting_level >= 0);
632
633   DRD_(g_threadinfo)[tid].pthread_create_nesting_level++;
634}
635
636/** Tells DRD that the calling thread has left pthread_create(). */
637void DRD_(thread_left_pthread_create)(const DrdThreadId tid)
638{
639   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
640             && tid != DRD_INVALID_THREADID);
641   tl_assert(DRD_(g_threadinfo)[tid].pt_threadid != INVALID_POSIX_THREADID);
642   tl_assert(DRD_(g_threadinfo)[tid].pthread_create_nesting_level > 0);
643
644   DRD_(g_threadinfo)[tid].pthread_create_nesting_level--;
645}
646
647/** Obtain the thread number and the user-assigned thread name. */
648const HChar* DRD_(thread_get_name)(const DrdThreadId tid)
649{
650   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
651             && tid != DRD_INVALID_THREADID);
652
653   return DRD_(g_threadinfo)[tid].name;
654}
655
656/** Set the name of the specified thread. */
657void DRD_(thread_set_name)(const DrdThreadId tid, const HChar* const name)
658{
659   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
660             && tid != DRD_INVALID_THREADID);
661
662   if (name == NULL || name[0] == 0)
663      VG_(snprintf)(DRD_(g_threadinfo)[tid].name,
664                    sizeof(DRD_(g_threadinfo)[tid].name),
665                    "Thread %d",
666                    tid);
667   else
668      VG_(snprintf)(DRD_(g_threadinfo)[tid].name,
669                    sizeof(DRD_(g_threadinfo)[tid].name),
670                    "Thread %d (%s)",
671                    tid, name);
672   DRD_(g_threadinfo)[tid].name[sizeof(DRD_(g_threadinfo)[tid].name) - 1] = 0;
673}
674
675/**
676 * Update s_vg_running_tid, DRD_(g_drd_running_tid) and recalculate the
677 * conflict set.
678 */
679void DRD_(thread_set_vg_running_tid)(const ThreadId vg_tid)
680{
681   tl_assert(vg_tid != VG_INVALID_THREADID);
682
683   if (vg_tid != s_vg_running_tid)
684   {
685      DRD_(thread_set_running_tid)(vg_tid,
686                                   DRD_(VgThreadIdToDrdThreadId)(vg_tid));
687   }
688
689   tl_assert(s_vg_running_tid != VG_INVALID_THREADID);
690   tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID);
691}
692
693/**
694 * Update s_vg_running_tid, DRD_(g_drd_running_tid) and recalculate the
695 * conflict set.
696 */
697void DRD_(thread_set_running_tid)(const ThreadId vg_tid,
698                                  const DrdThreadId drd_tid)
699{
700   tl_assert(vg_tid != VG_INVALID_THREADID);
701   tl_assert(drd_tid != DRD_INVALID_THREADID);
702
703   if (vg_tid != s_vg_running_tid)
704   {
705      if (s_trace_context_switches
706          && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID)
707      {
708         VG_(message)(Vg_DebugMsg,
709                      "Context switch from thread %d to thread %d;"
710                      " segments: %llu\n",
711                      DRD_(g_drd_running_tid), drd_tid,
712                      DRD_(sg_get_segments_alive_count)());
713      }
714      s_vg_running_tid = vg_tid;
715      DRD_(g_drd_running_tid) = drd_tid;
716      thread_compute_conflict_set(&DRD_(g_conflict_set), drd_tid);
717      s_context_switch_count++;
718   }
719
720   tl_assert(s_vg_running_tid != VG_INVALID_THREADID);
721   tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID);
722}
723
724/**
725 * Increase the synchronization nesting counter. Must be called before the
726 * client calls a synchronization function.
727 */
728int DRD_(thread_enter_synchr)(const DrdThreadId tid)
729{
730   tl_assert(DRD_(IsValidDrdThreadId)(tid));
731   return DRD_(g_threadinfo)[tid].synchr_nesting++;
732}
733
734/**
735 * Decrease the synchronization nesting counter. Must be called after the
736 * client left a synchronization function.
737 */
738int DRD_(thread_leave_synchr)(const DrdThreadId tid)
739{
740   tl_assert(DRD_(IsValidDrdThreadId)(tid));
741   tl_assert(DRD_(g_threadinfo)[tid].synchr_nesting >= 1);
742   return --DRD_(g_threadinfo)[tid].synchr_nesting;
743}
744
745/** Returns the synchronization nesting counter. */
746int DRD_(thread_get_synchr_nesting_count)(const DrdThreadId tid)
747{
748   tl_assert(DRD_(IsValidDrdThreadId)(tid));
749   return DRD_(g_threadinfo)[tid].synchr_nesting;
750}
751
752/** Append a new segment at the end of the segment list. */
753static
754void thread_append_segment(const DrdThreadId tid, Segment* const sg)
755{
756   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
757             && tid != DRD_INVALID_THREADID);
758
759#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
760   tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid]));
761#endif
762
763   // add at tail
764   sg->thr_prev = DRD_(g_threadinfo)[tid].sg_last;
765   sg->thr_next = NULL;
766   if (DRD_(g_threadinfo)[tid].sg_last)
767      DRD_(g_threadinfo)[tid].sg_last->thr_next = sg;
768   DRD_(g_threadinfo)[tid].sg_last = sg;
769   if (DRD_(g_threadinfo)[tid].sg_first == NULL)
770      DRD_(g_threadinfo)[tid].sg_first = sg;
771
772#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
773   tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid]));
774#endif
775}
776
777/**
778 * Remove a segment from the segment list of thread threadid, and free the
779 * associated memory.
780 */
781static
782void thread_discard_segment(const DrdThreadId tid, Segment* const sg)
783{
784   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
785             && tid != DRD_INVALID_THREADID);
786
787#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
788   tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid]));
789#endif
790
791   if (sg->thr_prev)
792      sg->thr_prev->thr_next = sg->thr_next;
793   if (sg->thr_next)
794      sg->thr_next->thr_prev = sg->thr_prev;
795   if (sg == DRD_(g_threadinfo)[tid].sg_first)
796      DRD_(g_threadinfo)[tid].sg_first = sg->thr_next;
797   if (sg == DRD_(g_threadinfo)[tid].sg_last)
798      DRD_(g_threadinfo)[tid].sg_last = sg->thr_prev;
799   DRD_(sg_put)(sg);
800
801#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
802   tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid]));
803#endif
804}
805
806/**
807 * Returns a pointer to the vector clock of the most recent segment associated
808 * with thread 'tid'.
809 */
810VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid)
811{
812   Segment* latest_sg;
813
814   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
815             && tid != DRD_INVALID_THREADID);
816   latest_sg = DRD_(g_threadinfo)[tid].sg_last;
817   tl_assert(latest_sg);
818   return &latest_sg->vc;
819}
820
821/**
822 * Return the latest segment of thread 'tid' and increment its reference count.
823 */
824void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid)
825{
826   Segment* latest_sg;
827
828   tl_assert(sg);
829   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
830             && tid != DRD_INVALID_THREADID);
831   latest_sg = DRD_(g_threadinfo)[tid].sg_last;
832   tl_assert(latest_sg);
833
834   DRD_(sg_put)(*sg);
835   *sg = DRD_(sg_get)(latest_sg);
836}
837
838/**
839 * Compute the minimum of all latest vector clocks of all threads
840 * (Michiel Ronsse calls this "clock snooping" in his papers about DIOTA).
841 *
842 * @param vc pointer to a vectorclock, holds result upon return.
843 */
844static void DRD_(thread_compute_minimum_vc)(VectorClock* vc)
845{
846   unsigned i;
847   Bool first;
848   Segment* latest_sg;
849
850   first = True;
851   for (i = 0; i < DRD_N_THREADS; i++)
852   {
853      latest_sg = DRD_(g_threadinfo)[i].sg_last;
854      if (latest_sg) {
855         if (first)
856            DRD_(vc_assign)(vc, &latest_sg->vc);
857         else
858            DRD_(vc_min)(vc, &latest_sg->vc);
859         first = False;
860      }
861   }
862}
863
864/**
865 * Compute the maximum of all latest vector clocks of all threads.
866 *
867 * @param vc pointer to a vectorclock, holds result upon return.
868 */
869static void DRD_(thread_compute_maximum_vc)(VectorClock* vc)
870{
871   unsigned i;
872   Bool first;
873   Segment* latest_sg;
874
875   first = True;
876   for (i = 0; i < DRD_N_THREADS; i++)
877   {
878      latest_sg = DRD_(g_threadinfo)[i].sg_last;
879      if (latest_sg) {
880         if (first)
881            DRD_(vc_assign)(vc, &latest_sg->vc);
882         else
883            DRD_(vc_combine)(vc, &latest_sg->vc);
884         first = False;
885      }
886   }
887}
888
889/**
890 * Discard all segments that have a defined order against the latest vector
891 * clock of all threads -- these segments can no longer be involved in a
892 * data race.
893 */
894static void thread_discard_ordered_segments(void)
895{
896   unsigned i;
897   VectorClock thread_vc_min;
898
899   s_discard_ordered_segments_count++;
900
901   DRD_(vc_init)(&thread_vc_min, 0, 0);
902   DRD_(thread_compute_minimum_vc)(&thread_vc_min);
903   if (DRD_(sg_get_trace)())
904   {
905      HChar *vc_min, *vc_max;
906      VectorClock thread_vc_max;
907
908      DRD_(vc_init)(&thread_vc_max, 0, 0);
909      DRD_(thread_compute_maximum_vc)(&thread_vc_max);
910      vc_min = DRD_(vc_aprint)(&thread_vc_min);
911      vc_max = DRD_(vc_aprint)(&thread_vc_max);
912      VG_(message)(Vg_DebugMsg,
913                   "Discarding ordered segments -- min vc is %s, max vc is %s\n",
914                   vc_min, vc_max);
915      VG_(free)(vc_min);
916      VG_(free)(vc_max);
917      DRD_(vc_cleanup)(&thread_vc_max);
918   }
919
920   for (i = 0; i < DRD_N_THREADS; i++) {
921      Segment* sg;
922      Segment* sg_next;
923
924      for (sg = DRD_(g_threadinfo)[i].sg_first;
925           sg && (sg_next = sg->thr_next)
926              && DRD_(vc_lte)(&sg->vc, &thread_vc_min);
927           sg = sg_next)
928      {
929         thread_discard_segment(i, sg);
930      }
931   }
932   DRD_(vc_cleanup)(&thread_vc_min);
933}
934
935/**
936 * An implementation of the property 'equiv(sg1, sg2)' as defined in the paper
937 * by Mark Christiaens e.a. The property equiv(sg1, sg2) holds if and only if
938 * all segments in the set CS are ordered consistently against both sg1 and
939 * sg2. The set CS is defined as the set of segments that can immediately
940 * precede future segments via inter-thread synchronization operations. In
941 * DRD the set CS consists of the latest segment of each thread combined with
942 * all segments for which the reference count is strictly greater than one.
943 * The code below is an optimized version of the following:
944 *
945 * for (i = 0; i < DRD_N_THREADS; i++)
946 * {
947 *    Segment* sg;
948 *
949 *    for (sg = DRD_(g_threadinfo)[i].first; sg; sg = sg->next)
950 *    {
951 *       if (sg == DRD_(g_threadinfo)[i].last || DRD_(sg_get_refcnt)(sg) > 1)
952 *       {
953 *          if (   DRD_(vc_lte)(&sg1->vc, &sg->vc)
954 *              != DRD_(vc_lte)(&sg2->vc, &sg->vc)
955 *              || DRD_(vc_lte)(&sg->vc, &sg1->vc)
956 *              != DRD_(vc_lte)(&sg->vc, &sg2->vc))
957 *          {
958 *             return False;
959 *          }
960 *       }
961 *    }
962 * }
963 */
964static Bool thread_consistent_segment_ordering(const DrdThreadId tid,
965                                               Segment* const sg1,
966                                               Segment* const sg2)
967{
968   unsigned i;
969
970   tl_assert(sg1->thr_next);
971   tl_assert(sg2->thr_next);
972   tl_assert(sg1->thr_next == sg2);
973   tl_assert(DRD_(vc_lte)(&sg1->vc, &sg2->vc));
974
975   for (i = 0; i < DRD_N_THREADS; i++)
976   {
977      Segment* sg;
978
979      for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) {
980         if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) {
981            if (DRD_(vc_lte)(&sg2->vc, &sg->vc))
982               break;
983            if (DRD_(vc_lte)(&sg1->vc, &sg->vc))
984               return False;
985         }
986      }
987      for (sg = DRD_(g_threadinfo)[i].sg_last; sg; sg = sg->thr_prev) {
988         if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) {
989            if (DRD_(vc_lte)(&sg->vc, &sg1->vc))
990               break;
991            if (DRD_(vc_lte)(&sg->vc, &sg2->vc))
992               return False;
993         }
994      }
995   }
996   return True;
997}
998
999/**
1000 * Merge all segments that may be merged without triggering false positives
1001 * or discarding real data races. For the theoretical background of segment
1002 * merging, see also the following paper: Mark Christiaens, Michiel Ronsse
1003 * and Koen De Bosschere. Bounding the number of segment histories during
1004 * data race detection. Parallel Computing archive, Volume 28, Issue 9,
1005 * pp 1221-1238, September 2002. This paper contains a proof that merging
1006 * consecutive segments for which the property equiv(s1,s2) holds can be
1007 * merged without reducing the accuracy of datarace detection. Furthermore
1008 * it is also proven that the total number of all segments will never grow
1009 * unbounded if all segments s1, s2 for which equiv(s1, s2) holds are merged
1010 * every time a new segment is created. The property equiv(s1, s2) is defined
1011 * as follows: equiv(s1, s2) <=> for all segments in the set CS, the vector
1012 * clocks of segments s and s1 are ordered in the same way as those of segments
1013 * s and s2. The set CS is defined as the set of existing segments s that have
1014 * the potential to conflict with not yet created segments, either because the
1015 * segment s is the latest segment of a thread or because it can become the
1016 * immediate predecessor of a new segment due to a synchronization operation.
1017 */
1018static void thread_merge_segments(void)
1019{
1020   unsigned i;
1021
1022   s_new_segments_since_last_merge = 0;
1023
1024   for (i = 0; i < DRD_N_THREADS; i++)
1025   {
1026      Segment* sg;
1027
1028#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
1029      tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[i]));
1030#endif
1031
1032      for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) {
1033         if (DRD_(sg_get_refcnt)(sg) == 1 && sg->thr_next) {
1034            Segment* const sg_next = sg->thr_next;
1035            if (DRD_(sg_get_refcnt)(sg_next) == 1
1036                && sg_next->thr_next
1037                && thread_consistent_segment_ordering(i, sg, sg_next))
1038            {
1039               /* Merge sg and sg_next into sg. */
1040               DRD_(sg_merge)(sg, sg_next);
1041               thread_discard_segment(i, sg_next);
1042            }
1043         }
1044      }
1045
1046#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
1047      tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[i]));
1048#endif
1049   }
1050}
1051
1052/**
1053 * Create a new segment for the specified thread, and discard any segments
1054 * that cannot cause races anymore.
1055 */
1056void DRD_(thread_new_segment)(const DrdThreadId tid)
1057{
1058   Segment* last_sg;
1059   Segment* new_sg;
1060
1061   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1062             && tid != DRD_INVALID_THREADID);
1063   tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid)));
1064
1065   last_sg = DRD_(g_threadinfo)[tid].sg_last;
1066   new_sg = DRD_(sg_new)(tid, tid);
1067   thread_append_segment(tid, new_sg);
1068   if (tid == DRD_(g_drd_running_tid) && last_sg)
1069   {
1070      DRD_(thread_update_conflict_set)(tid, &last_sg->vc);
1071      s_update_conflict_set_new_sg_count++;
1072   }
1073
1074   tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid)));
1075
1076   if (s_segment_merging
1077       && ++s_new_segments_since_last_merge >= s_segment_merge_interval)
1078   {
1079      thread_discard_ordered_segments();
1080      thread_merge_segments();
1081   }
1082}
1083
1084/** Call this function after thread 'joiner' joined thread 'joinee'. */
1085void DRD_(thread_combine_vc_join)(DrdThreadId joiner, DrdThreadId joinee)
1086{
1087   tl_assert(joiner != joinee);
1088   tl_assert(0 <= (int)joiner && joiner < DRD_N_THREADS
1089             && joiner != DRD_INVALID_THREADID);
1090   tl_assert(0 <= (int)joinee && joinee < DRD_N_THREADS
1091             && joinee != DRD_INVALID_THREADID);
1092   tl_assert(DRD_(g_threadinfo)[joiner].sg_first);
1093   tl_assert(DRD_(g_threadinfo)[joiner].sg_last);
1094   tl_assert(DRD_(g_threadinfo)[joinee].sg_first);
1095   tl_assert(DRD_(g_threadinfo)[joinee].sg_last);
1096
1097   if (DRD_(sg_get_trace)())
1098   {
1099      HChar *str1, *str2;
1100      str1 = DRD_(vc_aprint)(DRD_(thread_get_vc)(joiner));
1101      str2 = DRD_(vc_aprint)(DRD_(thread_get_vc)(joinee));
1102      VG_(message)(Vg_DebugMsg, "Before join: joiner %s, joinee %s\n",
1103                   str1, str2);
1104      VG_(free)(str1);
1105      VG_(free)(str2);
1106   }
1107   if (joiner == DRD_(g_drd_running_tid)) {
1108      VectorClock old_vc;
1109
1110      DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(joiner));
1111      DRD_(vc_combine)(DRD_(thread_get_vc)(joiner),
1112                       DRD_(thread_get_vc)(joinee));
1113      DRD_(thread_update_conflict_set)(joiner, &old_vc);
1114      s_update_conflict_set_join_count++;
1115      DRD_(vc_cleanup)(&old_vc);
1116   } else {
1117      DRD_(vc_combine)(DRD_(thread_get_vc)(joiner),
1118                       DRD_(thread_get_vc)(joinee));
1119   }
1120
1121   thread_discard_ordered_segments();
1122
1123   if (DRD_(sg_get_trace)()) {
1124      HChar* str;
1125
1126      str = DRD_(vc_aprint)(DRD_(thread_get_vc)(joiner));
1127      VG_(message)(Vg_DebugMsg, "After join: %s\n", str);
1128      VG_(free)(str);
1129   }
1130}
1131
1132/**
1133 * Update the vector clock of the last segment of thread tid with the
1134 * the vector clock of segment sg.
1135 */
1136static void thread_combine_vc_sync(DrdThreadId tid, const Segment* sg)
1137{
1138   const VectorClock* const vc = &sg->vc;
1139
1140   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1141             && tid != DRD_INVALID_THREADID);
1142   tl_assert(DRD_(g_threadinfo)[tid].sg_first);
1143   tl_assert(DRD_(g_threadinfo)[tid].sg_last);
1144   tl_assert(sg);
1145   tl_assert(vc);
1146
1147   if (tid != sg->tid) {
1148      VectorClock old_vc;
1149
1150      DRD_(vc_copy)(&old_vc, DRD_(thread_get_vc)(tid));
1151      DRD_(vc_combine)(DRD_(thread_get_vc)(tid), vc);
1152      if (DRD_(sg_get_trace)()) {
1153         HChar *str1, *str2;
1154         str1 = DRD_(vc_aprint)(&old_vc);
1155         str2 = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid));
1156         VG_(message)(Vg_DebugMsg, "thread %d: vc %s -> %s\n", tid, str1, str2);
1157         VG_(free)(str1);
1158         VG_(free)(str2);
1159      }
1160
1161      thread_discard_ordered_segments();
1162
1163      DRD_(thread_update_conflict_set)(tid, &old_vc);
1164      s_update_conflict_set_sync_count++;
1165
1166      DRD_(vc_cleanup)(&old_vc);
1167   } else {
1168      tl_assert(DRD_(vc_lte)(vc, DRD_(thread_get_vc)(tid)));
1169   }
1170}
1171
1172/**
1173 * Create a new segment for thread tid and update the vector clock of the last
1174 * segment of this thread with the the vector clock of segment sg. Call this
1175 * function after thread tid had to wait because of thread synchronization
1176 * until the memory accesses in the segment sg finished.
1177 */
1178void DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid, const Segment* sg)
1179{
1180   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1181             && tid != DRD_INVALID_THREADID);
1182   tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid)));
1183   tl_assert(sg);
1184
1185   thread_append_segment(tid, DRD_(sg_new)(tid, tid));
1186
1187   thread_combine_vc_sync(tid, sg);
1188
1189   if (s_segment_merging
1190       && ++s_new_segments_since_last_merge >= s_segment_merge_interval)
1191   {
1192      thread_discard_ordered_segments();
1193      thread_merge_segments();
1194   }
1195}
1196
1197/**
1198 * Call this function whenever a thread is no longer using the memory
1199 * [ a1, a2 [, e.g. because of a call to free() or a stack pointer
1200 * increase.
1201 */
1202void DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2)
1203{
1204   Segment* p;
1205
1206   for (p = DRD_(g_sg_list); p; p = p->g_next)
1207      DRD_(bm_clear)(DRD_(sg_bm)(p), a1, a2);
1208
1209   DRD_(bm_clear)(DRD_(g_conflict_set), a1, a2);
1210}
1211
1212/** Specify whether memory loads should be recorded. */
1213void DRD_(thread_set_record_loads)(const DrdThreadId tid, const Bool enabled)
1214{
1215   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1216             && tid != DRD_INVALID_THREADID);
1217   tl_assert(enabled == !! enabled);
1218
1219   DRD_(g_threadinfo)[tid].is_recording_loads = enabled;
1220}
1221
1222/** Specify whether memory stores should be recorded. */
1223void DRD_(thread_set_record_stores)(const DrdThreadId tid, const Bool enabled)
1224{
1225   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1226             && tid != DRD_INVALID_THREADID);
1227   tl_assert(enabled == !! enabled);
1228
1229   DRD_(g_threadinfo)[tid].is_recording_stores = enabled;
1230}
1231
1232/**
1233 * Print the segment information for all threads.
1234 *
1235 * This function is only used for debugging purposes.
1236 */
1237void DRD_(thread_print_all)(void)
1238{
1239   unsigned i;
1240   Segment* p;
1241
1242   for (i = 0; i < DRD_N_THREADS; i++)
1243   {
1244      p = DRD_(g_threadinfo)[i].sg_first;
1245      if (p) {
1246         VG_(printf)("**************\n"
1247                     "* thread %3d (%d/%d/%d/%d/0x%lx/%d) *\n"
1248                     "**************\n",
1249                     i,
1250                     DRD_(g_threadinfo)[i].valid,
1251                     DRD_(g_threadinfo)[i].vg_thread_exists,
1252                     DRD_(g_threadinfo)[i].vg_threadid,
1253                     DRD_(g_threadinfo)[i].posix_thread_exists,
1254                     DRD_(g_threadinfo)[i].pt_threadid,
1255                     DRD_(g_threadinfo)[i].detached_posix_thread);
1256         for ( ; p; p = p->thr_next)
1257            DRD_(sg_print)(p);
1258      }
1259   }
1260}
1261
1262/** Show a call stack involved in a data race. */
1263static void show_call_stack(const DrdThreadId tid, ExeContext* const callstack)
1264{
1265   const ThreadId vg_tid = DRD_(DrdThreadIdToVgThreadId)(tid);
1266
1267   if (vg_tid != VG_INVALID_THREADID) {
1268      if (callstack)
1269         VG_(pp_ExeContext)(callstack);
1270      else
1271         VG_(get_and_pp_StackTrace)(vg_tid, VG_(clo_backtrace_size));
1272   } else {
1273      if (!VG_(clo_xml))
1274         VG_(message)(Vg_UserMsg,
1275                      "   (thread finished, call stack no longer available)\n");
1276   }
1277}
1278
1279/** Print information about the segments involved in a data race. */
1280static void
1281thread_report_conflicting_segments_segment(const DrdThreadId tid,
1282                                           const Addr addr,
1283                                           const SizeT size,
1284                                           const BmAccessTypeT access_type,
1285                                           const Segment* const p)
1286{
1287   unsigned i;
1288
1289   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1290             && tid != DRD_INVALID_THREADID);
1291   tl_assert(p);
1292
1293   for (i = 0; i < DRD_N_THREADS; i++) {
1294      if (i != tid) {
1295         Segment* q;
1296
1297         for (q = DRD_(g_threadinfo)[i].sg_last; q; q = q->thr_prev) {
1298            /*
1299             * Since q iterates over the segments of thread i in order of
1300             * decreasing vector clocks, if q->vc <= p->vc, then
1301             * q->next->vc <= p->vc will also hold. Hence, break out of the
1302             * loop once this condition is met.
1303             */
1304            if (DRD_(vc_lte)(&q->vc, &p->vc))
1305               break;
1306            if (!DRD_(vc_lte)(&p->vc, &q->vc)) {
1307               if (DRD_(bm_has_conflict_with)(DRD_(sg_bm)(q), addr, addr + size,
1308                                              access_type)) {
1309                  Segment* q_next;
1310
1311                  tl_assert(q->stacktrace);
1312                  if (VG_(clo_xml))
1313                     VG_(printf_xml)("  <other_segment_start>\n");
1314                  else
1315                     VG_(message)(Vg_UserMsg,
1316                                  "Other segment start (thread %d)\n", i);
1317                  show_call_stack(i, q->stacktrace);
1318                  if (VG_(clo_xml))
1319                     VG_(printf_xml)("  </other_segment_start>\n"
1320                                     "  <other_segment_end>\n");
1321                  else
1322                     VG_(message)(Vg_UserMsg,
1323                                  "Other segment end (thread %d)\n", i);
1324                  q_next = q->thr_next;
1325                  show_call_stack(i, q_next ? q_next->stacktrace : 0);
1326                  if (VG_(clo_xml))
1327                     VG_(printf_xml)("  </other_segment_end>\n");
1328               }
1329            }
1330         }
1331      }
1332   }
1333}
1334
1335/** Print information about all segments involved in a data race. */
1336void DRD_(thread_report_conflicting_segments)(const DrdThreadId tid,
1337                                              const Addr addr,
1338                                              const SizeT size,
1339                                              const BmAccessTypeT access_type)
1340{
1341   Segment* p;
1342
1343   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1344             && tid != DRD_INVALID_THREADID);
1345
1346   for (p = DRD_(g_threadinfo)[tid].sg_first; p; p = p->thr_next) {
1347      if (DRD_(bm_has)(DRD_(sg_bm)(p), addr, addr + size, access_type))
1348         thread_report_conflicting_segments_segment(tid, addr, size,
1349                                                    access_type, p);
1350   }
1351}
1352
1353/**
1354 * Verify whether the conflict set for thread tid is up to date. Only perform
1355 * the check if the environment variable DRD_VERIFY_CONFLICT_SET has been set.
1356 */
1357static Bool thread_conflict_set_up_to_date(const DrdThreadId tid)
1358{
1359   Bool result;
1360   struct bitmap* computed_conflict_set = 0;
1361
1362   if (!DRD_(verify_conflict_set))
1363      return True;
1364
1365   thread_compute_conflict_set(&computed_conflict_set, tid);
1366   result = DRD_(bm_equal)(DRD_(g_conflict_set), computed_conflict_set);
1367   if (! result)
1368   {
1369      VG_(printf)("actual conflict set:\n");
1370      DRD_(bm_print)(DRD_(g_conflict_set));
1371      VG_(printf)("\n");
1372      VG_(printf)("computed conflict set:\n");
1373      DRD_(bm_print)(computed_conflict_set);
1374      VG_(printf)("\n");
1375   }
1376   DRD_(bm_delete)(computed_conflict_set);
1377   return result;
1378}
1379
1380/**
1381 * Compute the conflict set: a bitmap that represents the union of all memory
1382 * accesses of all segments that are unordered to the current segment of the
1383 * thread tid.
1384 */
1385static void thread_compute_conflict_set(struct bitmap** conflict_set,
1386                                        const DrdThreadId tid)
1387{
1388   Segment* p;
1389
1390   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1391             && tid != DRD_INVALID_THREADID);
1392   tl_assert(tid == DRD_(g_drd_running_tid));
1393
1394   s_compute_conflict_set_count++;
1395   s_conflict_set_bitmap_creation_count
1396      -= DRD_(bm_get_bitmap_creation_count)();
1397   s_conflict_set_bitmap2_creation_count
1398      -= DRD_(bm_get_bitmap2_creation_count)();
1399
1400   if (*conflict_set) {
1401      DRD_(bm_cleanup)(*conflict_set);
1402      DRD_(bm_init)(*conflict_set);
1403   } else {
1404      *conflict_set = DRD_(bm_new)();
1405   }
1406
1407   if (s_trace_conflict_set) {
1408      HChar* str;
1409
1410      str = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid));
1411      VG_(message)(Vg_DebugMsg,
1412                   "computing conflict set for thread %d with vc %s\n",
1413                   tid, str);
1414      VG_(free)(str);
1415   }
1416
1417   p = DRD_(g_threadinfo)[tid].sg_last;
1418   {
1419      unsigned j;
1420
1421      if (s_trace_conflict_set) {
1422         HChar* vc;
1423
1424         vc = DRD_(vc_aprint)(&p->vc);
1425         VG_(message)(Vg_DebugMsg, "conflict set: thread [%d] at vc %s\n",
1426                      tid, vc);
1427         VG_(free)(vc);
1428      }
1429
1430      for (j = 0; j < DRD_N_THREADS; j++) {
1431         if (j != tid && DRD_(IsValidDrdThreadId)(j)) {
1432            Segment* q;
1433
1434            for (q = DRD_(g_threadinfo)[j].sg_last; q; q = q->thr_prev) {
1435               if (!DRD_(vc_lte)(&q->vc, &p->vc)
1436                   && !DRD_(vc_lte)(&p->vc, &q->vc)) {
1437                  if (s_trace_conflict_set) {
1438                     HChar* str;
1439
1440                     str = DRD_(vc_aprint)(&q->vc);
1441                     VG_(message)(Vg_DebugMsg,
1442                                  "conflict set: [%d] merging segment %s\n",
1443                                  j, str);
1444                     VG_(free)(str);
1445                  }
1446                  DRD_(bm_merge2)(*conflict_set, DRD_(sg_bm)(q));
1447               } else {
1448                  if (s_trace_conflict_set) {
1449                     HChar* str;
1450
1451                     str = DRD_(vc_aprint)(&q->vc);
1452                     VG_(message)(Vg_DebugMsg,
1453                                  "conflict set: [%d] ignoring segment %s\n",
1454                                  j, str);
1455                     VG_(free)(str);
1456                  }
1457               }
1458            }
1459         }
1460      }
1461   }
1462
1463   s_conflict_set_bitmap_creation_count
1464      += DRD_(bm_get_bitmap_creation_count)();
1465   s_conflict_set_bitmap2_creation_count
1466      += DRD_(bm_get_bitmap2_creation_count)();
1467
1468   if (s_trace_conflict_set_bm) {
1469      VG_(message)(Vg_DebugMsg, "[%d] new conflict set:\n", tid);
1470      DRD_(bm_print)(*conflict_set);
1471      VG_(message)(Vg_DebugMsg, "[%d] end of new conflict set.\n", tid);
1472   }
1473}
1474
1475/**
1476 * Update the conflict set after the vector clock of thread tid has been
1477 * updated from old_vc to its current value, either because a new segment has
1478 * been created or because of a synchronization operation.
1479 */
1480void DRD_(thread_update_conflict_set)(const DrdThreadId tid,
1481                                      const VectorClock* const old_vc)
1482{
1483   const VectorClock* new_vc;
1484   Segment* p;
1485   unsigned j;
1486
1487   tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
1488             && tid != DRD_INVALID_THREADID);
1489   tl_assert(old_vc);
1490   tl_assert(tid == DRD_(g_drd_running_tid));
1491   tl_assert(DRD_(g_conflict_set));
1492
1493   if (s_trace_conflict_set) {
1494      HChar* str;
1495
1496      str = DRD_(vc_aprint)(DRD_(thread_get_vc)(tid));
1497      VG_(message)(Vg_DebugMsg,
1498                   "updating conflict set for thread %d with vc %s\n",
1499                   tid, str);
1500      VG_(free)(str);
1501   }
1502
1503   new_vc = DRD_(thread_get_vc)(tid);
1504   tl_assert(DRD_(vc_lte)(old_vc, new_vc));
1505
1506   DRD_(bm_unmark)(DRD_(g_conflict_set));
1507
1508   for (j = 0; j < DRD_N_THREADS; j++)
1509   {
1510      Segment* q;
1511
1512      if (j == tid || ! DRD_(IsValidDrdThreadId)(j))
1513         continue;
1514
1515      for (q = DRD_(g_threadinfo)[j].sg_last;
1516           q && !DRD_(vc_lte)(&q->vc, new_vc);
1517           q = q->thr_prev) {
1518         const Bool included_in_old_conflict_set
1519            = !DRD_(vc_lte)(old_vc, &q->vc);
1520         const Bool included_in_new_conflict_set
1521            = !DRD_(vc_lte)(new_vc, &q->vc);
1522
1523         if (UNLIKELY(s_trace_conflict_set)) {
1524            HChar* str;
1525
1526            str = DRD_(vc_aprint)(&q->vc);
1527            VG_(message)(Vg_DebugMsg,
1528                         "conflict set: [%d] %s segment %s\n", j,
1529                         included_in_old_conflict_set
1530                         != included_in_new_conflict_set
1531                         ? "merging" : "ignoring", str);
1532            VG_(free)(str);
1533         }
1534         if (included_in_old_conflict_set != included_in_new_conflict_set)
1535            DRD_(bm_mark)(DRD_(g_conflict_set), DRD_(sg_bm)(q));
1536      }
1537
1538      for ( ; q && !DRD_(vc_lte)(&q->vc, old_vc); q = q->thr_prev) {
1539         const Bool included_in_old_conflict_set
1540            = !DRD_(vc_lte)(old_vc, &q->vc);
1541         const Bool included_in_new_conflict_set
1542            = !DRD_(vc_lte)(&q->vc, new_vc)
1543            && !DRD_(vc_lte)(new_vc, &q->vc);
1544
1545         if (UNLIKELY(s_trace_conflict_set)) {
1546            HChar* str;
1547
1548            str = DRD_(vc_aprint)(&q->vc);
1549            VG_(message)(Vg_DebugMsg,
1550                         "conflict set: [%d] %s segment %s\n", j,
1551                         included_in_old_conflict_set
1552                         != included_in_new_conflict_set
1553                         ? "merging" : "ignoring", str);
1554            VG_(free)(str);
1555         }
1556         if (included_in_old_conflict_set != included_in_new_conflict_set)
1557            DRD_(bm_mark)(DRD_(g_conflict_set), DRD_(sg_bm)(q));
1558      }
1559   }
1560
1561   DRD_(bm_clear_marked)(DRD_(g_conflict_set));
1562
1563   p = DRD_(g_threadinfo)[tid].sg_last;
1564   for (j = 0; j < DRD_N_THREADS; j++) {
1565      if (j != tid && DRD_(IsValidDrdThreadId)(j)) {
1566         Segment* q;
1567         for (q = DRD_(g_threadinfo)[j].sg_last;
1568              q && !DRD_(vc_lte)(&q->vc, &p->vc);
1569              q = q->thr_prev) {
1570            if (!DRD_(vc_lte)(&p->vc, &q->vc))
1571               DRD_(bm_merge2_marked)(DRD_(g_conflict_set), DRD_(sg_bm)(q));
1572         }
1573      }
1574   }
1575
1576   DRD_(bm_remove_cleared_marked)(DRD_(g_conflict_set));
1577
1578   s_update_conflict_set_count++;
1579
1580   if (s_trace_conflict_set_bm)
1581   {
1582      VG_(message)(Vg_DebugMsg, "[%d] updated conflict set:\n", tid);
1583      DRD_(bm_print)(DRD_(g_conflict_set));
1584      VG_(message)(Vg_DebugMsg, "[%d] end of updated conflict set.\n", tid);
1585   }
1586
1587   tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid)));
1588}
1589
1590/** Report the number of context switches performed. */
1591ULong DRD_(thread_get_context_switch_count)(void)
1592{
1593   return s_context_switch_count;
1594}
1595
1596/** Report the number of ordered segments that have been discarded. */
1597ULong DRD_(thread_get_discard_ordered_segments_count)(void)
1598{
1599   return s_discard_ordered_segments_count;
1600}
1601
1602/** Return how many times the conflict set has been updated entirely. */
1603ULong DRD_(thread_get_compute_conflict_set_count)()
1604{
1605   return s_compute_conflict_set_count;
1606}
1607
1608/** Return how many times the conflict set has been updated partially. */
1609ULong DRD_(thread_get_update_conflict_set_count)(void)
1610{
1611   return s_update_conflict_set_count;
1612}
1613
1614/**
1615 * Return how many times the conflict set has been updated partially
1616 * because a new segment has been created.
1617 */
1618ULong DRD_(thread_get_update_conflict_set_new_sg_count)(void)
1619{
1620   return s_update_conflict_set_new_sg_count;
1621}
1622
1623/**
1624 * Return how many times the conflict set has been updated partially
1625 * because of combining vector clocks due to synchronization operations
1626 * other than reader/writer lock or barrier operations.
1627 */
1628ULong DRD_(thread_get_update_conflict_set_sync_count)(void)
1629{
1630   return s_update_conflict_set_sync_count;
1631}
1632
1633/**
1634 * Return how many times the conflict set has been updated partially
1635 * because of thread joins.
1636 */
1637ULong DRD_(thread_get_update_conflict_set_join_count)(void)
1638{
1639   return s_update_conflict_set_join_count;
1640}
1641
1642/**
1643 * Return the number of first-level bitmaps that have been created during
1644 * conflict set updates.
1645 */
1646ULong DRD_(thread_get_conflict_set_bitmap_creation_count)(void)
1647{
1648   return s_conflict_set_bitmap_creation_count;
1649}
1650
1651/**
1652 * Return the number of second-level bitmaps that have been created during
1653 * conflict set updates.
1654 */
1655ULong DRD_(thread_get_conflict_set_bitmap2_creation_count)(void)
1656{
1657   return s_conflict_set_bitmap2_creation_count;
1658}
1659