1/* 2 This file is part of drd, a thread error detector. 3 4 Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>. 5 6 This program is free software; you can redistribute it and/or 7 modify it under the terms of the GNU General Public License as 8 published by the Free Software Foundation; either version 2 of the 9 License, or (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307, USA. 20 21 The GNU General Public License is contained in the file COPYING. 22*/ 23 24 25#ifndef __DRD_CLIENTOBJ_H 26#define __DRD_CLIENTOBJ_H 27 28 29#include "drd_basics.h" /* DrdThreadId */ 30#include "drd_clientreq.h" /* MutexT */ 31#include "pub_tool_basics.h" 32#include "pub_tool_execontext.h" /* ExeContext */ 33#include "pub_tool_oset.h" 34#include "pub_tool_xarray.h" 35 36 37/* Forward declarations. */ 38 39union drd_clientobj; 40 41 42/* Type definitions. */ 43 44typedef enum { 45 ClientMutex = 1, 46 ClientCondvar = 2, 47 ClientHbvar = 3, 48 ClientSemaphore = 4, 49 ClientBarrier = 5, 50 ClientRwlock = 6, 51} ObjType; 52 53struct any 54{ 55 Addr a1; 56 ObjType type; 57 void (*cleanup)(union drd_clientobj*); 58 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 59 ExeContext* first_observed_at; 60}; 61 62struct mutex_info 63{ 64 Addr a1; 65 ObjType type; 66 void (*cleanup)(union drd_clientobj*); 67 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 68 ExeContext* first_observed_at; 69 MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t. 70 int recursion_count; // 0 if free, >= 1 if locked. 71 DrdThreadId owner; // owner if locked, last owner if free. 72 struct segment* last_locked_segment; 73 ULong acquiry_time_ms; 74 ExeContext* acquired_at; 75}; 76 77struct cond_info 78{ 79 Addr a1; 80 ObjType type; 81 void (*cleanup)(union drd_clientobj*); 82 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 83 ExeContext* first_observed_at; 84 int waiter_count; 85 Addr mutex; // Client mutex specified in pthread_cond_wait() call, and 86 // null if no client threads are currently waiting on this cond.var. 87}; 88 89struct hb_info 90{ 91 Addr a1; 92 ObjType type; 93 void (*cleanup)(union drd_clientobj*); 94 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 95 ExeContext* first_observed_at; 96 OSet* oset; // Per-thread order annotation information. 97}; 98 99struct semaphore_info 100{ 101 Addr a1; 102 ObjType type; 103 void (*cleanup)(union drd_clientobj*); 104 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 105 ExeContext* first_observed_at; 106 UInt waits_to_skip; // Number of sem_wait() calls to skip 107 // (due to the value assigned by sem_init()). 108 UInt value; // Semaphore value. 109 UWord waiters; // Number of threads inside sem_wait(). 110 DrdThreadId last_sem_post_tid; // Thread ID associated with last sem_post(). 111 XArray* last_sem_post_seg; // array of Segment*, used as a stack. 112}; 113 114struct barrier_info 115{ 116 Addr a1; 117 ObjType type; 118 void (*cleanup)(union drd_clientobj*); 119 void (*delete_thread)(union drd_clientobj*, DrdThreadId); 120 ExeContext* first_observed_at; 121 BarrierT barrier_type; // pthread_barrier or gomp_barrier. 122 Word count; // Participant count in a barrier wait. 123 Word pre_iteration; // pre barrier completion count modulo two. 124 Word post_iteration; // post barrier completion count modulo two. 125 Word pre_waiters_left; // number of waiters left for a complete barrier. 126 Word post_waiters_left; // number of waiters left for a complete barrier. 127 OSet* oset[2]; // Per-thread barrier information for the latest 128 // two barrier iterations. 129}; 130 131struct 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 144typedef 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 158void DRD_(clientobj_set_trace)(const Bool trace); 159void DRD_(clientobj_init)(void); 160void DRD_(clientobj_cleanup)(void); 161DrdClientobj* DRD_(clientobj_get_any)(const Addr addr); 162DrdClientobj* DRD_(clientobj_get)(const Addr addr, const ObjType t); 163Bool DRD_(clientobj_present)(const Addr a1, const Addr a2); 164DrdClientobj* DRD_(clientobj_add)(const Addr a1, const ObjType t); 165Bool DRD_(clientobj_remove)(const Addr addr, const ObjType t); 166void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2); 167void DRD_(clientobj_delete_thread)(const DrdThreadId tid); 168const HChar* DRD_(clientobj_type_name)(const ObjType t); 169 170 171#endif /* __DRD_CLIENTOBJ_H */ 172