static bool _CalculateLockDependency()

in src/Trinity.C/src/Storage/LocalStorage/ThreadContext.cpp [211:310]


    static bool _CalculateLockDependency(const THREAD_CONTEXT& a, const THREAD_CONTEXT& b)
    {
        auto sa = _GetThreadContextStatus(a);
        auto sb = _GetThreadContextStatus(b);

        if (sa == LOCKCELL) switch (sb)
        {
        case LOCKCELL:
            // a is locking a cell held by b
            return b.LockedCells.Contains(a.LockingCell);
        case LOCKHASH:
            // a is locking a cell, whose bucket lock is taken by b.
            // or b is holding the lock.
            return (Storage::LocalMemoryStorage::GetTrunkId(a.LockingCell) == 
                    b.LockingMTHash)
                    || b.LockedCells.Contains(a.LockingCell);
        case RELOAD:
            // a is locking a cell, whose trunk is being reloaded
            // or b is holding the lock.
            return (Storage::LocalMemoryStorage::GetTrunkId(a.LockingCell) ==
                    Storage::LocalMemoryStorage::GetTrunkId(b.LockingCell))
                    || b.LockedCells.Contains(a.LockingCell);
        case LOCKDB:
            // a is locking a cell while the db is being locked
            return true;
        }
        else if (sb == LOCKCELL) switch (sa)
        {
            //case LOCKCELL: <-- already executed in previous branch
        case LOCKHASH:
            // a is locking a MTHash, while b possesses cell locks in this MTHash
            return b.LockedCells.Any([&](cellid_t lockedCell)
            {
                return 
                    Storage::LocalMemoryStorage::GetTrunkId(lockedCell) == 
                    a.LockingMTHash;
            });
        case RELOAD:
            // a is reloading while b has locked a cell in the same MTHash
            return b.LockedCells.Any([&](cellid_t lockedCell)
            {
                return 
                    Storage::LocalMemoryStorage::GetTrunkId(lockedCell) == 
                    Storage::LocalMemoryStorage::GetTrunkId(a.LockingCell);
            });
        case LOCKDB:
            // a is locking db, while b possesses cell locks
            return (b.LockedCells.size() != 0);
        }
        /*(sa != LOCKCELL && sb != LOCKCELL)*/
        else if (sa == RELOAD) switch(sb)
        {
        case LOCKHASH:
        case LOCKDB:
            // a is reloading a MTHash, and b possesses some locks in that trunk.
            return b.LockedCells.Any([&](cellid_t lockedCell)
            {
                return 
                    Storage::LocalMemoryStorage::GetTrunkId(lockedCell) == 
                    Storage::LocalMemoryStorage::GetTrunkId(a.LockingCell);
            });
        case RELOAD:
            // when both a and b are reloading (they should be reloading different trunks
            // due to the alloc_lock), they do not lock each other, because they share
            // g_memory_arena and thus are aware of each other's context.
            return false;
        }
        else if (sa == LOCKHASH) switch (sb) 
        {
        case LOCKHASH:
        case LOCKDB:
            // a is locking a MTHash, while b possesses cell locks in that trunk.
            return b.LockedCells.Any([&](cellid_t lockedCell)
            {
                return 
                    Storage::LocalMemoryStorage::GetTrunkId(lockedCell) == 
                    a.LockingMTHash;
            });
            break;
        case RELOAD:
            // a is locking a MTHash, while b is reloading this MTHash (taken all entries)
            return 
                a.LockingMTHash ==
                Storage::LocalMemoryStorage::GetTrunkId(b.LockingCell);
            break;
        }
        else if (sa == LOCKDB) switch (sb) 
        {
        case LOCKHASH:
        case LOCKDB:
            // a is locking db and b possesses cell locks.
            return (b.LockedCells.size() != 0);
        case RELOAD:
            // a is locking db and b is reloading, and thus possesses at least one cell lock.
            return true;
        }

        assert(false && "_CalculateDependency_LOCKCELL");
        return false;
    }