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 __DRD_CLIENTOBJ_H 27 #define __DRD_CLIENTOBJ_H 28 29 30 #include "drd_basics.h" /* DrdThreadId */ 31 #include "drd_clientreq.h" /* MutexT */ 32 #include "pub_tool_basics.h" 33 #include "pub_tool_execontext.h" /* ExeContext */ 34 #include "pub_tool_oset.h" 35 #include "pub_tool_xarray.h" 36 37 38 /* Forward declarations. */ 39 40 union drd_clientobj; 41 42 43 /* Type definitions. */ 44 45 typedef enum { 46 ClientMutex = 1, 47 ClientCondvar = 2, 48 ClientHbvar = 3, 49 ClientSemaphore = 4, 50 ClientBarrier = 5, 51 ClientRwlock = 6, 52 } ObjType; 53 54 struct any 55 { 56 Addr a1; 57 ObjType type; 58 void (*cleanup)(union drd_clientobj*); 59 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 60 ExeContext* first_observed_at; 61 }; 62 63 struct mutex_info 64 { 65 Addr a1; 66 ObjType type; 67 void (*cleanup)(union drd_clientobj*); 68 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 69 ExeContext* first_observed_at; 70 MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t. 71 int recursion_count; // 0 if free, >= 1 if locked. 72 DrdThreadId owner; // owner if locked, last owner if free. 73 struct segment* last_locked_segment; 74 ULong acquiry_time_ms; 75 ExeContext* acquired_at; 76 }; 77 78 struct cond_info 79 { 80 Addr a1; 81 ObjType type; 82 void (*cleanup)(union drd_clientobj*); 83 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 84 ExeContext* first_observed_at; 85 int waiter_count; 86 Addr mutex; // Client mutex specified in pthread_cond_wait() call, and 87 // null if no client threads are currently waiting on this cond.var. 88 }; 89 90 struct hb_info 91 { 92 Addr a1; 93 ObjType type; 94 void (*cleanup)(union drd_clientobj*); 95 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 96 ExeContext* first_observed_at; 97 OSet* oset; // Per-thread order annotation information. 98 }; 99 100 struct semaphore_info 101 { 102 Addr a1; 103 ObjType type; 104 void (*cleanup)(union drd_clientobj*); 105 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 106 ExeContext* first_observed_at; 107 UInt waits_to_skip; // Number of sem_wait() calls to skip 108 // (due to the value assigned by sem_init()). 109 UInt value; // Semaphore value. 110 UWord waiters; // Number of threads inside sem_wait(). 111 DrdThreadId last_sem_post_tid; // Thread ID associated with last sem_post(). 112 XArray* last_sem_post_seg; // array of Segment*, used as a stack. 113 }; 114 115 struct barrier_info 116 { 117 Addr a1; 118 ObjType type; 119 void (*cleanup)(union drd_clientobj*); 120 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 121 ExeContext* first_observed_at; 122 BarrierT barrier_type; // pthread_barrier or gomp_barrier. 123 Word count; // Participant count in a barrier wait. 124 Word pre_iteration; // pre barrier completion count modulo two. 125 Word post_iteration; // post barrier completion count modulo two. 126 Word pre_waiters_left; // number of waiters left for a complete barrier. 127 Word post_waiters_left; // number of waiters left for a complete barrier. 128 OSet* oset; // Per-thread barrier information. 129 }; 130 131 struct rwlock_info 132 { 133 Addr a1; 134 ObjType type; 135 void (*cleanup)(union drd_clientobj*); 136 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 137 ExeContext* first_observed_at; 138 RwLockT rwlock_type; 139 OSet* thread_info; 140 ULong acquiry_time_ms; 141 ExeContext* acquired_at; 142 }; 143 144 typedef union drd_clientobj 145 { 146 struct any any; 147 struct mutex_info mutex; 148 struct cond_info cond; 149 struct hb_info hb; 150 struct semaphore_info semaphore; 151 struct barrier_info barrier; 152 struct rwlock_info rwlock; 153 } DrdClientobj; 154 155 156 /* Function declarations. */ 157 158 void DRD_(clientobj_set_trace)(const Bool trace); 159 void DRD_(clientobj_init)(void); 160 void DRD_(clientobj_cleanup)(void); 161 DrdClientobj* DRD_(clientobj_get_any)(const Addr addr); 162 DrdClientobj* DRD_(clientobj_get)(const Addr addr, const ObjType t); 163 Bool DRD_(clientobj_present)(const Addr a1, const Addr a2); 164 DrdClientobj* DRD_(clientobj_add)(const Addr a1, const ObjType t); 165 Bool DRD_(clientobj_remove)(const Addr addr, const ObjType t); 166 void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2); 167 void DRD_(clientobj_delete_thread)(const DrdThreadId tid); 168 const char* DRD_(clientobj_type_name)(const ObjType t); 169 170 171 #endif /* __DRD_CLIENTOBJ_H */ 172