Skip to content

Commit

Permalink
DeadLock diagnostic fix
Browse files Browse the repository at this point in the history
Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman committed Oct 25, 2024
1 parent 0d56cf6 commit 83183b7
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -437,6 +435,13 @@ protected static Map<Thread, DeferredLockManager> getDeferredLockManagers() {
return DEFERRED_LOCK_MANAGERS;
}

/**
* Return snapshot of the deferred lock manager hashtable (thread - DeferredLockManager).
*/
protected static Map<Thread, DeferredLockManager> getDeferredLockManagersSnapshot() {
return Map.copyOf(DEFERRED_LOCK_MANAGERS);
}

/**
* Init the deferred lock managers (thread - DeferredLockManager).
*/
Expand Down Expand Up @@ -870,6 +875,13 @@ protected static Map<Thread, ReadLockManager> getReadLockManagers() {
return READ_LOCK_MANAGERS;
}

/**
* Return snapshot of the deferred lock manager hashtable (thread - DeferredLockManager).
*/
protected static Map<Thread, ReadLockManager> getReadLockManagersSnapshot() {
return Map.copyOf(READ_LOCK_MANAGERS);
}

/**
* Print the nested depth.
*/
Expand Down Expand Up @@ -971,33 +983,33 @@ public long getTotalNumberOfKeysReleasedForReadingBlewUpExceptionDueToCacheKeyHa
}

/** Getter for {@link #THREADS_TO_WAIT_ON_ACQUIRE} */
public static Map<Thread, ConcurrencyManager> getThreadsToWaitOnAcquire() {
return new HashMap<>(THREADS_TO_WAIT_ON_ACQUIRE);
public static Map<Thread, ConcurrencyManager> getThreadsToWaitOnAcquireSnapshot() {
return Map.copyOf(THREADS_TO_WAIT_ON_ACQUIRE);
}

/** Getter for {@link #THREADS_TO_WAIT_ON_ACQUIRE_NAME_OF_METHOD_CREATING_TRACE} */
public static Map<Thread, String> getThreadsToWaitOnAcquireMethodName() {
return new HashMap<>(THREADS_TO_WAIT_ON_ACQUIRE_NAME_OF_METHOD_CREATING_TRACE);
public static Map<Thread, String> getThreadsToWaitOnAcquireMethodNameSnapshot() {
return Map.copyOf(THREADS_TO_WAIT_ON_ACQUIRE_NAME_OF_METHOD_CREATING_TRACE);
}

/** Getter for {@link #THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK} */
public static Map<Thread, ConcurrencyManager> getThreadsToWaitOnAcquireReadLock() {
return THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK;
public static Map<Thread, ConcurrencyManager> getThreadsToWaitOnAcquireReadLockSnapshot() {
return Map.copyOf(THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK);
}

/** Getter for {@link #THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK_NAME_OF_METHOD_CREATING_TRACE} */
public static Map<Thread, String> getThreadsToWaitOnAcquireReadLockMethodName() {
return THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK_NAME_OF_METHOD_CREATING_TRACE;
public static Map<Thread, String> getThreadsToWaitOnAcquireReadLockMethodNameSnapshot() {
return Map.copyOf(THREADS_TO_WAIT_ON_ACQUIRE_READ_LOCK_NAME_OF_METHOD_CREATING_TRACE);
}

/** Getter for {@link #THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS} */
public static Set<Thread> getThreadsWaitingToReleaseDeferredLocks() {
return new HashSet<>(THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS);
public static Set<Thread> getThreadsWaitingToReleaseDeferredLocksSnapshot() {
return Set.copyOf(THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS);
}

/** Getter for {@link #THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS_BUILD_OBJECT_COMPLETE_GOES_NOWHERE} */
public static Map<Thread, String> getThreadsWaitingToReleaseDeferredLocksJustification() {
return new HashMap<>(THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS_BUILD_OBJECT_COMPLETE_GOES_NOWHERE);
public static Map<Thread, String> getThreadsWaitingToReleaseDeferredLocksJustificationSnapshot() {
return Map.copyOf(THREADS_WAITING_TO_RELEASE_DEFERRED_LOCKS_BUILD_OBJECT_COMPLETE_GOES_NOWHERE);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,16 +469,16 @@ public void dumpConcurrencyManagerInformationIfAppropriate() {
}

// do the "MassiveDump" logging if enough time has passed since the previous massive dump logging
Map<Thread, DeferredLockManager> deferredLockManagers = ConcurrencyManager.getDeferredLockManagers();
Map<Thread, ReadLockManager> readLockManagersOriginal = ConcurrencyManager.getReadLockManagers();
Map<Thread, ConcurrencyManager> mapThreadToWaitOnAcquireOriginal = ConcurrencyManager.getThreadsToWaitOnAcquire();
Map<Thread, String> mapThreadToWaitOnAcquireMethodNameOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireMethodName();
Map<Thread, ConcurrencyManager> mapThreadToWaitOnAcquireReadLockOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireReadLock();
Map<Thread, String> mapThreadToWaitOnAcquireReadLockMethodNameOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireReadLockMethodName();
Map<Thread, Set<ConcurrencyManager>> mapThreadToWaitOnAcquireInsideWriteLockManagerOriginal = WriteLockManager.getThreadToFailToAcquireCacheKeys();
Set<Thread> setThreadWaitingToReleaseDeferredLocksOriginal = ConcurrencyManager.getThreadsWaitingToReleaseDeferredLocks();
Map<Thread, String> mapThreadsThatAreCurrentlyWaitingToReleaseDeferredLocksJustificationClone = ConcurrencyManager.getThreadsWaitingToReleaseDeferredLocksJustification();
Map<Thread, Set<Object>> mapThreadToObjectIdWithWriteLockManagerChangesOriginal = WriteLockManager.getMapWriteLockManagerThreadToObjectIdsWithChangeSet();
Map<Thread, DeferredLockManager> deferredLockManagers = ConcurrencyManager.getDeferredLockManagersSnapshot();
Map<Thread, ReadLockManager> readLockManagersOriginal = ConcurrencyManager.getReadLockManagersSnapshot();
Map<Thread, ConcurrencyManager> mapThreadToWaitOnAcquireOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireSnapshot();
Map<Thread, String> mapThreadToWaitOnAcquireMethodNameOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireMethodNameSnapshot();
Map<Thread, ConcurrencyManager> mapThreadToWaitOnAcquireReadLockOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireReadLockSnapshot();
Map<Thread, String> mapThreadToWaitOnAcquireReadLockMethodNameOriginal = ConcurrencyManager.getThreadsToWaitOnAcquireReadLockMethodNameSnapshot();
Map<Thread, Set<ConcurrencyManager>> mapThreadToWaitOnAcquireInsideWriteLockManagerOriginal = WriteLockManager.getThreadToFailToAcquireCacheKeysSnapshot();
Set<Thread> setThreadWaitingToReleaseDeferredLocksOriginal = ConcurrencyManager.getThreadsWaitingToReleaseDeferredLocksSnapshot();
Map<Thread, String> mapThreadsThatAreCurrentlyWaitingToReleaseDeferredLocksJustificationClone = ConcurrencyManager.getThreadsWaitingToReleaseDeferredLocksJustificationSnapshot();
Map<Thread, Set<Object>> mapThreadToObjectIdWithWriteLockManagerChangesOriginal = WriteLockManager.getMapWriteLockManagerThreadToObjectIdsWithChangeSetSnapshot();
dumpConcurrencyManagerInformationStep01(
deferredLockManagers,
readLockManagersOriginal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static java.util.Collections.unmodifiableMap;

/**
* INTERNAL:
* <p>
Expand Down Expand Up @@ -657,13 +655,13 @@ protected CacheKey waitOnObjectLock(ClassDescriptor descriptor, Object primaryKe
// Helper data structures to have tracebility about object ids with change sets and cache keys we are sturggling to acquire

/** Getter for {@link #THREAD_TO_FAIL_TO_ACQUIRE_CACHE_KEYS} */
public static Map<Thread, Set<ConcurrencyManager>> getThreadToFailToAcquireCacheKeys() {
return unmodifiableMap(THREAD_TO_FAIL_TO_ACQUIRE_CACHE_KEYS);
public static Map<Thread, Set<ConcurrencyManager>> getThreadToFailToAcquireCacheKeysSnapshot() {
return Map.copyOf(THREAD_TO_FAIL_TO_ACQUIRE_CACHE_KEYS);
}

/** Getter for {@link #MAP_WRITE_LOCK_MANAGER_THREAD_TO_OBJECT_IDS_WITH_CHANGE_SET} */
public static Map<Thread, Set<Object>> getMapWriteLockManagerThreadToObjectIdsWithChangeSet() {
return unmodifiableMap(MAP_WRITE_LOCK_MANAGER_THREAD_TO_OBJECT_IDS_WITH_CHANGE_SET);
public static Map<Thread, Set<Object>> getMapWriteLockManagerThreadToObjectIdsWithChangeSetSnapshot() {
return Map.copyOf(MAP_WRITE_LOCK_MANAGER_THREAD_TO_OBJECT_IDS_WITH_CHANGE_SET);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -62,7 +62,7 @@ public class CacheKeyToThreadRelationships {

/**
* These are threads that have registered themselves as waiting for the cache key. See
* {@link org.eclipse.persistence.internal.helper.ConcurrencyManager#getThreadsToWaitOnAcquire()}
* {@link org.eclipse.persistence.internal.helper.ConcurrencyManager#getThreadsToWaitOnAcquireSnapshot()}
*
* (acquire lock for writing or as deferred - the cache key must be found with number of readers 0).
*/
Expand Down

0 comments on commit 83183b7

Please sign in to comment.