2 /*--------------------------------------------------------------------*/
3 /*--- Definitions for Locks and Threads. ---*/
4 /*--- hg_lock_n_thread.c ---*/
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 #include "pub_tool_basics.h"
31 #include "pub_tool_libcbase.h"
32 #include "pub_tool_libcassert.h"
33 #include "pub_tool_execontext.h"
34 #include "pub_tool_threadstate.h"
35 #include "pub_tool_wordfm.h"
37 #include "hg_basics.h"
38 #include "hg_wordset.h"
39 #include "hg_lock_n_thread.h" /* self */
42 /*----------------------------------------------------------------*/
43 /*--- Sanity checking ---*/
44 /*----------------------------------------------------------------*/
46 inline Bool
HG_(is_sane_Thread
) ( Thread
* thr
) {
47 return thr
!= NULL
&& thr
->magic
== Thread_MAGIC
;
50 static Bool
is_sane_Bag_of_Threads ( WordBag
* bag
)
54 VG_(initIterBag
)( bag
);
55 while (VG_(nextIterBag
)( bag
, (UWord
*)&thr
, &count
)) {
56 if (count
< 1) return False
;
57 if (!HG_(is_sane_Thread
)(thr
)) return False
;
59 VG_(doneIterBag
)( bag
);
63 static Bool
is_sane_Lock_BASE ( Lock
* lock
)
66 || (lock
->magic
!= LockN_MAGIC
&& lock
->magic
!= LockP_MAGIC
))
69 case LK_mbRec
: case LK_nonRec
: case LK_rdwr
: break;
70 default: return False
;
72 if (lock
->heldBy
== NULL
) {
73 if (lock
->acquired_at
!= NULL
) return False
;
74 /* Unheld. We arbitrarily require heldW to be False. */
77 if (lock
->acquired_at
== NULL
) return False
;
80 /* If heldBy is non-NULL, we require it to contain at least one
82 if (VG_(isEmptyBag
)(lock
->heldBy
))
85 /* Lock is either r- or w-held. */
86 if (!is_sane_Bag_of_Threads(lock
->heldBy
))
89 /* Held in write-mode */
90 if ((lock
->kind
== LK_nonRec
|| lock
->kind
== LK_rdwr
)
91 && !VG_(isSingletonTotalBag
)(lock
->heldBy
))
94 /* Held in read-mode */
95 if (lock
->kind
!= LK_rdwr
) return False
;
100 Bool
HG_(is_sane_LockP
) ( Lock
* lock
) {
102 && lock
->magic
== LockP_MAGIC
103 && lock
->hbso
== NULL
104 && is_sane_Lock_BASE(lock
);
107 Bool
HG_(is_sane_LockN
) ( Lock
* lock
) {
109 && lock
->magic
== LockN_MAGIC
110 && lock
->hbso
!= NULL
111 && is_sane_Lock_BASE(lock
);
114 Bool
HG_(is_sane_LockNorP
) ( Lock
* lock
) {
115 return is_sane_Lock_BASE(lock
);
119 /*--------------------------------------------------------------------*/
120 /*--- end hg_lock_n_thread.c ---*/
121 /*--------------------------------------------------------------------*/