1f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 3f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- Definitions for Locks and Threads. ---*/ 4f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- hg_lock_n_thread.c ---*/ 5f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 6f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 7f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* 8f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This file is part of Helgrind, a Valgrind tool for detecting errors 9f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj in threaded programs. 10f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2007-2017 OpenWorks Ltd 12f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj info@open-works.co.uk 13f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 14f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This program is free software; you can redistribute it and/or 15f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj modify it under the terms of the GNU General Public License as 16f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj published by the Free Software Foundation; either version 2 of the 17f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj License, or (at your option) any later version. 18f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 19f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This program is distributed in the hope that it will be useful, but 20f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj General Public License for more details. 23f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 24f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj You should have received a copy of the GNU General Public License 25f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj along with this program; if not, write to the Free Software 26f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 02111-1307, USA. 28f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 29f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj The GNU General Public License is contained in the file COPYING. 30f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 31f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 32f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_basics.h" 33f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_libcbase.h" 34f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_libcassert.h" 35f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_execontext.h" 36f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_threadstate.h" 37f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_wordfm.h" 38f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 39f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_basics.h" 40f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_wordset.h" 41f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_lock_n_thread.h" /* self */ 42f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 43f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 44f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*----------------------------------------------------------------*/ 45f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- Sanity checking ---*/ 46f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*----------------------------------------------------------------*/ 47f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 48f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjinline Bool HG_(is_sane_Thread) ( Thread* thr ) { 49f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return thr != NULL && thr->magic == Thread_MAGIC; 50f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 51f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 52f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool is_sane_Bag_of_Threads ( WordBag* bag ) 53f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 54f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; 556bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian UWord count; 56f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(initIterBag)( bag ); 576bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian while (VG_(nextIterBag)( bag, (UWord*)&thr, &count )) { 58f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (count < 1) return False; 59f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (!HG_(is_sane_Thread)(thr)) return False; 60f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 61f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(doneIterBag)( bag ); 62f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return True; 63f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 64f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 65f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Bool is_sane_Lock_BASE ( Lock* lock ) 66f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 67f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock == NULL 68f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj || (lock->magic != LockN_MAGIC && lock->magic != LockP_MAGIC)) 69f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; 70f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj switch (lock->kind) { 71f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case LK_mbRec: case LK_nonRec: case LK_rdwr: break; 72f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj default: return False; 73f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 74f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock->heldBy == NULL) { 75f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock->acquired_at != NULL) return False; 76f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Unheld. We arbitrarily require heldW to be False. */ 77f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return !lock->heldW; 78f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 79f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock->acquired_at == NULL) return False; 80f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 81f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 82f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* If heldBy is non-NULL, we require it to contain at least one 83f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj thread. */ 84f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (VG_(isEmptyBag)(lock->heldBy)) 85f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; 86f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 87f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Lock is either r- or w-held. */ 88f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (!is_sane_Bag_of_Threads(lock->heldBy)) 89f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; 90f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock->heldW) { 91f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Held in write-mode */ 92f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if ((lock->kind == LK_nonRec || lock->kind == LK_rdwr) 93f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && !VG_(isSingletonTotalBag)(lock->heldBy)) 94f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; 95f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 96f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Held in read-mode */ 97f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lock->kind != LK_rdwr) return False; 98f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 99f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return True; 100f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 101f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 102f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool HG_(is_sane_LockP) ( Lock* lock ) { 103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return lock != NULL 104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && lock->magic == LockP_MAGIC 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && lock->hbso == NULL 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && is_sane_Lock_BASE(lock); 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 109f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool HG_(is_sane_LockN) ( Lock* lock ) { 110f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return lock != NULL 111f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && lock->magic == LockN_MAGIC 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && lock->hbso != NULL 113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && is_sane_Lock_BASE(lock); 114f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 115f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 116f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjBool HG_(is_sane_LockNorP) ( Lock* lock ) { 117f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return is_sane_Lock_BASE(lock); 118f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 119f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 120f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 121f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 122f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- end hg_lock_n_thread.c ---*/ 123f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 124