blob: 919ca92abfb53d963b497a9c2afa1b3b537d99f9 [file] [log] [blame]
sewardjaf44c822007-11-25 14:01:38 +00001/*
bart86562bd2009-02-16 19:43:56 +00002 This file is part of drd, a thread error detector.
sewardjaf44c822007-11-25 14:01:38 +00003
bart86562bd2009-02-16 19:43:56 +00004 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
sewardjaf44c822007-11-25 14:01:38 +00005
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#ifndef __THREAD_H
26#define __THREAD_H
27
28
bart324a23b2009-02-15 12:14:52 +000029/* Include directives. */
sewardjaf44c822007-11-25 14:01:38 +000030
bart09dc13f2009-02-14 15:13:31 +000031#include "drd_basics.h"
bartf00a85b2008-03-13 18:49:23 +000032#include "drd_segment.h"
bartd59bb0f2008-06-08 08:08:31 +000033#include "pub_drd_bitmap.h"
bart86a87df2009-03-04 19:26:47 +000034#include "pub_tool_libcassert.h" /* tl_assert() */
35#include "pub_tool_stacktrace.h" /* typedef StackTrace */
36#include "pub_tool_threadstate.h" /* VG_N_THREADS */
bartf00a85b2008-03-13 18:49:23 +000037
38
bart324a23b2009-02-15 12:14:52 +000039/* Defines. */
bartf00a85b2008-03-13 18:49:23 +000040
bart86a87df2009-03-04 19:26:47 +000041/** Maximum number of threads DRD keeps information about. */
bartf00a85b2008-03-13 18:49:23 +000042#define DRD_N_THREADS VG_N_THREADS
sewardjaf44c822007-11-25 14:01:38 +000043
bart86a87df2009-03-04 19:26:47 +000044/** A number different from any valid DRD thread ID. */
sewardjaf44c822007-11-25 14:01:38 +000045#define DRD_INVALID_THREADID 0
46
bart86a87df2009-03-04 19:26:47 +000047/**
48 * A number different from any valid POSIX thread ID.
49 *
50 * @note The PThreadId typedef and the INVALID_POSIX_THREADID depend on the
51 * operating system and threading library in use. PThreadId must contain at
52 * least as many bits as pthread_t, and INVALID_POSIX_THREADID
53 * must be a value that will never be returned by pthread_self().
54 */
sewardjaf44c822007-11-25 14:01:38 +000055#define INVALID_POSIX_THREADID ((PThreadId)0)
56
57
bart324a23b2009-02-15 12:14:52 +000058/* Type definitions. */
bartf00a85b2008-03-13 18:49:23 +000059
bart86a87df2009-03-04 19:26:47 +000060/**
61 * POSIX thread ID. The type PThreadId must be at least as wide as
62 * pthread_t.
63 */
sewardjaf44c822007-11-25 14:01:38 +000064typedef UWord PThreadId;
65
bart86a87df2009-03-04 19:26:47 +000066/** Per-thread information managed by DRD. */
bartf00a85b2008-03-13 18:49:23 +000067typedef struct
68{
bart86a87df2009-03-04 19:26:47 +000069 Segment* first; /**< Pointer to first segment. */
70 Segment* last; /**< Pointer to last segment. */
71 ThreadId vg_threadid; /**< Valgrind thread ID. */
72 PThreadId pt_threadid; /**< POSIX thread ID. */
bart324a23b2009-02-15 12:14:52 +000073 Addr stack_min_min; /**< Lowest value stack pointer ever had. */
74 Addr stack_min; /**< Current stack pointer. */
75 Addr stack_startup; /**<Stack pointer after pthread_create() finished.*/
76 Addr stack_max; /**< Top of stack. */
77 SizeT stack_size; /**< Maximum size of stack. */
78 /** Indicates whether the Valgrind core knows about this thread. */
bart1a473c72008-03-13 19:03:38 +000079 Bool vg_thread_exists;
bart324a23b2009-02-15 12:14:52 +000080 /** Indicates whether there is an associated POSIX thread ID. */
bart1a473c72008-03-13 19:03:38 +000081 Bool posix_thread_exists;
bart324a23b2009-02-15 12:14:52 +000082 /**
83 * If true, indicates that there is a corresponding POSIX thread ID and
84 * a corresponding OS thread that is detached.
85 */
bart1a473c72008-03-13 19:03:38 +000086 Bool detached_posix_thread;
bart324a23b2009-02-15 12:14:52 +000087 /** Wether recording of memory accesses is active. */
bart1a473c72008-03-13 19:03:38 +000088 Bool is_recording;
bart324a23b2009-02-15 12:14:52 +000089 /** Nesting level of synchronization functions called by the client. */
bart1a473c72008-03-13 19:03:38 +000090 Int synchr_nesting;
bartf00a85b2008-03-13 18:49:23 +000091} ThreadInfo;
92
93
bart324a23b2009-02-15 12:14:52 +000094/*
95 * Local variables of drd_thread.c that are declared here such that these
96 * can be accessed by inline functions.
97 */
bartf00a85b2008-03-13 18:49:23 +000098
bart86a87df2009-03-04 19:26:47 +000099/**
100 * DRD thread ID of the currently running thread. It is crucial for correct
101 * operation of DRD that this number is always in sync with
102 * VG_(get_running_tid)().
103 */
bart324a23b2009-02-15 12:14:52 +0000104extern DrdThreadId DRD_(g_drd_running_tid);
bart86a87df2009-03-04 19:26:47 +0000105/** Per-thread information managed by DRD. */
bart324a23b2009-02-15 12:14:52 +0000106extern ThreadInfo DRD_(g_threadinfo)[DRD_N_THREADS];
bart86a87df2009-03-04 19:26:47 +0000107/** Conflict set for the currently running thread. */
bart324a23b2009-02-15 12:14:52 +0000108extern struct bitmap* DRD_(g_conflict_set);
bartf00a85b2008-03-13 18:49:23 +0000109
110
bart324a23b2009-02-15 12:14:52 +0000111/* Function declarations. */
sewardjaf44c822007-11-25 14:01:38 +0000112
bart62a784c2009-02-15 13:11:14 +0000113void DRD_(thread_trace_context_switches)(const Bool t);
114void DRD_(thread_trace_conflict_set)(const Bool t);
bart09dc13f2009-02-14 15:13:31 +0000115Bool DRD_(thread_get_trace_fork_join)(void);
116void DRD_(thread_set_trace_fork_join)(const Bool t);
bart62a784c2009-02-15 13:11:14 +0000117void DRD_(thread_set_segment_merging)(const Bool m);
sewardjaf44c822007-11-25 14:01:38 +0000118
bart62a784c2009-02-15 13:11:14 +0000119DrdThreadId DRD_(VgThreadIdToDrdThreadId)(const ThreadId tid);
120DrdThreadId DRD_(NewVgThreadIdToDrdThreadId)(const ThreadId tid);
121DrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid);
122ThreadId DRD_(DrdThreadIdToVgThreadId)(const DrdThreadId tid);
123DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator,
sewardjaf44c822007-11-25 14:01:38 +0000124 const ThreadId vg_created);
bart62a784c2009-02-15 13:11:14 +0000125DrdThreadId DRD_(thread_post_create)(const ThreadId vg_created);
bart09dc13f2009-02-14 15:13:31 +0000126void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee);
bart62a784c2009-02-15 13:11:14 +0000127void DRD_(thread_delete)(const DrdThreadId tid);
128void DRD_(thread_finished)(const DrdThreadId tid);
129void DRD_(thread_pre_cancel)(const DrdThreadId tid);
130void DRD_(thread_set_stack_startup)(const DrdThreadId tid, const Addr stack_startup);
131Addr DRD_(thread_get_stack_min)(const DrdThreadId tid);
132Addr DRD_(thread_get_stack_min_min)(const DrdThreadId tid);
133Addr DRD_(thread_get_stack_max)(const DrdThreadId tid);
134SizeT DRD_(thread_get_stack_size)(const DrdThreadId tid);
135void DRD_(thread_set_pthreadid)(const DrdThreadId tid, const PThreadId ptid);
136Bool DRD_(thread_get_joinable)(const DrdThreadId tid);
137void DRD_(thread_set_joinable)(const DrdThreadId tid, const Bool joinable);
138void DRD_(thread_set_vg_running_tid)(const ThreadId vg_tid);
139void DRD_(thread_set_running_tid)(const ThreadId vg_tid,
sewardj8b09d4f2007-12-04 21:27:18 +0000140 const DrdThreadId drd_tid);
bart62a784c2009-02-15 13:11:14 +0000141int DRD_(thread_enter_synchr)(const DrdThreadId tid);
142int DRD_(thread_leave_synchr)(const DrdThreadId tid);
143int DRD_(thread_get_synchr_nesting_count)(const DrdThreadId tid);
144void DRD_(thread_new_segment)(const DrdThreadId tid);
145VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid);
146void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid);
147void DRD_(thread_combine_vc)(const DrdThreadId joiner, const DrdThreadId joinee);
148void DRD_(thread_combine_vc2)(const DrdThreadId tid, const VectorClock* const vc);
bartdfbae6e2008-06-05 08:29:53 +0000149
bart62a784c2009-02-15 13:11:14 +0000150void DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2);
151void DRD_(thread_start_recording)(const DrdThreadId tid);
152void DRD_(thread_stop_recording)(const DrdThreadId tid);
153void DRD_(thread_print_all)(void);
154void DRD_(thread_report_races)(const DrdThreadId tid);
155void DRD_(thread_report_races_segment)(const DrdThreadId tid,
sewardjaf44c822007-11-25 14:01:38 +0000156 const Segment* const p);
bart62a784c2009-02-15 13:11:14 +0000157void DRD_(thread_report_all_races)(void);
158void DRD_(thread_report_conflicting_segments)(const DrdThreadId tid,
sewardjaf44c822007-11-25 14:01:38 +0000159 const Addr addr,
160 const SizeT size,
161 const BmAccessTypeT access_type);
bart62a784c2009-02-15 13:11:14 +0000162ULong DRD_(thread_get_context_switch_count)(void);
163ULong DRD_(thread_get_report_races_count)(void);
164ULong DRD_(thread_get_discard_ordered_segments_count)(void);
165ULong DRD_(thread_get_update_conflict_set_count)(ULong* dsnsc, ULong* dscvc);
166ULong DRD_(thread_get_conflict_set_bitmap_creation_count)(void);
167ULong DRD_(thread_get_conflict_set_bitmap2_creation_count)(void);
sewardjaf44c822007-11-25 14:01:38 +0000168
169
bart324a23b2009-02-15 12:14:52 +0000170/* Inline function definitions. */
171
bart86a87df2009-03-04 19:26:47 +0000172/**
173 * Whether or not the specified DRD thread ID is valid.
174 *
175 * A DRD thread ID is valid if and only if the following conditions are met:
176 * - The ID is a valid index of the DRD_(g_threadinfo)[] array.
177 * - The ID is not equal to DRD_INVALID_THREADID.
178 * - The ID refers either to a thread known by the Valgrind core, a joinable
179 * thread that has not yet been joined or a detached thread.
180 */
bartbf80e122008-06-06 10:18:24 +0000181static __inline__
bart62a784c2009-02-15 13:11:14 +0000182Bool DRD_(IsValidDrdThreadId)(const DrdThreadId tid)
bartbf80e122008-06-06 10:18:24 +0000183{
184 return (0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID
bart324a23b2009-02-15 12:14:52 +0000185 && ! (DRD_(g_threadinfo)[tid].vg_thread_exists == False
186 && DRD_(g_threadinfo)[tid].posix_thread_exists == False
187 && DRD_(g_threadinfo)[tid].detached_posix_thread == False));
bartbf80e122008-06-06 10:18:24 +0000188}
189
bart86a87df2009-03-04 19:26:47 +0000190/** Returns the DRD thread ID of the currently running thread. */
bart08865622008-06-06 14:31:36 +0000191static __inline__
bart62a784c2009-02-15 13:11:14 +0000192DrdThreadId DRD_(thread_get_running_tid)(void)
bart1ea5fff2008-03-16 08:36:23 +0000193{
bart324a23b2009-02-15 12:14:52 +0000194 tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID);
195 return DRD_(g_drd_running_tid);
bart1ea5fff2008-03-16 08:36:23 +0000196}
197
bart86a87df2009-03-04 19:26:47 +0000198/** Returns a pointer to the conflict set for the currently running thread. */
bart08865622008-06-06 14:31:36 +0000199static __inline__
bart62a784c2009-02-15 13:11:14 +0000200struct bitmap* DRD_(thread_get_conflict_set)(void)
bart1a473c72008-03-13 19:03:38 +0000201{
bart324a23b2009-02-15 12:14:52 +0000202 return DRD_(g_conflict_set);
bart1a473c72008-03-13 19:03:38 +0000203}
204
bart86a87df2009-03-04 19:26:47 +0000205/**
206 * Reports whether or not memory access recording is enabled for the
207 * currently running thread.
208 */
bart08865622008-06-06 14:31:36 +0000209static __inline__
bart62a784c2009-02-15 13:11:14 +0000210Bool DRD_(running_thread_is_recording)(void)
bartf00a85b2008-03-13 18:49:23 +0000211{
bart8b4b2ee2008-06-11 13:17:56 +0000212#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart324a23b2009-02-15 12:14:52 +0000213 tl_assert(0 <= (int)DRD_(g_drd_running_tid) && DRD_(g_drd_running_tid) < DRD_N_THREADS
214 && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID);
bart589f9482008-06-09 15:08:22 +0000215#endif
bart324a23b2009-02-15 12:14:52 +0000216 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].synchr_nesting == 0
217 && DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].is_recording);
bart1a473c72008-03-13 19:03:38 +0000218}
219
bart86a87df2009-03-04 19:26:47 +0000220/**
221 * Update the information about the lowest stack address that has ever been
222 * accessed by a thread.
223 */
bart08865622008-06-06 14:31:36 +0000224static __inline__
bart62a784c2009-02-15 13:11:14 +0000225void DRD_(thread_set_stack_min)(const DrdThreadId tid, const Addr stack_min)
bart1ea5fff2008-03-16 08:36:23 +0000226{
bart8b4b2ee2008-06-11 13:17:56 +0000227#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartf0cdc602008-06-11 18:37:59 +0000228 tl_assert(0 <= (int)tid
229 && tid < DRD_N_THREADS
230 && tid != DRD_INVALID_THREADID);
bart1ea5fff2008-03-16 08:36:23 +0000231#endif
bart324a23b2009-02-15 12:14:52 +0000232 DRD_(g_threadinfo)[tid].stack_min = stack_min;
bart8b4b2ee2008-06-11 13:17:56 +0000233#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bartfda64922008-03-29 13:13:33 +0000234 /* This function can be called after the thread has been created but */
235 /* before drd_post_thread_create() has filled in stack_max. */
bart324a23b2009-02-15 12:14:52 +0000236 tl_assert(DRD_(g_threadinfo)[tid].stack_min < DRD_(g_threadinfo)[tid].stack_max
237 || DRD_(g_threadinfo)[tid].stack_max == 0);
bart1ea5fff2008-03-16 08:36:23 +0000238#endif
bart324a23b2009-02-15 12:14:52 +0000239 if (UNLIKELY(stack_min < DRD_(g_threadinfo)[tid].stack_min_min))
barte773de42008-03-29 12:54:01 +0000240 {
bart324a23b2009-02-15 12:14:52 +0000241 DRD_(g_threadinfo)[tid].stack_min_min = stack_min;
bart1ea5fff2008-03-16 08:36:23 +0000242 }
243}
244
bart324a23b2009-02-15 12:14:52 +0000245/**
246 * Return true if and only if the specified address is on the stack of the
247 * currently scheduled thread.
bart08865622008-06-06 14:31:36 +0000248 */
249static __inline__
bart62a784c2009-02-15 13:11:14 +0000250Bool DRD_(thread_address_on_stack)(const Addr a)
bart08865622008-06-06 14:31:36 +0000251{
bart324a23b2009-02-15 12:14:52 +0000252 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_min <= a
253 && a < DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_max);
bart08865622008-06-06 14:31:36 +0000254}
255
bart1a473c72008-03-13 19:03:38 +0000256/** Return a pointer to the latest segment for the specified thread. */
bart08865622008-06-06 14:31:36 +0000257static __inline__
bart62a784c2009-02-15 13:11:14 +0000258Segment* DRD_(thread_get_segment)(const DrdThreadId tid)
bart1a473c72008-03-13 19:03:38 +0000259{
bart8b4b2ee2008-06-11 13:17:56 +0000260#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart74a5f212008-05-11 06:43:07 +0000261 tl_assert(0 <= (int)tid && tid < DRD_N_THREADS
bart1a473c72008-03-13 19:03:38 +0000262 && tid != DRD_INVALID_THREADID);
bart324a23b2009-02-15 12:14:52 +0000263 tl_assert(DRD_(g_threadinfo)[tid].last);
bart589f9482008-06-09 15:08:22 +0000264#endif
bart324a23b2009-02-15 12:14:52 +0000265 return DRD_(g_threadinfo)[tid].last;
bartf00a85b2008-03-13 18:49:23 +0000266}
267
barta79df6e2008-03-14 17:07:51 +0000268/** Return a pointer to the latest segment for the running thread. */
bart08865622008-06-06 14:31:36 +0000269static __inline__
bart62a784c2009-02-15 13:11:14 +0000270Segment* DRD_(running_thread_get_segment)(void)
barta79df6e2008-03-14 17:07:51 +0000271{
bart62a784c2009-02-15 13:11:14 +0000272 return DRD_(thread_get_segment)(DRD_(g_drd_running_tid));
barta79df6e2008-03-14 17:07:51 +0000273}
bartf00a85b2008-03-13 18:49:23 +0000274
bart86a87df2009-03-04 19:26:47 +0000275#endif /* __THREAD_H */