1 2 /*--------------------------------------------------------------------*/ 3 /*--- Definitions for Locks and Threads. ---*/ 4 /*--- hg_lock_n_thread.h ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Helgrind, a Valgrind tool for detecting errors 9 in threaded programs. 10 11 Copyright (C) 2007-2010 OpenWorks Ltd 12 info (at) open-works.co.uk 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 #ifndef __HG_LOCK_N_THREAD_H 33 #define __HG_LOCK_N_THREAD_H 34 35 36 /*----------------------------------------------------------------*/ 37 /*--- Primary data definitions ---*/ 38 /*----------------------------------------------------------------*/ 39 40 /* Magic numbers, for doing assertions that structures really are of 41 the right type. Useful as some of the code can get a bit 42 complex. */ 43 #define Thread_MAGIC 0x504fc5e5 44 #define LockN_MAGIC 0x6545b557 /* normal nonpersistent locks */ 45 #define LockP_MAGIC 0x755b5456 /* persistent (copied) locks */ 46 47 48 /* These are handles for Word sets. CONSTRAINTS: must be (very) small 49 ints numbered from zero, since < 30-bit versions of them are used to 50 encode thread-sets and lock-sets in 32-bit shadow words. */ 51 typedef WordSet WordSetID; 52 53 54 /* Synchronisation Objects, exported abstractly by libhb. */ 55 typedef struct _SO SO; 56 57 /* Thr, libhb's private thread record, exported abstractly */ 58 typedef struct _Thr Thr; 59 60 61 /* Stores information about a thread. Addresses of these also serve 62 as unique thread identifiers and so are never freed, so they should 63 be as small as possible. Freeing Thread structures makes the 64 storage management just too complex, and most programs don't create 65 many threads, so tolerating this leak seems like a not-bad 66 tradeoff. 67 68 Since these are never freed, the .coretid field only indicates the 69 core's ThreadId associated with this Thread whilst it is alive. 70 Once the thread finishes, the ThreadId is set to 71 VG_INVALID_THREADID. 72 73 The core may later re-use the same ThreadId for what is a logically 74 completely different thread, which of course must have a different 75 Thread structure. */ 76 typedef 77 struct _Thread { 78 /* ADMIN */ 79 struct _Thread* admin; 80 UInt magic; 81 Thr* hbthr; 82 ThreadId coretid; 83 /* USEFUL */ 84 WordSetID locksetA; /* WordSet of Lock* currently held by thread */ 85 WordSetID locksetW; /* subset of locksetA held in w-mode */ 86 /* EXPOSITION */ 87 /* Place where parent was when this thread was created. */ 88 ExeContext* created_at; 89 Bool announced; 90 /* Index for generating references in error messages. */ 91 Int errmsg_index; 92 } 93 Thread; 94 95 96 /* Stores information about a lock's current state. These are 97 allocated and later freed (when the containing memory becomes 98 NoAccess). This gives a problem for the XError type, which 99 contains Lock*s. Solution is to copy any Lock which is to be 100 incorporated into an XErrors, so as to make it independent from the 101 'normal' collection of Locks, which can come and go. When the lock 102 is copied, its .magic is changed from LockN_Magic to 103 LockP_Magic. */ 104 105 /* Lock kinds. */ 106 typedef 107 enum { 108 LK_mbRec=1001, /* normal mutex, possibly recursive */ 109 LK_nonRec, /* normal mutex, definitely non recursive */ 110 LK_rdwr /* reader-writer lock */ 111 } 112 LockKind; 113 114 typedef 115 struct _Lock { 116 /* ADMIN */ 117 struct _Lock* admin; 118 ULong unique; /* used for persistence-hashing */ 119 UInt magic; /* LockN_MAGIC or LockP_MAGIC */ 120 /* EXPOSITION */ 121 /* Place where lock first came to the attention of Helgrind. */ 122 ExeContext* appeared_at; 123 /* If the lock is held, place where the lock most recently made 124 an unlocked->locked transition. Must be sync'd with .heldBy: 125 either both NULL or both non-NULL. */ 126 ExeContext* acquired_at; 127 /* USEFUL-STATIC */ 128 SO* hbso; /* associated SO */ 129 Addr guestaddr; /* Guest address of lock */ 130 LockKind kind; /* what kind of lock this is */ 131 /* USEFUL-DYNAMIC */ 132 Bool heldW; 133 WordBag* heldBy; /* bag of threads that hold this lock */ 134 /* .heldBy is NULL: lock is unheld, and .heldW is meaningless 135 but arbitrarily set to False 136 .heldBy is non-NULL: 137 .heldW is True: lock is w-held by threads in heldBy 138 .heldW is False: lock is r-held by threads in heldBy 139 Either way, heldBy may not validly be an empty Bag. 140 141 for LK_nonRec, r-holdings are not allowed, and w-holdings may 142 only have sizeTotal(heldBy) == 1 143 144 for LK_mbRec, r-holdings are not allowed, and w-holdings may 145 only have sizeUnique(heldBy) == 1 146 147 for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */ 148 } 149 Lock; 150 151 /*----------------------------------------------------------------*/ 152 /*--- Sanity checking ---*/ 153 /*----------------------------------------------------------------*/ 154 155 Bool HG_(is_sane_Thread) ( Thread* thr ); 156 Bool HG_(is_sane_LockP) ( Lock* lock ); 157 Bool HG_(is_sane_LockN) ( Lock* lock ); 158 Bool HG_(is_sane_LockNorP) ( Lock* lock ); 159 160 161 #endif /* ! __HG_LOCK_N_THREAD_H */ 162 163 /*--------------------------------------------------------------------*/ 164 /*--- end hg_lock_n_thread.h ---*/ 165 /*--------------------------------------------------------------------*/ 166