Merge Helgrind from branches/YARD into the trunk.  Also includes some
minor changes to make stack unwinding on amd64-linux approximately
twice as fast as it was before.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8707 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/helgrind/hg_lock_n_thread.h b/helgrind/hg_lock_n_thread.h
new file mode 100644
index 0000000..64b1f1e
--- /dev/null
+++ b/helgrind/hg_lock_n_thread.h
@@ -0,0 +1,165 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Definitions for Locks and Threads.                           ---*/
+/*---                                           hg_lock_n_thread.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+   This file is part of Helgrind, a Valgrind tool for detecting errors
+   in threaded programs.
+
+   Copyright (C) 2007-2008 OpenWorks Ltd
+      info@open-works.co.uk
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307, USA.
+
+   The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __HG_LOCK_N_THREAD_H
+#define __HG_LOCK_N_THREAD_H
+
+
+/*----------------------------------------------------------------*/
+/*--- Primary data definitions                                 ---*/
+/*----------------------------------------------------------------*/
+
+/* Magic numbers, for doing assertions that structures really are of
+   the right type.  Useful as some of the code can get a bit
+   complex. */
+#define Thread_MAGIC   0x504fc5e5
+#define LockN_MAGIC    0x6545b557 /* normal nonpersistent locks */
+#define LockP_MAGIC    0x755b5456 /* persistent (copied) locks */
+
+
+/* These are handles for Word sets.  CONSTRAINTS: must be (very) small
+   ints numbered from zero, since < 30-bit versions of them are used to
+   encode thread-sets and lock-sets in 32-bit shadow words. */
+typedef  WordSet  WordSetID;
+
+
+/* Synchronisation Objects, exported abstractly by libhb. */
+typedef  struct _SO  SO;
+
+/* Thr, libhb's private thread record, exported abstractly */
+typedef  struct _Thr  Thr;
+
+
+/* Stores information about a thread.  Addresses of these also serve
+   as unique thread identifiers and so are never freed, so they should
+   be as small as possible.  Freeing Thread structures makes the
+   storage management just too complex, and most programs don't create
+   many threads, so tolerating this leak seems like a not-bad
+   tradeoff.
+
+   Since these are never freed, the .coretid field only indicates the
+   core's ThreadId associated with this Thread whilst it is alive.
+   Once the thread finishes, the ThreadId is set to
+   VG_INVALID_THREADID.
+
+   The core may later re-use the same ThreadId for what is a logically
+   completely different thread, which of course must have a different
+   Thread structure. */
+typedef
+   struct _Thread {
+      /* ADMIN */
+      struct _Thread* admin;
+      UInt            magic;
+      Thr*            hbthr;
+      ThreadId        coretid;
+      /* USEFUL */
+      WordSetID locksetA; /* WordSet of Lock* currently held by thread */
+      WordSetID locksetW; /* subset of locksetA held in w-mode */
+      /* EXPOSITION */
+      /* Place where parent was when this thread was created. */
+      ExeContext* created_at;
+      Bool        announced;
+      /* Index for generating references in error messages. */
+      Int         errmsg_index;
+   }
+   Thread;
+
+
+/* Stores information about a lock's current state.  These are
+   allocated and later freed (when the containing memory becomes
+   NoAccess).  This gives a problem for the XError type, which
+   contains Lock*s.  Solution is to copy any Lock which is to be
+   incorporated into an XErrors, so as to make it independent from the
+   'normal' collection of Locks, which can come and go.  When the lock
+   is copied, its .magic is changed from LockN_Magic to
+   LockP_Magic. */
+
+/* Lock kinds. */
+typedef
+   enum {
+      LK_mbRec=1001, /* normal mutex, possibly recursive */
+      LK_nonRec,     /* normal mutex, definitely non recursive */
+      LK_rdwr        /* reader-writer lock */
+   }
+   LockKind;
+
+typedef
+   struct _Lock {
+      /* ADMIN */
+      struct _Lock* admin;
+      ULong         unique; /* used for persistence-hashing */
+      UInt          magic;  /* LockN_MAGIC or LockP_MAGIC */
+      /* EXPOSITION */
+      /* Place where lock first came to the attention of Helgrind. */
+      ExeContext*   appeared_at;
+      /* If the lock is held, place where the lock most recently made
+         an unlocked->locked transition.  Must be sync'd with .heldBy:
+         either both NULL or both non-NULL. */
+      ExeContext*   acquired_at;
+      /* USEFUL-STATIC */
+      SO*           hbso;      /* associated SO */
+      Addr          guestaddr; /* Guest address of lock */
+      LockKind      kind;      /* what kind of lock this is */
+      /* USEFUL-DYNAMIC */
+      Bool          heldW; 
+      WordBag*      heldBy; /* bag of threads that hold this lock */
+      /* .heldBy is NULL: lock is unheld, and .heldW is meaningless
+                          but arbitrarily set to False
+         .heldBy is non-NULL:
+            .heldW is True:  lock is w-held by threads in heldBy
+            .heldW is False: lock is r-held by threads in heldBy
+            Either way, heldBy may not validly be an empty Bag.
+
+         for LK_nonRec, r-holdings are not allowed, and w-holdings may
+         only have sizeTotal(heldBy) == 1
+
+         for LK_mbRec, r-holdings are not allowed, and w-holdings may
+         only have sizeUnique(heldBy) == 1
+
+         for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */
+   }
+   Lock;
+
+/*----------------------------------------------------------------*/
+/*--- Sanity checking                                          ---*/
+/*----------------------------------------------------------------*/
+
+Bool HG_(is_sane_Thread)   ( Thread* thr );
+Bool HG_(is_sane_LockP)    ( Lock* lock );
+Bool HG_(is_sane_LockN)    ( Lock* lock );
+Bool HG_(is_sane_LockNorP) ( Lock* lock );
+
+
+#endif /* ! __HG_LOCK_N_THREAD_H */
+
+/*--------------------------------------------------------------------*/
+/*--- end                                       hg_lock_n_thread.h ---*/
+/*--------------------------------------------------------------------*/