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-2017 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 small ints
     49    numbered from zero, since 32-bit versions of them are used to
     50    encode lock-sets in libhb's history records (Thr_n_RCEC). */
     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.  Thr's are
     58    allocated and never deallocated (simply leaked).  Also ThrID, which
     59    is a small integer which uniquely identifies a Thr and which is
     60    used in ScalarTS because it is smaller than a Thr*.  There is a 1-1
     61    mapping between Thr's and ThrIDs. */
     62 typedef  struct _Thr  Thr;
     63 typedef  UInt         ThrID;
     64 
     65 
     66 /* Stores information about a thread.  Addresses of these also serve
     67    as unique thread identifiers and so are never freed, so they should
     68    be as small as possible.  Freeing Thread structures makes the
     69    storage management just too complex, and most programs don't create
     70    many threads, so tolerating this leak seems like a not-bad
     71    tradeoff.
     72 
     73    Since these are never freed, the .coretid field only indicates the
     74    core's ThreadId associated with this Thread whilst it is alive.
     75    Once the thread finishes, the ThreadId is set to
     76    VG_INVALID_THREADID.
     77 
     78    The core may later re-use the same ThreadId for what is a logically
     79    completely different thread, which of course must have a different
     80    Thread structure. */
     81 typedef
     82    struct _Thread {
     83       /* ADMIN */
     84       struct _Thread* admin;
     85       UInt            magic;
     86       Thr*            hbthr; /* which in turn points back here .. */
     87       ThreadId        coretid;  /* .. via its hgthread field */
     88       /* USEFUL */
     89       WordSetID locksetA; /* WordSet of Lock* currently held by thread */
     90       WordSetID locksetW; /* subset of locksetA held in w-mode */
     91       /* EXPOSITION */
     92       /* Place where parent was when this thread was created. */
     93       ExeContext* created_at;
     94       Bool        announced;
     95       /* Index for generating references in error messages. */
     96       Int         errmsg_index;
     97 
     98       /* Nesting level of pthread_create(). New memory allocated is untracked
     99          when this value is > 0: race reporting is suppressed there. DRD does
    100          the same thing implicitly. This is necessary because for example
    101          Solaris libc caches many objects and reuses them for different threads
    102          and that confuses Helgrind. With libvki it would be possible to
    103          explicitly use VG_USERREQ__HG_CLEAN_MEMORY on such objects.
    104          Also mutex activity is ignored so that they do not impose false
    105          ordering between creator and created thread. */
    106       Int pthread_create_nesting_level;
    107 
    108       /* Nesting level of synchronization functions called by the client.
    109          Loads and stores are ignored when its value > 0.
    110          Currently this is used solely for suppressing races of primitive
    111          synchronization objects themselves - mutexes, condition variables,
    112          read-write locks and their associated sleep queues.
    113          See also documentation for command line option
    114          --ignore-thread-creation. */
    115       Int synchr_nesting;
    116 
    117 #if defined(VGO_solaris)
    118       Int      bind_guard_flag; /* Bind flag from the runtime linker. */
    119 #endif /* VGO_solaris */
    120    }
    121    Thread;
    122 
    123 /* Get hg's admin_threads value, so libhb can visit all of them. */
    124 Thread* get_admin_threads ( void );
    125 
    126 /* Stores information about a lock's current state.  These are
    127    allocated and later freed (when the containing memory becomes
    128    NoAccess).  This gives a problem for the XError type, which
    129    contains Lock*s.  Solution is to copy any Lock which is to be
    130    incorporated into an XErrors, so as to make it independent from the
    131    'normal' collection of Locks, which can come and go.  When the lock
    132    is copied, its .magic is changed from LockN_Magic to
    133    LockP_Magic. */
    134 
    135 /* Lock kinds. */
    136 typedef
    137    enum {
    138       LK_mbRec=1001, /* normal mutex, possibly recursive */
    139       LK_nonRec,     /* normal mutex, definitely non recursive */
    140       LK_rdwr        /* reader-writer lock */
    141    }
    142    LockKind;
    143 
    144 typedef
    145    struct _Lock {
    146       /* ADMIN */
    147       struct _Lock* admin_next; /* fields for a double linked */
    148       struct _Lock* admin_prev; /* list of these locks */
    149       ULong         unique; /* used for persistence-hashing */
    150       UInt          magic;  /* LockN_MAGIC or LockP_MAGIC */
    151       /* EXPOSITION */
    152       /* Place where lock first came to the attention of Helgrind. */
    153       ExeContext*   appeared_at;
    154       /* If the lock is held, place where the lock most recently made
    155          an unlocked->locked transition.  Must be sync'd with .heldBy:
    156          either both NULL or both non-NULL. */
    157       ExeContext*   acquired_at;
    158       /* USEFUL-STATIC */
    159       SO*           hbso;      /* associated SO */
    160       Addr          guestaddr; /* Guest address of lock */
    161       LockKind      kind;      /* what kind of lock this is */
    162       /* USEFUL-DYNAMIC */
    163       Bool          heldW;
    164       WordBag*      heldBy; /* bag of threads that hold this lock */
    165       /* .heldBy is NULL: lock is unheld, and .heldW is meaningless
    166                           but arbitrarily set to False
    167          .heldBy is non-NULL:
    168             .heldW is True:  lock is w-held by threads in heldBy
    169             .heldW is False: lock is r-held by threads in heldBy
    170             Either way, heldBy may not validly be an empty Bag.
    171 
    172          for LK_nonRec, r-holdings are not allowed, and w-holdings may
    173          only have sizeTotal(heldBy) == 1
    174 
    175          for LK_mbRec, r-holdings are not allowed, and w-holdings may
    176          only have sizeUnique(heldBy) == 1
    177 
    178          for LK_rdwr, w-holdings may only have sizeTotal(heldBy) == 1 */
    179    }
    180    Lock;
    181 
    182 #define Lock_INVALID  ((Lock*)1UL)
    183 
    184 /*----------------------------------------------------------------*/
    185 /*--- Sanity checking                                          ---*/
    186 /*----------------------------------------------------------------*/
    187 
    188 Bool HG_(is_sane_Thread)   ( Thread* thr );
    189 Bool HG_(is_sane_LockP)    ( Lock* lock );
    190 Bool HG_(is_sane_LockN)    ( Lock* lock );
    191 Bool HG_(is_sane_LockNorP) ( Lock* lock );
    192 
    193 
    194 #endif /* ! __HG_LOCK_N_THREAD_H */
    195 
    196 /*--------------------------------------------------------------------*/
    197 /*--- end                                       hg_lock_n_thread.h ---*/
    198 /*--------------------------------------------------------------------*/
    199