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-2011 OpenWorks Ltd 12 info@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 small ints 49 numbered from zero, since 32-bit versions of them are used to 50 encode lock-sets in libhb's history records (Thr_n_RCEC). */ 51typedef WordSet WordSetID; 52 53 54/* Synchronisation Objects, exported abstractly by libhb. */ 55typedef struct _SO SO; 56 57/* Thr, libhb's private thread record, exported abstractly. Thr's are 58 allocated and never deallocated (simply leaked). Also ThrID, which 59 is a small integer which uniquely identifies a Thr and which is 60 used in ScalarTS because it is smaller than a Thr*. There is a 1-1 61 mapping between Thr's and ThrIDs. */ 62typedef struct _Thr Thr; 63typedef UInt ThrID; 64 65 66/* Stores information about a thread. Addresses of these also serve 67 as unique thread identifiers and so are never freed, so they should 68 be as small as possible. Freeing Thread structures makes the 69 storage management just too complex, and most programs don't create 70 many threads, so tolerating this leak seems like a not-bad 71 tradeoff. 72 73 Since these are never freed, the .coretid field only indicates the 74 core's ThreadId associated with this Thread whilst it is alive. 75 Once the thread finishes, the ThreadId is set to 76 VG_INVALID_THREADID. 77 78 The core may later re-use the same ThreadId for what is a logically 79 completely different thread, which of course must have a different 80 Thread structure. */ 81typedef 82 struct _Thread { 83 /* ADMIN */ 84 struct _Thread* admin; 85 UInt magic; 86 Thr* hbthr; /* which in turn points back here .. */ 87 ThreadId coretid; /* .. via its hgthread field */ 88 /* USEFUL */ 89 WordSetID locksetA; /* WordSet of Lock* currently held by thread */ 90 WordSetID locksetW; /* subset of locksetA held in w-mode */ 91 /* EXPOSITION */ 92 /* Place where parent was when this thread was created. */ 93 ExeContext* created_at; 94 Bool announced; 95 /* Index for generating references in error messages. */ 96 Int errmsg_index; 97 } 98 Thread; 99 100/* Get hg's admin_threads value, so libhb can visit all of them. */ 101Thread* get_admin_threads ( void ); 102 103/* Stores information about a lock's current state. These are 104 allocated and later freed (when the containing memory becomes 105 NoAccess). This gives a problem for the XError type, which 106 contains Lock*s. Solution is to copy any Lock which is to be 107 incorporated into an XErrors, so as to make it independent from the 108 'normal' collection of Locks, which can come and go. When the lock 109 is copied, its .magic is changed from LockN_Magic to 110 LockP_Magic. */ 111 112/* Lock kinds. */ 113typedef 114 enum { 115 LK_mbRec=1001, /* normal mutex, possibly recursive */ 116 LK_nonRec, /* normal mutex, definitely non recursive */ 117 LK_rdwr /* reader-writer lock */ 118 } 119 LockKind; 120 121typedef 122 struct _Lock { 123 /* ADMIN */ 124 struct _Lock* admin_next; /* fields for a double linked */ 125 struct _Lock* admin_prev; /* list of these locks */ 126 ULong unique; /* used for persistence-hashing */ 127 UInt magic; /* LockN_MAGIC or LockP_MAGIC */ 128 /* EXPOSITION */ 129 /* Place where lock first came to the attention of Helgrind. */ 130 ExeContext* appeared_at; 131 /* If the lock is held, place where the lock most recently made 132 an unlocked->locked transition. Must be sync'd with .heldBy: 133 either both NULL or both non-NULL. */ 134 ExeContext* acquired_at; 135 /* USEFUL-STATIC */ 136 SO* hbso; /* associated SO */ 137 Addr guestaddr; /* Guest address of lock */ 138 LockKind kind; /* what kind of lock this is */ 139 /* USEFUL-DYNAMIC */ 140 Bool heldW; 141 WordBag* heldBy; /* bag of threads that hold this lock */ 142 /* .heldBy is NULL: lock is unheld, and .heldW is meaningless 143 but arbitrarily set to False 144 .heldBy is non-NULL: 145 .heldW is True: lock is w-held by threads in heldBy 146 .heldW is False: lock is r-held by threads in heldBy 147 Either way, heldBy may not validly be an empty Bag. 148 149 for LK_nonRec, r-holdings are not allowed, and w-holdings may 150 only have sizeTotal(heldBy) == 1 151 152 for LK_mbRec, r-holdings are not allowed, and w-holdings may 153 only have sizeUnique(heldBy) == 1 154 155 for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */ 156 } 157 Lock; 158 159#define Lock_INVALID ((Lock*)1UL) 160 161/*----------------------------------------------------------------*/ 162/*--- Sanity checking ---*/ 163/*----------------------------------------------------------------*/ 164 165Bool HG_(is_sane_Thread) ( Thread* thr ); 166Bool HG_(is_sane_LockP) ( Lock* lock ); 167Bool HG_(is_sane_LockN) ( Lock* lock ); 168Bool HG_(is_sane_LockNorP) ( Lock* lock ); 169 170 171#endif /* ! __HG_LOCK_N_THREAD_H */ 172 173/*--------------------------------------------------------------------*/ 174/*--- end hg_lock_n_thread.h ---*/ 175/*--------------------------------------------------------------------*/ 176