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, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_tool_basics.h"
33 #include "pub_tool_libcbase.h"
34 #include "pub_tool_libcassert.h"
35 #include "pub_tool_execontext.h"
36 #include "pub_tool_threadstate.h"
37 #include "pub_tool_wordfm.h"
39 #include "hg_basics.h"
40 #include "hg_wordset.h"
41 #include "hg_lock_n_thread.h" /* self */
44 /*----------------------------------------------------------------*/
45 /*--- Sanity checking ---*/
46 /*----------------------------------------------------------------*/
48 inline Bool
HG_(is_sane_Thread
) ( Thread
* thr
) {
49 return thr
!= NULL
&& thr
->magic
== Thread_MAGIC
;
52 static Bool
is_sane_Bag_of_Threads ( WordBag
* bag
)
56 VG_(initIterBag
)( bag
);
57 while (VG_(nextIterBag
)( bag
, (UWord
*)&thr
, &count
)) {
58 if (count
< 1) return False
;
59 if (!HG_(is_sane_Thread
)(thr
)) return False
;
61 VG_(doneIterBag
)( bag
);
65 static Bool
is_sane_Lock_BASE ( Lock
* lock
)
68 || (lock
->magic
!= LockN_MAGIC
&& lock
->magic
!= LockP_MAGIC
))
71 case LK_mbRec
: case LK_nonRec
: case LK_rdwr
: break;
72 default: return False
;
74 if (lock
->heldBy
== NULL
) {
75 if (lock
->acquired_at
!= NULL
) return False
;
76 /* Unheld. We arbitrarily require heldW to be False. */
79 if (lock
->acquired_at
== NULL
) return False
;
82 /* If heldBy is non-NULL, we require it to contain at least one
84 if (VG_(isEmptyBag
)(lock
->heldBy
))
87 /* Lock is either r- or w-held. */
88 if (!is_sane_Bag_of_Threads(lock
->heldBy
))
91 /* Held in write-mode */
92 if ((lock
->kind
== LK_nonRec
|| lock
->kind
== LK_rdwr
)
93 && !VG_(isSingletonTotalBag
)(lock
->heldBy
))
96 /* Held in read-mode */
97 if (lock
->kind
!= LK_rdwr
) return False
;
102 Bool
HG_(is_sane_LockP
) ( Lock
* lock
) {
104 && lock
->magic
== LockP_MAGIC
105 && lock
->hbso
== NULL
106 && is_sane_Lock_BASE(lock
);
109 Bool
HG_(is_sane_LockN
) ( Lock
* lock
) {
111 && lock
->magic
== LockN_MAGIC
112 && lock
->hbso
!= NULL
113 && is_sane_Lock_BASE(lock
);
116 Bool
HG_(is_sane_LockNorP
) ( Lock
* lock
) {
117 return is_sane_Lock_BASE(lock
);
121 /*--------------------------------------------------------------------*/
122 /*--- end hg_lock_n_thread.c ---*/
123 /*--------------------------------------------------------------------*/