blob: dc983a5fb47718bd58bc738e471af2ca4cc0a713 [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
57/* Thr, libhb's private thread record, exported abstractly */
58typedef 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. */
76typedef
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. */
106typedef
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
114typedef
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
155Bool HG_(is_sane_Thread) ( Thread* thr );
156Bool HG_(is_sane_LockP) ( Lock* lock );
157Bool HG_(is_sane_LockN) ( Lock* lock );
158Bool 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/*--------------------------------------------------------------------*/