Home | History | Annotate | Download | only in helgrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Definitions for Locks and Threads.                           ---*/
      4 /*---                                           hg_lock_n_thread.h ---*/
      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-2010 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 #ifndef __HG_LOCK_N_THREAD_H
     33 #define __HG_LOCK_N_THREAD_H
     34 
     35 
     36 /*----------------------------------------------------------------*/
     37 /*--- Primary data definitions                                 ---*/
     38 /*----------------------------------------------------------------*/
     39 
     40 /* Magic numbers, for doing assertions that structures really are of
     41    the right type.  Useful as some of the code can get a bit
     42    complex. */
     43 #define Thread_MAGIC   0x504fc5e5
     44 #define LockN_MAGIC    0x6545b557 /* normal nonpersistent locks */
     45 #define LockP_MAGIC    0x755b5456 /* persistent (copied) locks */
     46 
     47 
     48 /* These are handles for Word sets.  CONSTRAINTS: must be (very) small
     49    ints numbered from zero, since < 30-bit versions of them are used to
     50    encode thread-sets and lock-sets in 32-bit shadow words. */
     51 typedef  WordSet  WordSetID;
     52 
     53 
     54 /* Synchronisation Objects, exported abstractly by libhb. */
     55 typedef  struct _SO  SO;
     56 
     57 /* Thr, libhb's private thread record, exported abstractly */
     58 typedef  struct _Thr  Thr;
     59 
     60 
     61 /* Stores information about a thread.  Addresses of these also serve
     62    as unique thread identifiers and so are never freed, so they should
     63    be as small as possible.  Freeing Thread structures makes the
     64    storage management just too complex, and most programs don't create
     65    many threads, so tolerating this leak seems like a not-bad
     66    tradeoff.
     67 
     68    Since these are never freed, the .coretid field only indicates the
     69    core's ThreadId associated with this Thread whilst it is alive.
     70    Once the thread finishes, the ThreadId is set to
     71    VG_INVALID_THREADID.
     72 
     73    The core may later re-use the same ThreadId for what is a logically
     74    completely different thread, which of course must have a different
     75    Thread structure. */
     76 typedef
     77    struct _Thread {
     78       /* ADMIN */
     79       struct _Thread* admin;
     80       UInt            magic;
     81       Thr*            hbthr;
     82       ThreadId        coretid;
     83       /* USEFUL */
     84       WordSetID locksetA; /* WordSet of Lock* currently held by thread */
     85       WordSetID locksetW; /* subset of locksetA held in w-mode */
     86       /* EXPOSITION */
     87       /* Place where parent was when this thread was created. */
     88       ExeContext* created_at;
     89       Bool        announced;
     90       /* Index for generating references in error messages. */
     91       Int         errmsg_index;
     92    }
     93    Thread;
     94 
     95 
     96 /* Stores information about a lock's current state.  These are
     97    allocated and later freed (when the containing memory becomes
     98    NoAccess).  This gives a problem for the XError type, which
     99    contains Lock*s.  Solution is to copy any Lock which is to be
    100    incorporated into an XErrors, so as to make it independent from the
    101    'normal' collection of Locks, which can come and go.  When the lock
    102    is copied, its .magic is changed from LockN_Magic to
    103    LockP_Magic. */
    104 
    105 /* Lock kinds. */
    106 typedef
    107    enum {
    108       LK_mbRec=1001, /* normal mutex, possibly recursive */
    109       LK_nonRec,     /* normal mutex, definitely non recursive */
    110       LK_rdwr        /* reader-writer lock */
    111    }
    112    LockKind;
    113 
    114 typedef
    115    struct _Lock {
    116       /* ADMIN */
    117       struct _Lock* admin;
    118       ULong         unique; /* used for persistence-hashing */
    119       UInt          magic;  /* LockN_MAGIC or LockP_MAGIC */
    120       /* EXPOSITION */
    121       /* Place where lock first came to the attention of Helgrind. */
    122       ExeContext*   appeared_at;
    123       /* If the lock is held, place where the lock most recently made
    124          an unlocked->locked transition.  Must be sync'd with .heldBy:
    125          either both NULL or both non-NULL. */
    126       ExeContext*   acquired_at;
    127       /* USEFUL-STATIC */
    128       SO*           hbso;      /* associated SO */
    129       Addr          guestaddr; /* Guest address of lock */
    130       LockKind      kind;      /* what kind of lock this is */
    131       /* USEFUL-DYNAMIC */
    132       Bool          heldW;
    133       WordBag*      heldBy; /* bag of threads that hold this lock */
    134       /* .heldBy is NULL: lock is unheld, and .heldW is meaningless
    135                           but arbitrarily set to False
    136          .heldBy is non-NULL:
    137             .heldW is True:  lock is w-held by threads in heldBy
    138             .heldW is False: lock is r-held by threads in heldBy
    139             Either way, heldBy may not validly be an empty Bag.
    140 
    141          for LK_nonRec, r-holdings are not allowed, and w-holdings may
    142          only have sizeTotal(heldBy) == 1
    143 
    144          for LK_mbRec, r-holdings are not allowed, and w-holdings may
    145          only have sizeUnique(heldBy) == 1
    146 
    147          for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */
    148    }
    149    Lock;
    150 
    151 /*----------------------------------------------------------------*/
    152 /*--- Sanity checking                                          ---*/
    153 /*----------------------------------------------------------------*/
    154 
    155 Bool HG_(is_sane_Thread)   ( Thread* thr );
    156 Bool HG_(is_sane_LockP)    ( Lock* lock );
    157 Bool HG_(is_sane_LockN)    ( Lock* lock );
    158 Bool HG_(is_sane_LockNorP) ( Lock* lock );
    159 
    160 
    161 #endif /* ! __HG_LOCK_N_THREAD_H */
    162 
    163 /*--------------------------------------------------------------------*/
    164 /*--- end                                       hg_lock_n_thread.h ---*/
    165 /*--------------------------------------------------------------------*/
    166