1 /* -*- mode: C; c-basic-offset: 3; -*- */ 2 /* 3 This file is part of drd, a thread error detector. 4 5 Copyright (C) 2006-2010 Bart Van Assche <bvanassche (at) 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 #ifndef __THREAD_H 27 #define __THREAD_H 28 29 30 /* Include directives. */ 31 32 #include "drd_basics.h" 33 #include "drd_segment.h" 34 #include "pub_drd_bitmap.h" 35 #include "pub_tool_libcassert.h" /* tl_assert() */ 36 #include "pub_tool_stacktrace.h" /* typedef StackTrace */ 37 #include "pub_tool_threadstate.h" /* VG_N_THREADS */ 38 39 40 /* Defines. */ 41 42 /** Maximum number of threads DRD keeps information about. */ 43 #define DRD_N_THREADS VG_N_THREADS 44 45 /** A number different from any valid DRD thread ID. */ 46 #define DRD_INVALID_THREADID 0 47 48 /** 49 * A number different from any valid POSIX thread ID. 50 * 51 * @note The PThreadId typedef and the INVALID_POSIX_THREADID depend on the 52 * operating system and threading library in use. PThreadId must contain at 53 * least as many bits as pthread_t, and INVALID_POSIX_THREADID 54 * must be a value that will never be returned by pthread_self(). 55 */ 56 #define INVALID_POSIX_THREADID ((PThreadId)0) 57 58 59 /* Type definitions. */ 60 61 /** 62 * POSIX thread ID. The type PThreadId must be at least as wide as 63 * pthread_t. 64 */ 65 typedef UWord PThreadId; 66 67 /** Per-thread information managed by DRD. */ 68 typedef struct 69 { 70 Segment* first; /**< Pointer to first segment. */ 71 Segment* last; /**< Pointer to last segment. */ 72 ThreadId vg_threadid; /**< Valgrind thread ID. */ 73 PThreadId pt_threadid; /**< POSIX thread ID. */ 74 Addr stack_min_min; /**< Lowest value stack pointer ever had. */ 75 Addr stack_min; /**< Current stack pointer. */ 76 Addr stack_startup; /**<Stack pointer after pthread_create() finished.*/ 77 Addr stack_max; /**< Top of stack. */ 78 SizeT stack_size; /**< Maximum size of stack. */ 79 char name[64]; /**< User-assigned thread name. */ 80 Bool on_alt_stack; 81 /** Indicates whether the Valgrind core knows about this thread. */ 82 Bool vg_thread_exists; 83 /** Indicates whether there is an associated POSIX thread ID. */ 84 Bool posix_thread_exists; 85 /** 86 * If true, indicates that there is a corresponding POSIX thread ID and 87 * a corresponding OS thread that is detached. 88 */ 89 Bool detached_posix_thread; 90 /** Wether recording of memory load accesses is currently enabled. */ 91 Bool is_recording_loads; 92 /** Wether recording of memory load accesses is currently enabled. */ 93 Bool is_recording_stores; 94 /** pthread_create() nesting level. */ 95 Int pthread_create_nesting_level; 96 /** Nesting level of synchronization functions called by the client. */ 97 Int synchr_nesting; 98 } ThreadInfo; 99 100 101 /* 102 * Local variables of drd_thread.c that are declared here such that these 103 * can be accessed by inline functions. 104 */ 105 106 /** 107 * DRD thread ID of the currently running thread. It is crucial for correct 108 * operation of DRD that this number is always in sync with 109 * VG_(get_running_tid)(). 110 */ 111 extern DrdThreadId DRD_(g_drd_running_tid); 112 /** Per-thread information managed by DRD. */ 113 extern ThreadInfo DRD_(g_threadinfo)[DRD_N_THREADS]; 114 /** Conflict set for the currently running thread. */ 115 extern struct bitmap* DRD_(g_conflict_set); 116 117 118 /* Function declarations. */ 119 120 void DRD_(thread_trace_context_switches)(const Bool t); 121 void DRD_(thread_trace_conflict_set)(const Bool t); 122 void DRD_(thread_trace_conflict_set_bm)(const Bool t); 123 Bool DRD_(thread_get_trace_fork_join)(void); 124 void DRD_(thread_set_trace_fork_join)(const Bool t); 125 void DRD_(thread_set_segment_merging)(const Bool m); 126 int DRD_(thread_get_segment_merge_interval)(void); 127 void DRD_(thread_set_segment_merge_interval)(const int i); 128 129 DrdThreadId DRD_(VgThreadIdToDrdThreadId)(const ThreadId tid); 130 DrdThreadId DRD_(NewVgThreadIdToDrdThreadId)(const ThreadId tid); 131 DrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid); 132 ThreadId DRD_(DrdThreadIdToVgThreadId)(const DrdThreadId tid); 133 DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator, 134 const ThreadId vg_created); 135 DrdThreadId DRD_(thread_post_create)(const ThreadId vg_created); 136 void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee); 137 void DRD_(thread_delete)(const DrdThreadId tid, Bool detached); 138 void DRD_(thread_finished)(const DrdThreadId tid); 139 void DRD_(drd_thread_atfork_child)(const DrdThreadId tid); 140 void DRD_(thread_pre_cancel)(const DrdThreadId tid); 141 void DRD_(thread_set_stack_startup)(const DrdThreadId tid, 142 const Addr stack_startup); 143 Addr DRD_(thread_get_stack_min)(const DrdThreadId tid); 144 Addr DRD_(thread_get_stack_min_min)(const DrdThreadId tid); 145 Addr DRD_(thread_get_stack_max)(const DrdThreadId tid); 146 SizeT DRD_(thread_get_stack_size)(const DrdThreadId tid); 147 Bool DRD_(thread_get_on_alt_stack)(const DrdThreadId tid); 148 void DRD_(thread_set_on_alt_stack)(const DrdThreadId tid, 149 const Bool on_alt_stack); 150 Int DRD_(thread_get_threads_on_alt_stack)(void); 151 void DRD_(thread_set_pthreadid)(const DrdThreadId tid, const PThreadId ptid); 152 Bool DRD_(thread_get_joinable)(const DrdThreadId tid); 153 void DRD_(thread_set_joinable)(const DrdThreadId tid, const Bool joinable); 154 void DRD_(thread_entering_pthread_create)(const DrdThreadId tid); 155 void DRD_(thread_left_pthread_create)(const DrdThreadId tid); 156 const char* DRD_(thread_get_name)(const DrdThreadId tid); 157 void DRD_(thread_set_name)(const DrdThreadId tid, const char* const name); 158 void DRD_(thread_set_vg_running_tid)(const ThreadId vg_tid); 159 void DRD_(thread_set_running_tid)(const ThreadId vg_tid, 160 const DrdThreadId drd_tid); 161 int DRD_(thread_enter_synchr)(const DrdThreadId tid); 162 int DRD_(thread_leave_synchr)(const DrdThreadId tid); 163 int DRD_(thread_get_synchr_nesting_count)(const DrdThreadId tid); 164 void DRD_(thread_new_segment)(const DrdThreadId tid); 165 VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid); 166 void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid); 167 void DRD_(thread_combine_vc_join)(const DrdThreadId joiner, 168 const DrdThreadId joinee); 169 void DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid, 170 const Segment* sg); 171 void DRD_(thread_update_conflict_set)(const DrdThreadId tid, 172 const VectorClock* const old_vc); 173 174 void DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2, 175 const Bool dont_clear_access); 176 void DRD_(thread_set_record_loads)(const DrdThreadId tid, const Bool enabled); 177 void DRD_(thread_set_record_stores)(const DrdThreadId tid, const Bool enabled); 178 void DRD_(thread_print_all)(void); 179 void DRD_(thread_report_races)(const DrdThreadId tid); 180 void DRD_(thread_report_races_segment)(const DrdThreadId tid, 181 const Segment* const p); 182 void DRD_(thread_report_all_races)(void); 183 void DRD_(thread_report_conflicting_segments)(const DrdThreadId tid, 184 const Addr addr, 185 const SizeT size, 186 const BmAccessTypeT access_type); 187 ULong DRD_(thread_get_context_switch_count)(void); 188 ULong DRD_(thread_get_report_races_count)(void); 189 ULong DRD_(thread_get_discard_ordered_segments_count)(void); 190 ULong DRD_(thread_get_compute_conflict_set_count)(void); 191 ULong DRD_(thread_get_update_conflict_set_count)(void); 192 ULong DRD_(thread_get_update_conflict_set_new_sg_count)(void); 193 ULong DRD_(thread_get_update_conflict_set_sync_count)(void); 194 ULong DRD_(thread_get_update_conflict_set_join_count)(void); 195 ULong DRD_(thread_get_conflict_set_bitmap_creation_count)(void); 196 ULong DRD_(thread_get_conflict_set_bitmap2_creation_count)(void); 197 198 199 /* Inline function definitions. */ 200 201 /** 202 * Whether or not the specified DRD thread ID is valid. 203 * 204 * A DRD thread ID is valid if and only if the following conditions are met: 205 * - The ID is a valid index of the DRD_(g_threadinfo)[] array. 206 * - The ID is not equal to DRD_INVALID_THREADID. 207 * - The ID refers either to a thread known by the Valgrind core, a joinable 208 * thread that has not yet been joined or a detached thread. 209 */ 210 static __inline__ 211 Bool DRD_(IsValidDrdThreadId)(const DrdThreadId tid) 212 { 213 return (0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID 214 && ! (DRD_(g_threadinfo)[tid].vg_thread_exists == False 215 && DRD_(g_threadinfo)[tid].posix_thread_exists == False 216 && DRD_(g_threadinfo)[tid].detached_posix_thread == False)); 217 } 218 219 /** Returns the DRD thread ID of the currently running thread. */ 220 static __inline__ 221 DrdThreadId DRD_(thread_get_running_tid)(void) 222 { 223 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 224 tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 225 #endif 226 return DRD_(g_drd_running_tid); 227 } 228 229 /** Returns a pointer to the conflict set for the currently running thread. */ 230 static __inline__ 231 struct bitmap* DRD_(thread_get_conflict_set)(void) 232 { 233 return DRD_(g_conflict_set); 234 } 235 236 /** 237 * Reports whether or not the currently running client thread is executing code 238 * inside the pthread_create() function. 239 */ 240 static __inline__ 241 Bool DRD_(running_thread_inside_pthread_create)(void) 242 { 243 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)] 244 .pthread_create_nesting_level > 0); 245 } 246 247 /** 248 * Reports whether or not recording of memory loads is enabled for the 249 * currently running client thread. 250 */ 251 static __inline__ 252 Bool DRD_(running_thread_is_recording_loads)(void) 253 { 254 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 255 tl_assert(0 <= (int)DRD_(g_drd_running_tid) 256 && DRD_(g_drd_running_tid) < DRD_N_THREADS 257 && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 258 #endif 259 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].synchr_nesting == 0 260 && DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].is_recording_loads); 261 } 262 263 /** 264 * Reports whether or not recording memory stores is enabled for the 265 * currently running client thread. 266 */ 267 static __inline__ 268 Bool DRD_(running_thread_is_recording_stores)(void) 269 { 270 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 271 tl_assert(0 <= (int)DRD_(g_drd_running_tid) 272 && DRD_(g_drd_running_tid) < DRD_N_THREADS 273 && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 274 #endif 275 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].synchr_nesting == 0 276 && DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].is_recording_stores); 277 } 278 279 /** 280 * Update the information about the lowest stack address that has ever been 281 * accessed by a thread. 282 */ 283 static __inline__ 284 void DRD_(thread_set_stack_min)(const DrdThreadId tid, const Addr stack_min) 285 { 286 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 287 tl_assert(0 <= (int)tid 288 && tid < DRD_N_THREADS 289 && tid != DRD_INVALID_THREADID); 290 #endif 291 DRD_(g_threadinfo)[tid].stack_min = stack_min; 292 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 293 /* This function can be called after the thread has been created but */ 294 /* before drd_post_thread_create() has filled in stack_max. */ 295 tl_assert(DRD_(g_threadinfo)[tid].stack_min 296 < DRD_(g_threadinfo)[tid].stack_max 297 || DRD_(g_threadinfo)[tid].stack_max == 0); 298 #endif 299 if (UNLIKELY(stack_min < DRD_(g_threadinfo)[tid].stack_min_min)) 300 { 301 DRD_(g_threadinfo)[tid].stack_min_min = stack_min; 302 } 303 } 304 305 /** 306 * Return true if and only if the specified address is on the stack of the 307 * currently scheduled thread. 308 */ 309 static __inline__ 310 Bool DRD_(thread_address_on_stack)(const Addr a) 311 { 312 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_min <= a 313 && a < DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_max); 314 } 315 316 /** 317 * Return true if and only if the specified address is on the stack of any 318 * thread. 319 */ 320 static __inline__ 321 Bool DRD_(thread_address_on_any_stack)(const Addr a) 322 { 323 int i; 324 325 for (i = 1; i < DRD_N_THREADS; i++) 326 { 327 if (DRD_(g_threadinfo)[i].vg_thread_exists 328 && DRD_(g_threadinfo)[i].stack_min <= a 329 && a < DRD_(g_threadinfo)[i].stack_max) 330 { 331 return True; 332 } 333 } 334 return False; 335 } 336 337 /** Return a pointer to the latest segment for the specified thread. */ 338 static __inline__ 339 Segment* DRD_(thread_get_segment)(const DrdThreadId tid) 340 { 341 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 342 tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 343 && tid != DRD_INVALID_THREADID); 344 tl_assert(DRD_(g_threadinfo)[tid].last); 345 #endif 346 return DRD_(g_threadinfo)[tid].last; 347 } 348 349 /** Return a pointer to the latest segment for the running thread. */ 350 static __inline__ 351 Segment* DRD_(running_thread_get_segment)(void) 352 { 353 return DRD_(thread_get_segment)(DRD_(g_drd_running_tid)); 354 } 355 356 #endif /* __THREAD_H */ 357