LCOV - code coverage report
Current view: top level - src - sync.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 98.0 % 51 50
Test Date: 2025-08-25 05:11:47 Functions: 100.0 % 10 10
Branches: 20.1 % 13006 2614

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2                 :             : // Copyright (c) 2009-2022 The Bitcoin Core developers
       3                 :             : // Distributed under the MIT software license, see the accompanying
       4                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5                 :             : 
       6                 :             : #ifndef BITCOIN_SYNC_H
       7                 :             : #define BITCOIN_SYNC_H
       8                 :             : 
       9                 :             : #ifdef DEBUG_LOCKCONTENTION
      10                 :             : #include <logging.h>
      11                 :             : #include <logging/timer.h>
      12                 :             : #endif
      13                 :             : 
      14                 :             : #include <threadsafety.h> // IWYU pragma: export
      15                 :             : #include <util/macros.h>
      16                 :             : 
      17                 :             : #include <cassert>
      18                 :             : #include <condition_variable>
      19                 :             : #include <mutex>
      20                 :             : #include <string>
      21                 :             : #include <thread>
      22                 :             : 
      23                 :             : ////////////////////////////////////////////////
      24                 :             : //                                            //
      25                 :             : // THE SIMPLE DEFINITION, EXCLUDING DEBUG CODE //
      26                 :             : //                                            //
      27                 :             : ////////////////////////////////////////////////
      28                 :             : 
      29                 :             : /*
      30                 :             : RecursiveMutex mutex;
      31                 :             :     std::recursive_mutex mutex;
      32                 :             : 
      33                 :             : LOCK(mutex);
      34                 :             :     std::unique_lock<std::recursive_mutex> criticalblock(mutex);
      35                 :             : 
      36                 :             : LOCK2(mutex1, mutex2);
      37                 :             :     std::unique_lock<std::recursive_mutex> criticalblock1(mutex1);
      38                 :             :     std::unique_lock<std::recursive_mutex> criticalblock2(mutex2);
      39                 :             : 
      40                 :             : TRY_LOCK(mutex, name);
      41                 :             :     std::unique_lock<std::recursive_mutex> name(mutex, std::try_to_lock_t);
      42                 :             :  */
      43                 :             : 
      44                 :             : ///////////////////////////////
      45                 :             : //                           //
      46                 :             : // THE ACTUAL IMPLEMENTATION //
      47                 :             : //                           //
      48                 :             : ///////////////////////////////
      49                 :             : 
      50                 :             : #ifdef DEBUG_LOCKORDER
      51                 :             : template <typename MutexType>
      52                 :             : void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false);
      53                 :             : void LeaveCritical();
      54                 :             : void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line);
      55                 :             : template <typename MutexType>
      56                 :             : void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs);
      57                 :             : template <typename MutexType>
      58                 :             : void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs);
      59                 :             : void DeleteLock(void* cs);
      60                 :             : bool LockStackEmpty();
      61                 :             : 
      62                 :             : /**
      63                 :             :  * Call abort() if a potential lock order deadlock bug is detected, instead of
      64                 :             :  * just logging information and throwing a logic_error. Defaults to true, and
      65                 :             :  * set to false in DEBUG_LOCKORDER unit tests.
      66                 :             :  */
      67                 :             : extern bool g_debug_lockorder_abort;
      68                 :             : #else
      69                 :             : template <typename MutexType>
      70                 :     2612695 : inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {}
      71   [ +  -  +  -  :    39488174 : inline void LeaveCritical() {}
          +  -  +  -  +  
              - ][ +  - ]
           [ +  -  +  -  
             +  -  +  - ]
           [ +  -  +  -  
          #  #  #  #  #  
           #  #  # ][ +  
             -  +  -  +  
           - ][ +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
      72                 :     2612696 : inline void CheckLastCritical(void* cs, std::string& lockname, const char* guardname, const char* file, int line) {}
      73                 :             : template <typename MutexType>
      74                 :      147916 : inline void AssertLockHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) EXCLUSIVE_LOCKS_REQUIRED(cs) {}
      75                 :             : template <typename MutexType>
      76                 :             : void AssertLockNotHeldInternal(const char* pszName, const char* pszFile, int nLine, MutexType* cs) LOCKS_EXCLUDED(cs) {}
      77                 :       85955 : inline void DeleteLock(void* cs) {}
      78                 :             : inline bool LockStackEmpty() { return true; }
      79                 :             : #endif
      80                 :             : 
      81                 :             : /**
      82                 :             :  * Template mixin that adds -Wthread-safety locking annotations and lock order
      83                 :             :  * checking to a subset of the mutex API.
      84                 :             :  */
      85                 :             : template <typename PARENT>
      86   [ +  -  +  - ]:       88372 : class LOCKABLE AnnotatedMixin : public PARENT
           [ +  -  +  +  
          +  -  +  -  +  
          -  +  -  +  +  
           -  + ][ +  + ]
           [ +  -  +  +  
           +  - ][ +  -  
          +  -  +  -  +  
             -  +  -  +  
                      - ]
      87                 :             : {
      88                 :             : public:
      89                 :       85955 :     ~AnnotatedMixin() {
      90                 :       85952 :         DeleteLock((void*)this);
      91                 :       78109 :     }
      92                 :             : 
      93                 :             :     void lock() EXCLUSIVE_LOCK_FUNCTION()
      94                 :             :     {
      95                 :             :         PARENT::lock();
      96                 :             :     }
      97                 :             : 
      98                 :             :     void unlock() UNLOCK_FUNCTION()
      99                 :             :     {
     100                 :             :         PARENT::unlock();
     101                 :             :     }
     102                 :             : 
     103                 :         200 :     bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
     104                 :             :     {
     105                 :         200 :         return PARENT::try_lock();
     106                 :             :     }
     107                 :             : 
     108                 :             :     using unique_lock = std::unique_lock<PARENT>;
     109                 :             : #ifdef __clang__
     110                 :             :     //! For negative capabilities in the Clang Thread Safety Analysis.
     111                 :             :     //! A negative requirement uses the EXCLUSIVE_LOCKS_REQUIRED attribute, in conjunction
     112                 :             :     //! with the ! operator, to indicate that a mutex should not be held.
     113                 :             :     const AnnotatedMixin& operator!() const { return *this; }
     114                 :             : #endif // __clang__
     115                 :             : };
     116                 :             : 
     117                 :             : /**
     118                 :             :  * Wrapped mutex: supports recursive locking, but no waiting
     119                 :             :  * TODO: We should move away from using the recursive lock by default.
     120                 :             :  */
     121                 :             : using RecursiveMutex = AnnotatedMixin<std::recursive_mutex>;
     122                 :             : 
     123                 :             : /** Wrapped mutex: supports waiting but not recursive locking */
     124                 :             : using Mutex = AnnotatedMixin<std::mutex>;
     125                 :             : 
     126                 :             : /** Different type to mark Mutex at global scope
     127                 :             :  *
     128                 :             :  * Thread safety analysis can't handle negative assertions about mutexes
     129                 :             :  * with global scope well, so mark them with a separate type, and
     130                 :             :  * eventually move all the mutexes into classes so they are not globally
     131                 :             :  * visible.
     132                 :             :  *
     133                 :             :  * See: https://github.com/bitcoin/bitcoin/pull/20272#issuecomment-720755781
     134                 :             :  */
     135                 :             : class GlobalMutex : public Mutex { };
     136                 :             : 
     137                 :             : #define AssertLockHeld(cs) AssertLockHeldInternal(#cs, __FILE__, __LINE__, &cs)
     138                 :             : 
     139                 :         981 : inline void AssertLockNotHeldInline(const char* name, const char* file, int line, Mutex* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) { AssertLockNotHeldInternal(name, file, line, cs); }
     140                 :             : inline void AssertLockNotHeldInline(const char* name, const char* file, int line, RecursiveMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); }
     141                 :             : inline void AssertLockNotHeldInline(const char* name, const char* file, int line, GlobalMutex* cs) LOCKS_EXCLUDED(cs) { AssertLockNotHeldInternal(name, file, line, cs); }
     142                 :             : #define AssertLockNotHeld(cs) AssertLockNotHeldInline(#cs, __FILE__, __LINE__, &cs)
     143                 :             : 
     144                 :             : /** Wrapper around std::unique_lock style lock for MutexType. */
     145                 :             : template <typename MutexType>
     146                 :             : class SCOPED_LOCKABLE UniqueLock : public MutexType::unique_lock
     147                 :             : {
     148                 :             : private:
     149                 :             :     using Base = typename MutexType::unique_lock;
     150                 :             : 
     151                 :    87196038 :     void Enter(const char* pszName, const char* pszFile, int nLine)
     152                 :             :     {
     153                 :    87196038 :         EnterCritical(pszName, pszFile, nLine, Base::mutex());
     154                 :             : #ifdef DEBUG_LOCKCONTENTION
     155                 :             :         if (Base::try_lock()) return;
     156                 :             :         LOG_TIME_MICROS_WITH_CATEGORY(strprintf("lock contention %s, %s:%d", pszName, pszFile, nLine), BCLog::LOCK);
     157                 :             : #endif
     158 [ +  - ][ +  -  :    87196038 :         Base::lock();
             +  -  #  # ]
           [ +  -  +  -  
                   -  - ]
     159                 :    87196038 :     }
     160                 :             : 
     161                 :        1124 :     bool TryEnter(const char* pszName, const char* pszFile, int nLine)
     162                 :             :     {
     163                 :        1124 :         EnterCritical(pszName, pszFile, nLine, Base::mutex(), true);
     164 [ +  - ][ -  -  :        1124 :         if (Base::try_lock()) {
             +  -  #  # ]
           [ #  #  #  #  
                   #  # ]
     165                 :             :             return true;
     166                 :             :         }
     167                 :             :         LeaveCritical();
     168                 :             :         return false;
     169                 :             :     }
     170                 :             : 
     171                 :             : public:
     172         [ +  + ]:    87040545 :     UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock)
     173                 :             :     {
     174         [ +  + ]:    87040545 :         if (fTry)
     175                 :    87040545 :             TryEnter(pszName, pszFile, nLine);
     176                 :             :         else
     177                 :    87040545 :             Enter(pszName, pszFile, nLine);
     178         [ -  - ]:    87040545 :     }
     179                 :             : 
     180                 :      158428 :     UniqueLock(MutexType* pmutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(pmutexIn)
     181         [ +  + ]:      158428 :     {
     182         [ +  + ]:      158428 :         if (!pmutexIn) return;
     183                 :             : 
     184         [ -  + ]:      156617 :         *static_cast<Base*>(this) = Base(*pmutexIn, std::defer_lock);
     185         [ -  + ]:      156617 :         if (fTry)
     186                 :      158428 :             TryEnter(pszName, pszFile, nLine);
     187                 :             :         else
     188                 :      158428 :             Enter(pszName, pszFile, nLine);
     189         [ -  - ]:           0 :     }
     190                 :             : 
     191                 :    89810433 :     ~UniqueLock() UNLOCK_FUNCTION()
     192                 :             :     {
     193   [ +  -  +  -  :    87197864 :         if (Base::owns_lock())
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
           [ +  -  +  -  
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
           - ][ +  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
             -  +  -  -  
           - ][ +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
             -  -  -  -  
           - ][ +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  +  
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  -  -  
             +  -  -  - ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
             -  -  -  -  
           - ][ +  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  - ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
             +  -  -  - ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
           +  - ][ +  -  
          +  -  +  -  +  
          -  -  -  +  -  
           +  - ][ +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
           -  - ][ +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
             -  +  -  -  
           - ][ +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
           -  - ][ #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
             +  -  -  - ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
           - ][ +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
           - ][ -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  -  
          +  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
             -  -  +  - ]
           [ +  -  +  -  
          +  -  -  -  +  
          -  -  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  +  -  -  
           - ][ +  -  +  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  -  -  
             -  -  -  - ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
             +  -  -  - ]
           [ +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  -  
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
             -  +  -  -  
           - ][ +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  -  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  - ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
             -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     194                 :             :             LeaveCritical();
     195   [ +  -  +  -  :   128338869 :     }
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  - ]
           [ +  -  +  -  
          +  -  -  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           # ][ +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  - ]
           [ +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  +  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  +  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
           -  - ][ +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  +  
          +  -  +  +  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          +  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  +  
          +  -  -  -  -  
          -  -  +  -  +  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          +  -  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  +  +  -  -  
          -  +  -  +  -  
          +  -  +  +  +  
          -  -  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          +  +  -  +  -  
          +  +  +  -  +  
          +  +  -  +  -  
          +  +  +  -  -  
          -  +  -  +  +  
          +  -  +  -  +  
          -  -  -  +  -  
          +  +  +  +  +  
          +  +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          +  +  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  +  
          -  -  +  -  -  
          -  +  -  +  +  
          -  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
             -  -  -  -  
           - ][ +  -  +  
          -  +  +  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  +  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          +  +  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  +  +  -  +  
          +  +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          +  -  -  +  -  
          +  +  -  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  -  - ]
           [ +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  -  -  +  -  
           -  - ][ +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
           -  - ][ +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  -  -  
             -  -  -  - ]
           [ +  -  +  -  
          +  +  -  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  -  
           - ][ +  +  +  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  +  -  -  
           - ][ +  -  -  
          -  +  -  -  -  
          +  +  -  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
           -  -  - ][ +  
          -  +  +  +  -  
          +  +  +  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
             -  -  -  -  
           - ][ +  -  +  
          +  +  -  +  -  
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  +  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  -  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
           -  - ][ +  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
             -  +  -  +  
           - ][ +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  +  +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  +  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  -  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  -  
           - ][ +  -  -  
          +  +  -  +  -  
          +  +  +  -  +  
          -  +  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  +  +  +  
          -  +  +  +  -  
          +  +  +  -  +  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          +  +  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  +  +  -  
          -  +  -  +  -  
          -  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          +  -  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          +  +  -  +  +  
          +  -  +  -  +  
          +  +  -  +  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  +  
          +  -  +  +  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  -  
           - ][ +  -  +  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  -  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
           - ][ +  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
             -  -  -  +  
           - ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  +  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
           -  -  - ][ +  
          -  +  -  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  +  -  +  +  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  -  -  +  
          -  -  +  -  -  
          +  -  -  +  -  
          -  +  -  -  +  
          -  -  +  -  -  
          +  -  -  +  -  
          -  +  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
             +  -  -  - ]
           [ +  -  +  -  
          -  -  +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  -  
           - ][ +  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  -  -  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  +  -  -  
          -  +  -  -  -  
             +  -  -  - ]
           [ +  -  +  -  
          -  -  -  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
          -  -  -  -  -  
          +  -  +  -  -  
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  -  -  +  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  #  # ][ +  
          -  -  -  +  -  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  +  +  -  
          +  -  +  -  +  
           -  +  - ][ +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  #  
           # ][ +  -  +  
          -  -  -  -  -  
          +  -  -  -  +  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
           # ][ +  -  +  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  +  -  +  
          -  +  -  -  -  
          -  -  +  -  +  
             -  -  -  -  
           - ][ +  -  +  
          +  +  -  -  -  
          +  -  -  -  -  
          -  -  -  -  -  
          -  -  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     196                 :             : 
     197                 :        1124 :     operator bool()
     198                 :             :     {
     199   [ #  #  #  # ]:        1124 :         return Base::owns_lock();
                 [ +  + ]
     200                 :             :     }
     201                 :             : 
     202                 :             : protected:
     203                 :             :     // needed for reverse_lock
     204                 :     2612696 :     UniqueLock() = default;
     205                 :             : 
     206                 :             : public:
     207                 :             :     /**
     208                 :             :      * An RAII-style reverse lock. Unlocks on construction and locks on destruction.
     209                 :             :      */
     210                 :             :     class SCOPED_LOCKABLE reverse_lock {
     211                 :             :     public:
     212         [ +  - ]:     2612697 :         explicit reverse_lock(UniqueLock& _lock, const MutexType& mutex, const char* _guardname, const char* _file, int _line) UNLOCK_FUNCTION(mutex) : lock(_lock), file(_file), line(_line) {
     213                 :             :             // Ensure that mutex passed back for thread-safety analysis is indeed the original
     214         [ -  + ]:     2612696 :             assert(std::addressof(mutex) == lock.mutex());
     215                 :             : 
     216         [ +  + ]:     2612696 :             CheckLastCritical((void*)lock.mutex(), lockname, _guardname, _file, _line);
     217         [ +  + ]:     2612696 :             lock.unlock();
     218                 :             :             LeaveCritical();
     219                 :     2612695 :             lock.swap(templock);
     220         [ -  + ]:     2612696 :         }
     221                 :             : 
     222                 :     2612695 :         ~reverse_lock() UNLOCK_FUNCTION() {
     223                 :     2612695 :             templock.swap(lock);
     224                 :     2612695 :             EnterCritical(lockname.c_str(), file.c_str(), line, lock.mutex());
     225                 :     2612695 :             lock.lock();
     226         [ -  + ]:     2612695 :         }
     227                 :             : 
     228                 :             :      private:
     229                 :             :         reverse_lock(reverse_lock const&);
     230                 :             :         reverse_lock& operator=(reverse_lock const&);
     231                 :             : 
     232                 :             :         UniqueLock& lock;
     233                 :             :         UniqueLock templock;
     234                 :             :         std::string lockname;
     235                 :             :         const std::string file;
     236                 :             :         const int line;
     237                 :             :      };
     238                 :             :      friend class reverse_lock;
     239                 :             : };
     240                 :             : 
     241                 :             : // clang's thread-safety analyzer is unable to deal with aliases of mutexes, so
     242                 :             : // it is not possible to use the lock's copy of the mutex for that purpose.
     243                 :             : // Instead, the original mutex needs to be passed back to the reverse_lock for
     244                 :             : // the sake of thread-safety analysis, but it is not actually used otherwise.
     245                 :             : #define REVERSE_LOCK(g, cs) typename std::decay<decltype(g)>::type::reverse_lock UNIQUE_NAME(revlock)(g, cs, #cs, __FILE__, __LINE__)
     246                 :             : 
     247                 :             : // When locking a Mutex, require negative capability to ensure the lock
     248                 :             : // is not already held
     249         [ +  - ]:     1051915 : inline Mutex& MaybeCheckNotHeld(Mutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; }
     250                 :             : inline Mutex* MaybeCheckNotHeld(Mutex* cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; }
     251                 :             : 
     252                 :             : // When locking a GlobalMutex or RecursiveMutex, just check it is not
     253                 :             : // locked in the surrounding scope.
     254                 :             : template <typename MutexType>
     255         [ +  - ]:      810215 : inline MutexType& MaybeCheckNotHeld(MutexType& m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; }
     256                 :             : template <typename MutexType>
     257                 :             : inline MutexType* MaybeCheckNotHeld(MutexType* m) LOCKS_EXCLUDED(m) LOCK_RETURNED(m) { return m; }
     258                 :             : 
     259                 :             : #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
     260                 :             : #define LOCK2(cs1, cs2)                                               \
     261                 :             :     UniqueLock criticalblock1(MaybeCheckNotHeld(cs1), #cs1, __FILE__, __LINE__); \
     262                 :             :     UniqueLock criticalblock2(MaybeCheckNotHeld(cs2), #cs2, __FILE__, __LINE__)
     263                 :             : #define LOCK_ARGS(cs) MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__
     264                 :             : #define TRY_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs), true)
     265                 :             : #define WAIT_LOCK(cs, name) UniqueLock name(LOCK_ARGS(cs))
     266                 :             : 
     267                 :             : //! Run code while locking a mutex.
     268                 :             : //!
     269                 :             : //! Examples:
     270                 :             : //!
     271                 :             : //!   WITH_LOCK(cs, shared_val = shared_val + 1);
     272                 :             : //!
     273                 :             : //!   int val = WITH_LOCK(cs, return shared_val);
     274                 :             : //!
     275                 :             : //! Note:
     276                 :             : //!
     277                 :             : //! Since the return type deduction follows that of decltype(auto), while the
     278                 :             : //! deduced type of:
     279                 :             : //!
     280                 :             : //!   WITH_LOCK(cs, return {int i = 1; return i;});
     281                 :             : //!
     282                 :             : //! is int, the deduced type of:
     283                 :             : //!
     284                 :             : //!   WITH_LOCK(cs, return {int j = 1; return (j);});
     285                 :             : //!
     286                 :             : //! is &int, a reference to a local variable
     287                 :             : //!
     288                 :             : //! The above is detectable at compile-time with the -Wreturn-local-addr flag in
     289                 :             : //! gcc and the -Wreturn-stack-address flag in clang, both enabled by default.
     290                 :             : #define WITH_LOCK(cs, code) (MaybeCheckNotHeld(cs), [&]() -> decltype(auto) { LOCK(cs); code; }())
     291                 :             : 
     292                 :             : #endif // BITCOIN_SYNC_H
        

Generated by: LCOV version 2.0-1