blob: 78948fe11206989bfddabbe0808d1e5d01ae1498 [file] [log] [blame]
sewardjf98e1c02008-10-25 16:22:41 +00001
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
sewardj9eecbbb2010-05-03 21:37:12 +000011 Copyright (C) 2007-2010 OpenWorks Ltd
sewardjf98e1c02008-10-25 16:22:41 +000012 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 (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. */
51typedef WordSet WordSetID;
52
53
54/* Synchronisation Objects, exported abstractly by libhb. */
55typedef struct _SO SO;
56
sewardje4cce742011-02-24 15:25:24 +000057/* 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. */
sewardjf98e1c02008-10-25 16:22:41 +000062typedef struct _Thr Thr;
sewardje4cce742011-02-24 15:25:24 +000063typedef UInt ThrID;
sewardjf98e1c02008-10-25 16:22:41 +000064
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;
87 ThreadId coretid;
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
101/* Stores information about a lock's current state. These are
102 allocated and later freed (when the containing memory becomes
103 NoAccess). This gives a problem for the XError type, which
104 contains Lock*s. Solution is to copy any Lock which is to be
105 incorporated into an XErrors, so as to make it independent from the
106 'normal' collection of Locks, which can come and go. When the lock
107 is copied, its .magic is changed from LockN_Magic to
108 LockP_Magic. */
109
110/* Lock kinds. */
111typedef
112 enum {
113 LK_mbRec=1001, /* normal mutex, possibly recursive */
114 LK_nonRec, /* normal mutex, definitely non recursive */
115 LK_rdwr /* reader-writer lock */
116 }
117 LockKind;
118
119typedef
120 struct _Lock {
121 /* ADMIN */
sewardj1d7c3322011-02-28 09:22:51 +0000122 struct _Lock* admin_next; /* fields for a double linked */
123 struct _Lock* admin_prev; /* list of these locks */
sewardjf98e1c02008-10-25 16:22:41 +0000124 ULong unique; /* used for persistence-hashing */
125 UInt magic; /* LockN_MAGIC or LockP_MAGIC */
126 /* EXPOSITION */
127 /* Place where lock first came to the attention of Helgrind. */
128 ExeContext* appeared_at;
129 /* If the lock is held, place where the lock most recently made
130 an unlocked->locked transition. Must be sync'd with .heldBy:
131 either both NULL or both non-NULL. */
132 ExeContext* acquired_at;
133 /* USEFUL-STATIC */
134 SO* hbso; /* associated SO */
135 Addr guestaddr; /* Guest address of lock */
136 LockKind kind; /* what kind of lock this is */
137 /* USEFUL-DYNAMIC */
138 Bool heldW;
139 WordBag* heldBy; /* bag of threads that hold this lock */
140 /* .heldBy is NULL: lock is unheld, and .heldW is meaningless
141 but arbitrarily set to False
142 .heldBy is non-NULL:
143 .heldW is True: lock is w-held by threads in heldBy
144 .heldW is False: lock is r-held by threads in heldBy
145 Either way, heldBy may not validly be an empty Bag.
146
147 for LK_nonRec, r-holdings are not allowed, and w-holdings may
148 only have sizeTotal(heldBy) == 1
149
150 for LK_mbRec, r-holdings are not allowed, and w-holdings may
151 only have sizeUnique(heldBy) == 1
152
153 for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */
154 }
155 Lock;
156
157/*----------------------------------------------------------------*/
158/*--- Sanity checking ---*/
159/*----------------------------------------------------------------*/
160
161Bool HG_(is_sane_Thread) ( Thread* thr );
162Bool HG_(is_sane_LockP) ( Lock* lock );
163Bool HG_(is_sane_LockN) ( Lock* lock );
164Bool HG_(is_sane_LockNorP) ( Lock* lock );
165
166
167#endif /* ! __HG_LOCK_N_THREAD_H */
168
169/*--------------------------------------------------------------------*/
170/*--- end hg_lock_n_thread.h ---*/
171/*--------------------------------------------------------------------*/