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