1 2 /*--------------------------------------------------------------------*/ 3 /*--- Definitions for Locks and Threads. ---*/ 4 /*--- hg_lock_n_thread.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Helgrind, a Valgrind tool for detecting errors 9 in threaded programs. 10 11 Copyright (C) 2007-2012 OpenWorks Ltd 12 info (at) 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 #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" 38 39 #include "hg_basics.h" 40 #include "hg_wordset.h" 41 #include "hg_lock_n_thread.h" /* self */ 42 43 44 /*----------------------------------------------------------------*/ 45 /*--- Sanity checking ---*/ 46 /*----------------------------------------------------------------*/ 47 48 inline Bool HG_(is_sane_Thread) ( Thread* thr ) { 49 return thr != NULL && thr->magic == Thread_MAGIC; 50 } 51 52 static Bool is_sane_Bag_of_Threads ( WordBag* bag ) 53 { 54 Thread* thr; 55 Word count; 56 VG_(initIterBag)( bag ); 57 while (VG_(nextIterBag)( bag, (Word*)&thr, &count )) { 58 if (count < 1) return False; 59 if (!HG_(is_sane_Thread)(thr)) return False; 60 } 61 VG_(doneIterBag)( bag ); 62 return True; 63 } 64 65 static Bool is_sane_Lock_BASE ( Lock* lock ) 66 { 67 if (lock == NULL 68 || (lock->magic != LockN_MAGIC && lock->magic != LockP_MAGIC)) 69 return False; 70 switch (lock->kind) { 71 case LK_mbRec: case LK_nonRec: case LK_rdwr: break; 72 default: return False; 73 } 74 if (lock->heldBy == NULL) { 75 if (lock->acquired_at != NULL) return False; 76 /* Unheld. We arbitrarily require heldW to be False. */ 77 return !lock->heldW; 78 } else { 79 if (lock->acquired_at == NULL) return False; 80 } 81 82 /* If heldBy is non-NULL, we require it to contain at least one 83 thread. */ 84 if (VG_(isEmptyBag)(lock->heldBy)) 85 return False; 86 87 /* Lock is either r- or w-held. */ 88 if (!is_sane_Bag_of_Threads(lock->heldBy)) 89 return False; 90 if (lock->heldW) { 91 /* Held in write-mode */ 92 if ((lock->kind == LK_nonRec || lock->kind == LK_rdwr) 93 && !VG_(isSingletonTotalBag)(lock->heldBy)) 94 return False; 95 } else { 96 /* Held in read-mode */ 97 if (lock->kind != LK_rdwr) return False; 98 } 99 return True; 100 } 101 102 Bool HG_(is_sane_LockP) ( Lock* lock ) { 103 return lock != NULL 104 && lock->magic == LockP_MAGIC 105 && lock->hbso == NULL 106 && is_sane_Lock_BASE(lock); 107 } 108 109 Bool HG_(is_sane_LockN) ( Lock* lock ) { 110 return lock != NULL 111 && lock->magic == LockN_MAGIC 112 && lock->hbso != NULL 113 && is_sane_Lock_BASE(lock); 114 } 115 116 Bool HG_(is_sane_LockNorP) ( Lock* lock ) { 117 return is_sane_Lock_BASE(lock); 118 } 119 120 121 /*--------------------------------------------------------------------*/ 122 /*--- end hg_lock_n_thread.c ---*/ 123 /*--------------------------------------------------------------------*/ 124