2 /*--------------------------------------------------------------------*/
3 /*--- Definitions for Locks and Threads. ---*/
4 /*--- hg_lock_n_thread.h ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Helgrind, a Valgrind tool for detecting errors
11 Copyright (C) 2007-2017 OpenWorks Ltd
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.
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.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #ifndef __HG_LOCK_N_THREAD_H
31 #define __HG_LOCK_N_THREAD_H
34 /*----------------------------------------------------------------*/
35 /*--- Primary data definitions ---*/
36 /*----------------------------------------------------------------*/
38 /* Magic numbers, for doing assertions that structures really are of
39 the right type. Useful as some of the code can get a bit
41 #define Thread_MAGIC 0x504fc5e5
42 #define LockN_MAGIC 0x6545b557 /* normal nonpersistent locks */
43 #define LockP_MAGIC 0x755b5456 /* persistent (copied) locks */
46 /* These are handles for Word sets. CONSTRAINTS: must be small ints
47 numbered from zero, since 32-bit versions of them are used to
48 encode lock-sets in libhb's history records (Thr_n_RCEC). */
49 typedef WordSet WordSetID
;
52 /* Synchronisation Objects, exported abstractly by libhb. */
53 typedef struct _SO SO
;
55 /* Thr, libhb's private thread record, exported abstractly. Thr's are
56 allocated and never deallocated (simply leaked). Also ThrID, which
57 is a small integer which uniquely identifies a Thr and which is
58 used in ScalarTS because it is smaller than a Thr*. There is a 1-1
59 mapping between Thr's and ThrIDs. */
60 typedef struct _Thr Thr
;
64 /* Stores information about a thread. Addresses of these also serve
65 as unique thread identifiers and so are never freed, so they should
66 be as small as possible. Freeing Thread structures makes the
67 storage management just too complex, and most programs don't create
68 many threads, so tolerating this leak seems like a not-bad
71 Since these are never freed, the .coretid field only indicates the
72 core's ThreadId associated with this Thread whilst it is alive.
73 Once the thread finishes, the ThreadId is set to
76 The core may later re-use the same ThreadId for what is a logically
77 completely different thread, which of course must have a different
82 struct _Thread
* admin
;
84 Thr
* hbthr
; /* which in turn points back here .. */
85 ThreadId coretid
; /* .. via its hgthread field */
87 WordSetID locksetA
; /* WordSet of Lock* currently held by thread */
88 WordSetID locksetW
; /* subset of locksetA held in w-mode */
90 /* Place where parent was when this thread was created. */
91 ExeContext
* created_at
;
93 /* != 0 if SP fixup needed for unwind : it contains a delta SP value
94 to use when evh__mem_help_c(read|write)_X is called in the
95 'middle of an instruction' (e.g. in a push)
96 after the SP was changed, but before the push has been completed. */
98 /* Index for generating references in error messages. */
101 /* Nesting level of pthread_create(). New memory allocated is untracked
102 when this value is > 0: race reporting is suppressed there. DRD does
103 the same thing implicitly. This is necessary because for example
104 Solaris libc caches many objects and reuses them for different threads
105 and that confuses Helgrind. With libvki it would be possible to
106 explicitly use VG_USERREQ__HG_CLEAN_MEMORY on such objects.
107 Also mutex activity is ignored so that they do not impose false
108 ordering between creator and created thread. */
109 Int pthread_create_nesting_level
;
111 /* Nesting level of synchronization functions called by the client.
112 Loads and stores are ignored when its value > 0.
113 Currently this is used solely for suppressing races of primitive
114 synchronization objects themselves - mutexes, condition variables,
115 read-write locks and their associated sleep queues.
116 See also documentation for command line option
117 --ignore-thread-creation. */
120 #if defined(VGO_solaris)
121 Int bind_guard_flag
; /* Bind flag from the runtime linker. */
122 #endif /* VGO_solaris */
126 /* Get hg's admin_threads value, so libhb can visit all of them. */
127 Thread
* get_admin_threads ( void );
129 /* Stores information about a lock's current state. These are
130 allocated and later freed (when the containing memory becomes
131 NoAccess). This gives a problem for the XError type, which
132 contains Lock*s. Solution is to copy any Lock which is to be
133 incorporated into an XErrors, so as to make it independent from the
134 'normal' collection of Locks, which can come and go. When the lock
135 is copied, its .magic is changed from LockN_Magic to
141 LK_mbRec
=1001, /* normal mutex, possibly recursive */
142 LK_nonRec
, /* normal mutex, definitely non recursive */
143 LK_rdwr
/* reader-writer lock */
150 struct _Lock
* admin_next
; /* fields for a double linked */
151 struct _Lock
* admin_prev
; /* list of these locks */
152 ULong unique
; /* used for persistence-hashing */
153 UInt magic
; /* LockN_MAGIC or LockP_MAGIC */
155 /* Place where lock first came to the attention of Helgrind. */
156 ExeContext
* appeared_at
;
157 /* If the lock is held, place where the lock most recently made
158 an unlocked->locked transition. Must be sync'd with .heldBy:
159 either both NULL or both non-NULL. */
160 ExeContext
* acquired_at
;
162 SO
* hbso
; /* associated SO */
163 Addr guestaddr
; /* Guest address of lock */
164 LockKind kind
; /* what kind of lock this is */
167 WordBag
* heldBy
; /* bag of threads that hold this lock */
168 /* .heldBy is NULL: lock is unheld, and .heldW is meaningless
169 but arbitrarily set to False
171 .heldW is True: lock is w-held by threads in heldBy
172 .heldW is False: lock is r-held by threads in heldBy
173 Either way, heldBy may not validly be an empty Bag.
175 for LK_nonRec, r-holdings are not allowed, and w-holdings may
176 only have sizeTotal(heldBy) == 1
178 for LK_mbRec, r-holdings are not allowed, and w-holdings may
179 only have sizeUnique(heldBy) == 1
181 for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */
185 #define Lock_INVALID ((Lock*)1UL)
187 /*----------------------------------------------------------------*/
188 /*--- Sanity checking ---*/
189 /*----------------------------------------------------------------*/
191 Bool
HG_(is_sane_Thread
) ( Thread
* thr
);
192 Bool
HG_(is_sane_LockP
) ( Lock
* lock
);
193 Bool
HG_(is_sane_LockN
) ( Lock
* lock
);
194 Bool
HG_(is_sane_LockNorP
) ( Lock
* lock
);
197 #endif /* ! __HG_LOCK_N_THREAD_H */
199 /*--------------------------------------------------------------------*/
200 /*--- end hg_lock_n_thread.h ---*/
201 /*--------------------------------------------------------------------*/