This is an automated email from the ASF dual-hosted git repository.

ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 9d725d97080 IGNITE-24683 Remove `PageLockListener` from non-test 
classes (#5328)
9d725d97080 is described below

commit 9d725d970800e6b230cab1ff4fc714edc216f074
Author: Ivan Bessonov <[email protected]>
AuthorDate: Mon Mar 3 11:37:21 2025 +0300

    IGNITE-24683 Remove `PageLockListener` from non-test classes (#5328)
---
 .../ignite/internal/util/OffheapReadWriteLock.java |   3 +
 .../tree/AbstractBplusTreePageMemoryTest.java      | 134 ++++++---------------
 .../tree/AbstractBplusTreeReusePageMemoryTest.java | 118 +-----------------
 .../tree/ItBplusTreeReplaceRemoveRaceTest.java     |   6 +-
 ...ItBplusTreeReuseListVolatilePageMemoryTest.java |  10 +-
 .../ItBplusTreeVolatilePageMemoryTest.java         |  10 +-
 .../ItBplusTreePersistentPageMemoryTest.java       |  10 +-
 ...BplusTreeReuseListPersistentPageMemoryTest.java |   8 +-
 .../pagememory/datastructure/DataStructure.java    |  33 ++---
 .../internal/pagememory/freelist/FreeListImpl.java |   4 -
 .../internal/pagememory/freelist/PagesList.java    |   5 +-
 .../pagememory/inmemory/VolatilePageMemory.java    |  16 +--
 .../ignite/internal/pagememory/tree/BplusTree.java |   9 +-
 .../internal/pagememory/util/PageHandler.java      | 131 ++------------------
 .../pagememory/util/PageLockListenerNoOp.java      |  75 ------------
 .../pagememory/freelist/FreeListImplTest.java      |   6 +-
 .../inmemory/VolatilePageMemoryNoLoadSelfTest.java |   4 +-
 .../replacement/AbstractPageReplacementTest.java   |   2 +-
 .../util/ListeningOffheapReadWriteLock.java        | 103 ++++++++++++++++
 .../internal/pagememory/util/PageLockListener.java |  42 +++----
 .../util/SequencedOffheapReadWriteLock.java        |   2 +-
 .../pagememory/PersistentPageMemoryDataRegion.java |   2 +-
 .../PersistentPageMemoryTableStorage.java          |   5 -
 .../pagememory/VolatilePageMemoryDataRegion.java   |  14 ++-
 .../pagememory/VolatilePageMemoryTableStorage.java |   4 -
 .../pagememory/index/hash/HashIndexTree.java       |  15 +--
 .../pagememory/index/meta/IndexMetaTree.java       |   5 +-
 .../pagememory/index/sorted/SortedIndexTree.java   |  18 +--
 .../storage/pagememory/mv/BlobStorage.java         |   7 +-
 .../storage/pagememory/mv/IndexStorageFactory.java |   6 -
 .../storage/pagememory/mv/VersionChainTree.java    |   4 -
 .../internal/storage/pagememory/mv/gc/GcQueue.java |   4 -
 .../pagememory/PersistentPageMemoryNoLoadTest.java |   2 +-
 .../storage/pagememory/mv/BlobStorageTest.java     |   7 +-
 34 files changed, 264 insertions(+), 560 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/OffheapReadWriteLock.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/OffheapReadWriteLock.java
index c632733b68e..f2cb3b50876 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/OffheapReadWriteLock.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/OffheapReadWriteLock.java
@@ -33,6 +33,9 @@ import org.jetbrains.annotations.Nullable;
  * </pre>
  */
 public class OffheapReadWriteLock {
+    /** Default concurrency level for the lock. */
+    public static final int DEFAULT_CONCURRENCY_LEVEL = 128;
+
     /**
      * Default empirical value for the spin count.
      *
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
index 87df854a65e..009bda5a003 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreePageMemoryTest.java
@@ -36,7 +36,6 @@ import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.runMultiT
 import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.runMultiThreadedAsync;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
 import static org.apache.ignite.internal.util.Constants.MiB;
-import static org.apache.ignite.internal.util.StringUtils.hexLong;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -95,12 +94,13 @@ import 
org.apache.ignite.internal.pagememory.tree.io.BplusInnerIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusLeafIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
+import 
org.apache.ignite.internal.pagememory.util.ListeningOffheapReadWriteLock;
 import org.apache.ignite.internal.pagememory.util.PageLockListener;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
 import org.apache.ignite.internal.util.Cursor;
 import org.apache.ignite.internal.util.IgniteRandom;
 import org.apache.ignite.internal.util.IgniteStripedLock;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -134,11 +134,11 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
 
     protected static final long MAX_MEMORY_SIZE = 64 * MiB;
 
-    /** Forces printing lock/unlock events on the test tree. */
-    private static boolean PRINT_LOCKS = false;
-
     protected static final Collection<Long> rmvdIds = 
ConcurrentHashMap.newKeySet();
 
+    /** The offset of the lock withing a page. This value might be different 
for different engines. */
+    protected static long lockOffset;
+
     @Nullable
     protected PageMemory pageMem;
 
@@ -2763,15 +2763,6 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
         return cnt;
     }
 
-    protected static void checkPageId(long pageId, long pageAddr) {
-        long actual = getPageId(pageAddr);
-
-        // Page ID must be 0L for newly allocated page, for reused page 
effective ID must remain the same.
-        if (actual != 0L && pageId != actual) {
-            throw new IllegalStateException("Page ID: " + hexLong(actual));
-        }
-    }
-
     private TestTree createTestTree(boolean canGetRow, AtomicLong globalRmvId) 
throws Exception {
         var tree = new TestTree(allocateMetaPage(), reuseList, canGetRow, 
pageMem, globalRmvId, true);
 
@@ -2823,7 +2814,6 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
                     null,
                     partitionId(metaPageId.pageId()),
                     pageMem,
-                    new TestPageLockListener(PageLockListenerNoOp.INSTANCE),
                     globalRmvId,
                     metaPageId.pageId(),
                     reuseList,
@@ -3094,6 +3084,10 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
         }
     }
 
+    protected OffheapReadWriteLock wrapLock(OffheapReadWriteLock delegate) {
+        return new ListeningOffheapReadWriteLock(delegate, new 
TestPageLockListener());
+    }
+
     /**
      * {@link PageLockListener} implementation for the test.
      */
@@ -3106,8 +3100,6 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
 
         static ConcurrentMap<Object, Map<Long, Long>> writeLocks = new 
ConcurrentHashMap<>();
 
-        private final PageLockListener delegate;
-
         static void clearStaticResources() {
             beforeReadLock.clear();
             readLocks.clear();
@@ -3116,117 +3108,70 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
             writeLocks.clear();
         }
 
-        /**
-         * Constructor.
-         *
-         * @param delegate Real implementation of page lock listener.
-         */
-        private TestPageLockListener(PageLockListener delegate) {
-            this.delegate = delegate;
+        private static long resolvePageId(long lockAddress) {
+            return getPageId(lockAddress - lockOffset);
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onBeforeReadLock(int cacheId, long pageId, long page) {
-            delegate.onBeforeReadLock(cacheId, pageId, page);
-
-            if (PRINT_LOCKS) {
-                println("  onBeforeReadLock: " + hexLong(pageId));
-            }
-
-            assertNull(beforeReadLock.put(threadId(), pageId));
+        public void onBeforeReadLock(long lockAddress) {
+            assertNull(beforeReadLock.put(threadId(), lockAddress));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onReadLock(int cacheId, long pageId, long page, long 
pageAddr) {
-            delegate.onReadLock(cacheId, pageId, page, pageAddr);
+        public void onReadLock(long lockAddress, boolean locked) {
+            if (locked) {
+                long actual = resolvePageId(lockAddress);
 
-            if (PRINT_LOCKS) {
-                println("  onReadLock: " + hexLong(pageId));
+                assertNull(locks(true).put(lockAddress, actual));
             }
 
-            if (pageAddr != 0L) {
-                long actual = getPageId(pageAddr);
-
-                checkPageId(pageId, pageAddr);
-
-                assertNull(locks(true).put(pageId, actual));
-            }
-
-            assertEquals(Long.valueOf(pageId), 
beforeReadLock.remove(threadId()));
+            assertEquals(Long.valueOf(lockAddress), 
beforeReadLock.remove(threadId()));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onReadUnlock(int cacheId, long pageId, long page, long 
pageAddr) {
-            delegate.onReadUnlock(cacheId, pageId, page, pageAddr);
-
-            if (PRINT_LOCKS) {
-                println("  onReadUnlock: " + hexLong(pageId));
-            }
-
-            checkPageId(pageId, pageAddr);
-
-            long actual = getPageId(pageAddr);
+        public void onReadUnlock(long lockAddress) {
+            long actual = resolvePageId(lockAddress);
 
-            assertEquals(Long.valueOf(actual), locks(true).remove(pageId));
+            assertEquals(Long.valueOf(actual), 
locks(true).remove(lockAddress));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onBeforeWriteLock(int cacheId, long pageId, long page) {
-            delegate.onBeforeWriteLock(cacheId, pageId, page);
-
-            if (PRINT_LOCKS) {
-                println("  onBeforeWriteLock: " + hexLong(pageId));
-            }
-
-            assertNull(beforeWriteLock.put(threadId(), pageId));
+        public void onBeforeWriteLock(long lockAddress) {
+            assertNull(beforeWriteLock.put(threadId(), lockAddress));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onWriteLock(int cacheId, long pageId, long page, long 
pageAddr) {
-            delegate.onWriteLock(cacheId, pageId, page, pageAddr);
+        public void onWriteLock(long lockAddress, boolean locked) {
+            if (locked) {
+                long actual = resolvePageId(lockAddress);
 
-            if (PRINT_LOCKS) {
-                println("  onWriteLock: " + hexLong(pageId));
+                // 0L for newly allocated page.
+                assertNull(locks(false).put(lockAddress, actual));
             }
 
-            if (pageAddr != 0L) {
-                checkPageId(pageId, pageAddr);
-
-                long actual = getPageId(pageAddr);
-
-                if (actual == 0L) {
-                    actual = pageId; // It is a newly allocated page.
-                }
-
-                assertNull(locks(false).put(pageId, actual));
-            }
-
-            assertEquals(Long.valueOf(pageId), 
beforeWriteLock.remove(threadId()));
+            assertEquals(Long.valueOf(lockAddress), 
beforeWriteLock.remove(threadId()));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void onWriteUnlock(int cacheId, long pageId, long page, long 
pageAddr) {
-            delegate.onWriteUnlock(cacheId, pageId, page, pageAddr);
-
-            if (PRINT_LOCKS) {
-                println("  onWriteUnlock: " + hexLong(pageId));
-            }
+        public void onWriteUnlock(long lockAddress) {
+            long actual = resolvePageId(lockAddress);
 
-            assertEquals(effectivePageId(pageId), 
effectivePageId(getPageId(pageAddr)));
+            long prevValue = locks(false).remove(lockAddress);
 
-            assertEquals(Long.valueOf(pageId), locks(false).remove(pageId));
+            if (prevValue != 0L) {
+                assertEquals(actual, prevValue);
+            }
         }
 
         /** {@inheritDoc} */
         @Override
         public void close() {
-            delegate.close();
         }
 
         private static Map<Long, Long> locks(boolean readLock) {
@@ -3265,15 +3210,6 @@ public abstract class AbstractBplusTreePageMemoryTest 
extends BaseIgniteAbstract
         System.out.println(msg);
     }
 
-    /**
-     * Alias for {@code System.out.print}.
-     *
-     * @param msg String to print.
-     */
-    protected static void print(@Nullable String msg) {
-        System.out.print(msg);
-    }
-
     /**
      * Output a message to the log.
      *
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreeReusePageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreeReusePageMemoryTest.java
index 48412463a82..15f004829fb 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreeReusePageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/AbstractBplusTreeReusePageMemoryTest.java
@@ -17,19 +17,11 @@
 
 package org.apache.ignite.internal.pagememory.tree;
 
-import static org.apache.ignite.internal.pagememory.io.PageIo.getPageId;
-import static 
org.apache.ignite.internal.pagememory.util.PageIdUtils.effectivePageId;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
 import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
 import org.apache.ignite.internal.pagememory.PageMemory;
 import org.apache.ignite.internal.pagememory.freelist.FreeListImpl;
 import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 
 /**
  * An abstract class for testing {@link BplusTree} with {@link ReuseList} 
using different implementations of {@link PageMemory}.
@@ -44,115 +36,15 @@ public abstract class AbstractBplusTreeReusePageMemoryTest 
extends AbstractBplus
             long rootId,
             boolean initNew
     ) throws IgniteInternalCheckedException {
-        return new TestReuseList(
+        return new FreeListImpl(
+                "test",
                 grpId,
                 partId,
                 pageMem,
-                new TestPageLockListener(),
                 rootId,
-                initNew
+                initNew,
+                null,
+                IoStatisticsHolderNoOp.INSTANCE
         );
     }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void assertNoLocks() {
-        super.assertNoLocks();
-
-        assertTrue(TestReuseList.checkNoLocks());
-    }
-
-    /**
-     * Test extension of {@link FreeListImpl}.
-     */
-    private static class TestReuseList extends FreeListImpl {
-        /**
-         * Constructor.
-         *
-         * @param grpId Group ID.
-         * @param partId Partition ID.
-         * @param pageMem Page memory.
-         * @param lockLsnr Page lock listener.
-         * @param metaPageId Metadata page ID.
-         * @param initNew {@code True} if new metadata should be initialized.
-         * @throws IgniteInternalCheckedException If failed.
-         */
-        TestReuseList(
-                int grpId,
-                int partId,
-                PageMemory pageMem,
-                PageLockListener lockLsnr,
-                long metaPageId,
-                boolean initNew
-        ) throws IgniteInternalCheckedException {
-            super("test", grpId, partId, pageMem, lockLsnr, metaPageId, 
initNew, null, IoStatisticsHolderNoOp.INSTANCE);
-        }
-
-        static boolean checkNoLocks() {
-            return TestPageLockListener.readLocks.get().isEmpty() && 
TestPageLockListener.writeLocks.get().isEmpty();
-        }
-    }
-
-    /**
-     * {@link PageLockListener} implementation for the test.
-     */
-    private static class TestPageLockListener implements PageLockListener {
-        private static final ThreadLocal<Set<Long>> readLocks = 
ThreadLocal.withInitial(HashSet::new);
-
-        private static final ThreadLocal<Set<Long>> writeLocks = 
ThreadLocal.withInitial(HashSet::new);
-
-        /** {@inheritDoc} */
-        @Override
-        public void onBeforeReadLock(int cacheId, long pageId, long page) {
-            // No-op.
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void onReadLock(int cacheId, long pageId, long page, long 
pageAddr) {
-            checkPageId(pageId, pageAddr);
-
-            assertTrue(readLocks.get().add(pageId));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void onReadUnlock(int cacheId, long pageId, long page, long 
pageAddr) {
-            checkPageId(pageId, pageAddr);
-
-            assertTrue(readLocks.get().remove(pageId));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void onBeforeWriteLock(int cacheId, long pageId, long page) {
-            // No-op.
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void onWriteLock(int cacheId, long pageId, long page, long 
pageAddr) {
-            if (pageAddr == 0L) {
-                return; // Failed to lock.
-            }
-
-            checkPageId(pageId, pageAddr);
-
-            assertTrue(writeLocks.get().add(pageId));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void onWriteUnlock(int cacheId, long pageId, long page, long 
pageAddr) {
-            assertEquals(effectivePageId(pageId), 
effectivePageId(getPageId(pageAddr)));
-
-            assertTrue(writeLocks.get().remove(pageId));
-        }
-
-        /** {@inheritDoc} */
-        @Override
-        public void close() {
-            // No-op.
-        }
-    }
 }
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
index 39493bdf221..974eb01aa2f 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/ItBplusTreeReplaceRemoveRaceTest.java
@@ -46,10 +46,10 @@ import 
org.apache.ignite.internal.pagememory.tree.io.BplusInnerIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusLeafIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.pagememory.util.PageUtils;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -103,7 +103,8 @@ public class ItBplusTreeReplaceRemoveRaceTest extends 
BaseIgniteAbstractTest {
         return new VolatilePageMemory(
                 (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(dataRegionCfg),
                 ioRegistry,
-                512
+                512,
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
     }
 
@@ -150,7 +151,6 @@ public class ItBplusTreeReplaceRemoveRaceTest extends 
BaseIgniteAbstractTest {
                     null,
                     partitionId(metaPageId.pageId()),
                     pageMem,
-                    PageLockListenerNoOp.INSTANCE,
                     new AtomicLong(),
                     metaPageId.pageId(),
                     null,
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeReuseListVolatilePageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeReuseListVolatilePageMemoryTest.java
index aee5824388e..71afc58d1d5 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeReuseListVolatilePageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeReuseListVolatilePageMemoryTest.java
@@ -28,6 +28,8 @@ import 
org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMe
 import org.apache.ignite.internal.pagememory.inmemory.VolatilePageMemory;
 import 
org.apache.ignite.internal.pagememory.tree.AbstractBplusTreeReusePageMemoryTest;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
@@ -45,6 +47,11 @@ public class ItBplusTreeReuseListVolatilePageMemoryTest 
extends AbstractBplusTre
     )
     private StorageProfileConfiguration storageProfileCfg;
 
+    @BeforeAll
+    static void initLockOffset() {
+        lockOffset = VolatilePageMemory.LOCK_OFFSET;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected PageMemory createPageMemory() {
@@ -55,7 +62,8 @@ public class ItBplusTreeReuseListVolatilePageMemoryTest 
extends AbstractBplusTre
         return new VolatilePageMemory(
                 (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(storageProfileCfg),
                 ioRegistry,
-                PAGE_SIZE
+                PAGE_SIZE,
+                wrapLock(new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL))
         );
     }
 
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeVolatilePageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeVolatilePageMemoryTest.java
index 2baf21b13f3..43ca6bb7350 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeVolatilePageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/inmemory/ItBplusTreeVolatilePageMemoryTest.java
@@ -30,7 +30,9 @@ import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import 
org.apache.ignite.internal.pagememory.tree.AbstractBplusTreePageMemoryTest;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
@@ -48,6 +50,11 @@ public class ItBplusTreeVolatilePageMemoryTest extends 
AbstractBplusTreePageMemo
     )
     private StorageProfileConfiguration storageProfileConfiguration;
 
+    @BeforeAll
+    static void initLockOffset() {
+        lockOffset = VolatilePageMemory.LOCK_OFFSET;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected PageMemory createPageMemory() {
@@ -58,7 +65,8 @@ public class ItBplusTreeVolatilePageMemoryTest extends 
AbstractBplusTreePageMemo
         return new VolatilePageMemory(
                 (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(storageProfileConfiguration),
                 ioRegistry,
-                PAGE_SIZE
+                PAGE_SIZE,
+                wrapLock(new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL))
         );
     }
 
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java
index 7052c148491..3e6d1792a21 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreePersistentPageMemoryTest.java
@@ -43,6 +43,7 @@ import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfigura
 import org.apache.ignite.internal.testframework.WithSystemProperty;
 import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -66,6 +67,11 @@ public class ItBplusTreePersistentPageMemoryTest extends 
AbstractBplusTreePageMe
 
     private OffheapReadWriteLock offheapReadWriteLock;
 
+    @BeforeAll
+    static void initLockOffset() {
+        lockOffset = PersistentPageMemory.PAGE_LOCK_OFFSET;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected PageMemory createPageMemory() {
@@ -75,7 +81,7 @@ public class ItBplusTreePersistentPageMemoryTest extends 
AbstractBplusTreePageMe
 
         offheapReadWriteLock = 
IgniteSystemProperties.getBoolean(USE_SEQUENCED_RW_LOCK)
                 ? new SequencedOffheapReadWriteLock()
-                : new OffheapReadWriteLock(128);
+                : new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL);
 
         return new PersistentPageMemory(
                 (PersistentPageMemoryProfileConfiguration) 
fixConfiguration(storageProfileCfg),
@@ -88,7 +94,7 @@ public class ItBplusTreePersistentPageMemoryTest extends 
AbstractBplusTreePageMe
                 mockCheckpointTimeoutLock(true),
                 () -> null,
                 PAGE_SIZE,
-                offheapReadWriteLock
+                wrapLock(offheapReadWriteLock)
         );
     }
 
diff --git 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java
 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java
index 7cd587131b3..467b716dcc7 100644
--- 
a/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java
+++ 
b/modules/page-memory/src/integrationTest/java/org/apache/ignite/internal/pagememory/tree/persistence/ItBplusTreeReuseListPersistentPageMemoryTest.java
@@ -35,6 +35,7 @@ import 
org.apache.ignite.internal.pagememory.persistence.TestPageReadWriteManage
 import 
org.apache.ignite.internal.pagememory.tree.AbstractBplusTreeReusePageMemoryTest;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
 import org.apache.ignite.internal.util.OffheapReadWriteLock;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
@@ -48,6 +49,11 @@ public class ItBplusTreeReuseListPersistentPageMemoryTest 
extends AbstractBplusT
     )
     private StorageProfileConfiguration dataRegionCfg;
 
+    @BeforeAll
+    static void initLockOffset() {
+        lockOffset = PersistentPageMemory.PAGE_LOCK_OFFSET;
+    }
+
     /** {@inheritDoc} */
     @Override
     protected PageMemory createPageMemory() throws Exception {
@@ -71,7 +77,7 @@ public class ItBplusTreeReuseListPersistentPageMemoryTest 
extends AbstractBplusT
                 mockCheckpointTimeoutLock(true),
                 () -> null,
                 PAGE_SIZE,
-                new OffheapReadWriteLock(128)
+                wrapLock(new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL))
         );
     }
 
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
index 88659f9c58e..be7e700a702 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
@@ -39,7 +39,6 @@ import org.apache.ignite.internal.pagememory.reuse.ReuseBag;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.util.PageHandler;
 import org.apache.ignite.internal.pagememory.util.PageIdUtils;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.util.StringUtils;
 import org.jetbrains.annotations.Nullable;
 
@@ -54,9 +53,6 @@ public abstract class DataStructure implements 
ManuallyCloseable {
     /** Structure name. */
     private final String name;
 
-    /** Page lock listener. */
-    private final PageLockListener lockLsnr;
-
     /** Group id. */
     protected final int grpId;
 
@@ -83,7 +79,6 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param defaultPageFlag Default flag value for allocated pages. One of 
{@link PageIdAllocator#FLAG_DATA} or {@link
      *      PageIdAllocator#FLAG_AUX}.
      */
@@ -93,7 +88,6 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             @Nullable String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             byte defaultPageFlag
     ) {
         assert !StringUtils.nullOrEmpty(structureNamePrefix);
@@ -105,7 +99,6 @@ public abstract class DataStructure implements 
ManuallyCloseable {
         this.grpName = grpName;
         this.partId = partId;
         this.pageMem = pageMem;
-        this.lockLsnr = lockLsnr;
         this.defaultPageFlag = defaultPageFlag;
     }
 
@@ -201,7 +194,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @return Page address or {@code 0} if failed to lock due to recycling.
      */
     protected final long tryWriteLock(long pageId, long page) {
-        return PageHandler.writeLock(pageMem, grpId, pageId, page, lockLsnr, 
true);
+        return pageMem.tryWriteLock(grpId, pageId, page);
     }
 
     /**
@@ -212,7 +205,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @return Page address.
      */
     protected final long writeLock(long pageId, long page) {
-        return PageHandler.writeLock(pageMem, grpId, pageId, page, lockLsnr, 
false);
+        return pageMem.writeLock(grpId, pageId, page);
     }
 
     /**
@@ -223,7 +216,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @return Page address.
      */
     protected final long readLock(long pageId, long page) {
-        return PageHandler.readLock(pageMem, grpId, pageId, page, lockLsnr);
+        return pageMem.readLock(grpId, pageId, page);
     }
 
     /**
@@ -234,7 +227,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @param pageAddr Page address.
      */
     protected final void readUnlock(long pageId, long page, long pageAddr) {
-        PageHandler.readUnlock(pageMem, grpId, pageId, page, pageAddr, 
lockLsnr);
+        pageMem.readUnlock(grpId, pageId, page);
     }
 
     /**
@@ -246,7 +239,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @param dirty Dirty flag.
      */
     protected final void writeUnlock(long pageId, long page, long pageAddr, 
boolean dirty) {
-        PageHandler.writeUnlock(pageMem, grpId, pageId, page, pageAddr, 
lockLsnr, dirty);
+        pageMem.writeUnlock(grpId, pageId, page, dirty);
     }
 
     /**
@@ -267,7 +260,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.writePage(pageMem, grpId, pageId, lockLsnr, h, 
null, null, intArg, lockFailed, statHolder);
+        return PageHandler.writePage(pageMem, grpId, pageId, h, null, null, 
intArg, lockFailed, statHolder);
     }
 
     /**
@@ -290,7 +283,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.writePage(pageMem, grpId, pageId, lockLsnr, h, 
null, arg, intArg, lockFailed, statHolder);
+        return PageHandler.writePage(pageMem, grpId, pageId, h, null, arg, 
intArg, lockFailed, statHolder);
     }
 
     /**
@@ -315,7 +308,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.writePage(pageMem, grpId, pageId, page, lockLsnr, 
h, null, arg, intArg, lockFailed, statHolder);
+        return PageHandler.writePage(pageMem, grpId, pageId, page, h, null, 
arg, intArg, lockFailed, statHolder);
     }
 
     /**
@@ -340,7 +333,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.writePage(pageMem, grpId, pageId, lockLsnr, h, 
init, arg, intArg, lockFailed, statHolder);
+        return PageHandler.writePage(pageMem, grpId, pageId, h, init, arg, 
intArg, lockFailed, statHolder);
     }
 
     /**
@@ -363,7 +356,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.readPage(pageMem, grpId, pageId, lockLsnr, h, arg, 
intArg, lockFailed, statHolder);
+        return PageHandler.readPage(pageMem, grpId, pageId, h, arg, intArg, 
lockFailed, statHolder);
     }
 
     /**
@@ -388,7 +381,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        return PageHandler.readPage(pageMem, grpId, pageId, page, lockLsnr, h, 
arg, intArg, lockFailed, statHolder);
+        return PageHandler.readPage(pageMem, grpId, pageId, page, h, arg, 
intArg, lockFailed, statHolder);
     }
 
     /**
@@ -399,7 +392,7 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      * @throws IgniteInternalCheckedException if failed.
      */
     protected final void init(long pageId, PageIo init) throws 
IgniteInternalCheckedException {
-        PageHandler.initPage(pageMem, grpId, pageId, init, lockLsnr, 
IoStatisticsHolderNoOp.INSTANCE);
+        PageHandler.initPage(pageMem, grpId, pageId, init, 
IoStatisticsHolderNoOp.INSTANCE);
     }
 
     /**
@@ -446,6 +439,6 @@ public abstract class DataStructure implements 
ManuallyCloseable {
      */
     @Override
     public void close() {
-        lockLsnr.close();
+        // No-op.
     }
 }
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
index f929c0a3eda..27bc6de0d70 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/FreeListImpl.java
@@ -43,7 +43,6 @@ import org.apache.ignite.internal.pagememory.reuse.ReuseBag;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.util.PageHandler;
 import org.apache.ignite.internal.pagememory.util.PageIdUtils;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -331,7 +330,6 @@ public class FreeListImpl extends PagesList implements 
FreeList, ReuseList {
      * @param grpId Group ID.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param metaPageId Metadata page ID.
      * @param initNew {@code True} if new metadata should be initialized.
      * @param pageListCacheLimit Page list cache limit.
@@ -342,7 +340,6 @@ public class FreeListImpl extends PagesList implements 
FreeList, ReuseList {
             int grpId,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             long metaPageId,
             boolean initNew,
             @Nullable AtomicLong pageListCacheLimit,
@@ -353,7 +350,6 @@ public class FreeListImpl extends PagesList implements 
FreeList, ReuseList {
                 grpId,
                 partId,
                 pageMem,
-                lockLsnr,
                 LOG,
                 BUCKETS,
                 metaPageId
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
index c473246aff9..392fa85676c 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
@@ -59,7 +59,6 @@ import 
org.apache.ignite.internal.pagememory.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagememory.reuse.ReuseBag;
 import org.apache.ignite.internal.pagememory.util.PageHandler;
 import org.apache.ignite.internal.pagememory.util.PageIdUtils;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.tostring.S;
 import org.jetbrains.annotations.Nullable;
 
@@ -189,7 +188,6 @@ public abstract class PagesList extends DataStructure {
      * @param grpId Group ID.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param log Logger.
      * @param buckets Number of buckets.
      * @param metaPageId Metadata page ID.
@@ -199,12 +197,11 @@ public abstract class PagesList extends DataStructure {
             int grpId,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             IgniteLogger log,
             int buckets,
             long metaPageId
     ) {
-        super(pageListNamePrefix, grpId, null, partId, pageMem, lockLsnr, 
FLAG_AUX);
+        super(pageListNamePrefix, grpId, null, partId, pageMem, FLAG_AUX);
 
         this.log = log;
         this.infoLogEnabled = log.isInfoEnabled();
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
index e1485dcbf58..0b83dcab1b9 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemory.java
@@ -28,7 +28,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.ignite.internal.lang.IgniteInternalException;
-import org.apache.ignite.internal.lang.IgniteSystemProperties;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
 import org.apache.ignite.internal.pagememory.PageMemory;
@@ -76,9 +75,6 @@ public class VolatilePageMemory implements PageMemory {
     /** Logger. */
     private static final IgniteLogger LOG = 
Loggers.forClass(VolatilePageMemory.class);
 
-    /** Ignite page memory concurrency level. */
-    private static final String IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL = 
"IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL";
-
     /** Marker bytes that signify beginning of used page in memory. */
     public static final long PAGE_MARKER = 0xBEEAAFDEADBEEF01L;
 
@@ -148,12 +144,6 @@ public class VolatilePageMemory implements PageMemory {
     /** Offheap read write lock instance. */
     private final OffheapReadWriteLock rwLock;
 
-    /** Concurrency level. */
-    private final int lockConcLvl = IgniteSystemProperties.getInteger(
-            IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL,
-            Integer.highestOneBit(Runtime.getRuntime().availableProcessors() * 
4)
-    );
-
     /** Total number of pages may be allocated for this instance. */
     private final int totalPages;
 
@@ -174,12 +164,14 @@ public class VolatilePageMemory implements PageMemory {
      * @param storageProfileConfiguration Storage profile configuration.
      * @param ioRegistry IO registry.
      * @param pageSize Page size in bytes.
+     * @param rwLock Read-write lock for pages.
      */
     public VolatilePageMemory(
             VolatilePageMemoryProfileConfiguration storageProfileConfiguration,
             PageIoRegistry ioRegistry,
             // TODO: IGNITE-17017 Move to common config
-            int pageSize
+            int pageSize,
+            OffheapReadWriteLock rwLock
     ) {
         this.ioRegistry = ioRegistry;
         this.trackAcquiredPages = false;
@@ -193,7 +185,7 @@ public class VolatilePageMemory implements PageMemory {
 
         totalPages = (int) (this.storageProfileView.maxSize() / sysPageSize);
 
-        rwLock = new OffheapReadWriteLock(lockConcLvl);
+        this.rwLock = rwLock;
     }
 
     @Override
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/tree/BplusTree.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/tree/BplusTree.java
index a3331eac97f..bc7da3ad373 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/tree/BplusTree.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/tree/BplusTree.java
@@ -69,7 +69,6 @@ import 
org.apache.ignite.internal.pagememory.tree.io.BplusLeafIo;
 import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
 import org.apache.ignite.internal.pagememory.util.GradualTask;
 import org.apache.ignite.internal.pagememory.util.PageHandler;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.storage.StorageException;
 import org.apache.ignite.internal.tostring.S;
 import org.apache.ignite.internal.util.Cursor;
@@ -919,7 +918,6 @@ public abstract class BplusTree<L, T extends L> extends 
DataStructure implements
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -934,7 +932,6 @@ public abstract class BplusTree<L, T extends L> extends 
DataStructure implements
             @Nullable String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
@@ -942,7 +939,7 @@ public abstract class BplusTree<L, T extends L> extends 
DataStructure implements
             IoVersions<? extends BplusLeafIo<L>> leafIos,
             IoVersions<? extends BplusMetaIo> metaIos
     ) {
-        this(treeNamePrefix, grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        this(treeNamePrefix, grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         setIos(innerIos, leafIos, metaIos);
     }
@@ -954,7 +951,6 @@ public abstract class BplusTree<L, T extends L> extends 
DataStructure implements
      * @param grpId Group ID.
      * @param grpName Group name.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -966,12 +962,11 @@ public abstract class BplusTree<L, T extends L> extends 
DataStructure implements
             @Nullable String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList
     ) {
-        super(treeNamePrefix, grpId, grpName, partId, pageMem, lockLsnr, 
FLAG_AUX);
+        super(treeNamePrefix, grpId, grpName, partId, pageMem, FLAG_AUX);
 
         // TODO: IGNITE-16350 Move to config.
         minFill = 0.0f; // Testing worst case when merge happens only on empty 
page.
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageHandler.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageHandler.java
index 5b622ae98b0..21b59f58369 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageHandler.java
+++ 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageHandler.java
@@ -88,7 +88,6 @@ public interface PageHandler<X, R> {
      * @param pageMem Page memory.
      * @param groupId Group ID.
      * @param pageId Page ID.
-     * @param lsnr Lock listener.
      * @param h Handler.
      * @param arg Argument.
      * @param intArg Argument of type {@code int}.
@@ -101,7 +100,6 @@ public interface PageHandler<X, R> {
             PageMemory pageMem,
             int groupId,
             long pageId,
-            PageLockListener lsnr,
             PageHandler<X, R> h,
             X arg,
             int intArg,
@@ -111,7 +109,7 @@ public interface PageHandler<X, R> {
         long page = pageMem.acquirePage(groupId, pageId, statHolder);
 
         try {
-            return readPage(pageMem, groupId, pageId, page, lsnr, h, arg, 
intArg, lockFailed, statHolder);
+            return readPage(pageMem, groupId, pageId, page, h, arg, intArg, 
lockFailed, statHolder);
         } finally {
             pageMem.releasePage(groupId, pageId, page);
         }
@@ -124,7 +122,6 @@ public interface PageHandler<X, R> {
      * @param groupId Group ID.
      * @param pageId Page ID.
      * @param page Page pointer.
-     * @param lsnr Lock listener.
      * @param h Handler.
      * @param arg Argument.
      * @param intArg Argument of type {@code int}.
@@ -138,7 +135,6 @@ public interface PageHandler<X, R> {
             int groupId,
             long pageId,
             long page,
-            PageLockListener lsnr,
             PageHandler<X, R> h,
             X arg,
             int intArg,
@@ -148,7 +144,7 @@ public interface PageHandler<X, R> {
         long pageAddr = 0L;
 
         try {
-            if ((pageAddr = readLock(pageMem, groupId, pageId, page, lsnr)) == 
0L) {
+            if ((pageAddr = pageMem.readLock(groupId, pageId, page)) == 0L) {
                 return lockFailed;
             }
 
@@ -157,60 +153,11 @@ public interface PageHandler<X, R> {
             return h.run(groupId, pageId, page, pageAddr, io, arg, intArg, 
statHolder);
         } finally {
             if (pageAddr != 0L) {
-                readUnlock(pageMem, groupId, pageId, page, pageAddr, lsnr);
+                pageMem.readUnlock(groupId, pageId, page);
             }
         }
     }
 
-    /**
-     * Acquires the read lock on the page.
-     *
-     * @param pageMem Page memory.
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param lsnr Lock listener.
-     * @return Page address or {@code 0} if acquiring failed.
-     */
-    static long readLock(
-            PageMemory pageMem,
-            int groupId,
-            long pageId,
-            long page,
-            PageLockListener lsnr
-    ) {
-        lsnr.onBeforeReadLock(groupId, pageId, page);
-
-        long pageAddr = pageMem.readLock(groupId, pageId, page);
-
-        lsnr.onReadLock(groupId, pageId, page, pageAddr);
-
-        return pageAddr;
-    }
-
-    /**
-     * Releases acquired read lock.
-     *
-     * @param pageMem Page memory.
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
-     * @param lsnr Lock listener.
-     */
-    static void readUnlock(
-            PageMemory pageMem,
-            int groupId,
-            long pageId,
-            long page,
-            long pageAddr,
-            PageLockListener lsnr
-    ) {
-        lsnr.onReadUnlock(groupId, pageId, page, pageAddr);
-
-        pageMem.readUnlock(groupId, pageId, page);
-    }
-
     /**
      * Initializes a new page.
      *
@@ -218,7 +165,6 @@ public interface PageHandler<X, R> {
      * @param groupId Group ID.
      * @param pageId Page ID.
      * @param init IO for new page initialization.
-     * @param lsnr Lock listener.
      * @param statHolder Statistics holder to track IO operations.
      * @throws IgniteInternalCheckedException If failed.
      * @see PageIo#initNewPage(long, long, int)
@@ -228,15 +174,13 @@ public interface PageHandler<X, R> {
             int groupId,
             long pageId,
             PageIo init,
-            PageLockListener lsnr,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
         Boolean res = writePage(
                 pageMem,
                 groupId,
                 pageId,
-                lsnr,
-                PageHandler.NO_OP,
+                NO_OP,
                 init,
                 null,
                 0,
@@ -253,7 +197,6 @@ public interface PageHandler<X, R> {
      * @param pageMem Page memory.
      * @param groupId Group ID.
      * @param pageId Page ID.
-     * @param lsnr Lock listener.
      * @param h Handler.
      * @param init IO for new page initialization or {@code null} if it is an 
existing page.
      * @param arg Argument.
@@ -268,7 +211,6 @@ public interface PageHandler<X, R> {
             PageMemory pageMem,
             int groupId,
             final long pageId,
-            PageLockListener lsnr,
             PageHandler<X, R> h,
             @Nullable PageIo init,
             X arg,
@@ -279,7 +221,7 @@ public interface PageHandler<X, R> {
         boolean releaseAfterWrite = true;
         long page = pageMem.acquirePage(groupId, pageId, statHolder);
         try {
-            long pageAddr = writeLock(pageMem, groupId, pageId, page, lsnr, 
false);
+            long pageAddr = pageMem.writeLock(groupId, pageId, page);
 
             if (pageAddr == 0L) {
                 return lockFailed;
@@ -304,7 +246,7 @@ public interface PageHandler<X, R> {
                 assert PageIo.getCrc(pageAddr) == 0;
 
                 if (releaseAfterWrite = h.releaseAfterWrite(groupId, pageId, 
page, pageAddr, arg, intArg)) {
-                    writeUnlock(pageMem, groupId, pageId, page, pageAddr, 
lsnr, ok);
+                    pageMem.writeUnlock(groupId, pageId, page, ok);
                 }
             }
         } finally {
@@ -321,7 +263,6 @@ public interface PageHandler<X, R> {
      * @param groupId Group ID.
      * @param pageId Page ID.
      * @param page Page pointer.
-     * @param lsnr Lock listener.
      * @param h Handler.
      * @param init IO for new page initialization or {@code null} if it is an 
existing page.
      * @param arg Argument.
@@ -336,7 +277,6 @@ public interface PageHandler<X, R> {
             int groupId,
             long pageId,
             long page,
-            PageLockListener lsnr,
             PageHandler<X, R> h,
             PageIo init,
             X arg,
@@ -344,7 +284,7 @@ public interface PageHandler<X, R> {
             R lockFailed,
             IoStatisticsHolder statHolder
     ) throws IgniteInternalCheckedException {
-        long pageAddr = writeLock(pageMem, groupId, pageId, page, lsnr, false);
+        long pageAddr = pageMem.writeLock(groupId, pageId, page);
 
         if (pageAddr == 0L) {
             return lockFailed;
@@ -369,64 +309,11 @@ public interface PageHandler<X, R> {
             assert PageIo.getCrc(pageAddr) == 0;
 
             if (h.releaseAfterWrite(groupId, pageId, page, pageAddr, arg, 
intArg)) {
-                writeUnlock(pageMem, groupId, pageId, page, pageAddr, lsnr, 
ok);
+                pageMem.writeUnlock(groupId, pageId, page, ok);
             }
         }
     }
 
-    /**
-     * Acquires the write lock on the page.
-     *
-     * @param pageMem Page memory.
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param lsnr Lock listener.
-     * @param tryLock Only try to lock without waiting.
-     * @return Page address or {@code 0} if failed to lock due to recycling.
-     */
-    static long writeLock(
-            PageMemory pageMem,
-            int groupId,
-            long pageId,
-            long page,
-            PageLockListener lsnr,
-            boolean tryLock
-    ) {
-        lsnr.onBeforeWriteLock(groupId, pageId, page);
-
-        long pageAddr = tryLock ? pageMem.tryWriteLock(groupId, pageId, page) 
: pageMem.writeLock(groupId, pageId, page);
-
-        lsnr.onWriteLock(groupId, pageId, page, pageAddr);
-
-        return pageAddr;
-    }
-
-    /**
-     * Releases acquired write lock.
-     *
-     * @param pageMem Page memory.
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
-     * @param lsnr Lock listener.
-     * @param dirty Page is dirty.
-     */
-    static void writeUnlock(
-            PageMemory pageMem,
-            int groupId,
-            long pageId,
-            long page,
-            long pageAddr,
-            PageLockListener lsnr,
-            boolean dirty
-    ) {
-        lsnr.onWriteUnlock(groupId, pageId, page, pageAddr);
-
-        pageMem.writeUnlock(groupId, pageId, page, dirty);
-    }
-
     /**
      * Invokes {@link PageIo#initNewPage(long, long, int)} and does additional 
checks.
      */
@@ -436,7 +323,7 @@ public interface PageHandler<X, R> {
             long pageId,
             long pageAddr,
             PageIo init
-    ) throws IgniteInternalCheckedException {
+    ) {
         assert PageIo.getCrc(pageAddr) == 0;
 
         init.initNewPage(pageAddr, pageId, pageMem.realPageSize(groupId));
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListenerNoOp.java
 
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListenerNoOp.java
deleted file mode 100644
index 06db378f370..00000000000
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListenerNoOp.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.pagememory.util;
-
-/**
- * {@link PageLockListener} implementation that does nothing.
- */
-public class PageLockListenerNoOp implements PageLockListener {
-    /** Instance. */
-    public static final PageLockListenerNoOp INSTANCE = new 
PageLockListenerNoOp();
-
-    /**
-     * Private constructor.
-     */
-    private PageLockListenerNoOp() {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onBeforeWriteLock(int groupId, long pageId, long page) {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onWriteLock(int groupId, long pageId, long page, long 
pageAddr) {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onWriteUnlock(int groupId, long pageId, long page, long 
pageAddr) {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onBeforeReadLock(int groupId, long pageId, long page) {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onReadLock(int groupId, long pageId, long page, long pageAddr) 
{
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void onReadUnlock(int groupId, long pageId, long page, long 
pageAddr) {
-        // No-op.
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void close() {
-        // No-op.
-    }
-}
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
index 4bc1806c739..b7dafa76284 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/FreeListImplTest.java
@@ -50,9 +50,9 @@ import 
org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMe
 import org.apache.ignite.internal.pagememory.inmemory.VolatilePageMemory;
 import org.apache.ignite.internal.pagememory.io.DataPageIo;
 import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolderNoOp;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -147,7 +147,6 @@ public class FreeListImplTest extends 
BaseIgniteAbstractTest {
                 0,
                 1,
                 pageMemory,
-                PageLockListenerNoOp.INSTANCE,
                 metaPageId,
                 true,
                 null,
@@ -178,7 +177,8 @@ public class FreeListImplTest extends 
BaseIgniteAbstractTest {
         return new VolatilePageMemory(
                 (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(storageProfileCfg),
                 ioRegistry,
-                pageSize
+                pageSize,
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
     }
 
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemoryNoLoadSelfTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemoryNoLoadSelfTest.java
index 341ff6f34ce..3e71bf995cd 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemoryNoLoadSelfTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/inmemory/VolatilePageMemoryNoLoadSelfTest.java
@@ -26,6 +26,7 @@ import 
org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMe
 import 
org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMemoryProfileConfigurationSchema;
 import org.apache.ignite.internal.pagememory.io.PageIoRegistry;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
@@ -53,7 +54,8 @@ public class VolatilePageMemoryNoLoadSelfTest extends 
AbstractPageMemoryNoLoadSe
         return new VolatilePageMemory(
                 (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(storageProfileCfg),
                 ioRegistry,
-                PAGE_SIZE
+                PAGE_SIZE,
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
     }
 }
diff --git 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/AbstractPageReplacementTest.java
 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/AbstractPageReplacementTest.java
index 034d85d494c..fb97478d408 100644
--- 
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/AbstractPageReplacementTest.java
+++ 
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/persistence/replacement/AbstractPageReplacementTest.java
@@ -166,7 +166,7 @@ public abstract class AbstractPageReplacementTest extends 
IgniteAbstractTest {
                 checkpointManager.checkpointTimeoutLock(),
                 () -> null,
                 PAGE_SIZE,
-                new OffheapReadWriteLock(128)
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
 
         dataRegionList.add(() -> pageMemory);
diff --git 
a/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/ListeningOffheapReadWriteLock.java
 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/ListeningOffheapReadWriteLock.java
new file mode 100644
index 00000000000..ceeeb6a44d8
--- /dev/null
+++ 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/ListeningOffheapReadWriteLock.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.pagememory.util;
+
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Adds a {@link PageLockListener} to an {@link OffheapReadWriteLock}.
+ */
+public class ListeningOffheapReadWriteLock extends OffheapReadWriteLock {
+    private final OffheapReadWriteLock delegate;
+    private final PageLockListener listener;
+
+    /**
+     * Constructor.
+     *
+     * @param delegate Delegate.
+     * @param listener Listener.
+     */
+    public ListeningOffheapReadWriteLock(OffheapReadWriteLock delegate, 
PageLockListener listener) {
+        super(1);
+        this.delegate = delegate;
+        this.listener = listener;
+    }
+
+    @Override
+    public boolean readLock(long lock, int tag) {
+        listener.onBeforeReadLock(lock);
+
+        boolean locked = delegate.readLock(lock, tag);
+
+        listener.onReadLock(lock, locked);
+
+        return locked;
+    }
+
+    @Override
+    public void readUnlock(long lock) {
+        listener.onReadUnlock(lock);
+
+        delegate.readUnlock(lock);
+    }
+
+    @Override
+    public boolean tryWriteLock(long lock, int tag) {
+        listener.onBeforeWriteLock(lock);
+
+        boolean locked = delegate.tryWriteLock(lock, tag);
+
+        listener.onWriteLock(lock, locked);
+
+        return locked;
+    }
+
+    @Override
+    public boolean writeLock(long lock, int tag) {
+        listener.onBeforeWriteLock(lock);
+
+        boolean locked = delegate.writeLock(lock, tag);
+
+        listener.onWriteLock(lock, locked);
+
+        return locked;
+    }
+
+    @Override
+    public boolean isWriteLocked(long lock) {
+        return delegate.isWriteLocked(lock);
+    }
+
+    @Override
+    public boolean isReadLocked(long lock) {
+        return delegate.isReadLocked(lock);
+    }
+
+    @Override
+    public void writeUnlock(long lock, int tag) {
+        listener.onWriteUnlock(lock);
+
+        delegate.writeUnlock(lock, tag);
+    }
+
+    @Override
+    public @Nullable Boolean upgradeToWriteLock(long lock, int tag) {
+        return delegate.upgradeToWriteLock(lock, tag);
+    }
+}
diff --git 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
similarity index 59%
rename from 
modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
rename to 
modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
index a9c73e0ad61..864bfdc858d 100644
--- 
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
+++ 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/PageLockListener.java
@@ -27,60 +27,46 @@ public interface PageLockListener extends ManuallyCloseable 
{
     /**
      * Callback that's called before write lock acquiring.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
+     * @param lockAddress Lock pointer.
      */
-    void onBeforeWriteLock(int groupId, long pageId, long page);
+    void onBeforeWriteLock(long lockAddress);
 
     /**
      * Callback that's called after lock acquiring.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
+     * @param lockAddress Lock pointer.
+     * @param locked {@code true} if lock is locked.
      */
-    void onWriteLock(int groupId, long pageId, long page, long pageAddr);
+    void onWriteLock(long lockAddress, boolean locked);
 
     /**
      * Callback that's called before write lock releasing.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
+     * @param lockAddress Lock pointer.
      */
-    void onWriteUnlock(int groupId, long pageId, long page, long pageAddr);
+    void onWriteUnlock(long lockAddress);
 
     /**
      * Callback that's called before read lock acquiring.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
+     * @param lockAddress Lock pointer.
      */
-    void onBeforeReadLock(int groupId, long pageId, long page);
+    void onBeforeReadLock(long lockAddress);
 
     /**
      * Callback that's called after read lock acquiring.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
+     * @param lockAddress Lock pointer.
+     * @param locked {@code true} if lock is locked.
      */
-    void onReadLock(int groupId, long pageId, long page, long pageAddr);
+    void onReadLock(long lockAddress, boolean locked);
 
     /**
      * Callback that's called before read lock releasing.
      *
-     * @param groupId Group ID.
-     * @param pageId Page ID.
-     * @param page Page pointer.
-     * @param pageAddr Page address.
+     * @param lockAddress Lock pointer.
      */
-    void onReadUnlock(int groupId, long pageId, long page, long pageAddr);
+    void onReadUnlock(long lockAddress);
 
     /** {@inheritDoc} */
     @Override
diff --git 
a/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/SequencedOffheapReadWriteLock.java
 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/SequencedOffheapReadWriteLock.java
index 96ff0d0304a..25b705b853b 100644
--- 
a/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/SequencedOffheapReadWriteLock.java
+++ 
b/modules/page-memory/src/testFixtures/java/org/apache/ignite/internal/pagememory/util/SequencedOffheapReadWriteLock.java
@@ -43,7 +43,7 @@ public class SequencedOffheapReadWriteLock extends 
OffheapReadWriteLock {
      * Constructor.
      */
     public SequencedOffheapReadWriteLock() {
-        super(128);
+        super(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL);
     }
 
     /**
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
index 7ea510aa788..1fd0d2bda76 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryDataRegion.java
@@ -115,7 +115,7 @@ class PersistentPageMemoryDataRegion implements 
DataRegion<PersistentPageMemory>
                 checkpointManager.checkpointTimeoutLock(),
                 currentCheckpointProgress,
                 pageSize,
-                new OffheapReadWriteLock(128)
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
 
         pageMemory.start();
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
index 23d046ad473..f1415bcdf81 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryTableStorage.java
@@ -37,7 +37,6 @@ import 
org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointPr
 import 
org.apache.ignite.internal.pagememory.persistence.checkpoint.CheckpointTimeoutLock;
 import org.apache.ignite.internal.pagememory.persistence.store.FilePageStore;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.storage.StorageException;
 import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
 import org.apache.ignite.internal.storage.index.StorageIndexDescriptorSupplier;
@@ -170,7 +169,6 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
                     getTableId(),
                     partId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     meta.freeListRootPageId(),
                     initNew,
                     dataRegion.pageListCacheLimit(),
@@ -212,7 +210,6 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
                     Integer.toString(getTableId()),
                     partId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     meta.versionChainTreeRootPageId(),
                     reuseList,
@@ -254,7 +251,6 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
                     Integer.toString(getTableId()),
                     partitionId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     meta.indexTreeMetaPageId(),
                     reuseList,
@@ -296,7 +292,6 @@ public class PersistentPageMemoryTableStorage extends 
AbstractPageMemoryTableSto
                     Integer.toString(getTableId()),
                     partitionId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     meta.gcQueueMetaPageId(),
                     reuseList,
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
index 11056f01ff7..f28a98a3bf2 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryDataRegion.java
@@ -21,6 +21,7 @@ import static 
org.apache.ignite.internal.pagememory.PageIdAllocator.FLAG_AUX;
 import static org.apache.ignite.internal.util.IgniteUtils.closeAllManually;
 
 import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
+import org.apache.ignite.internal.lang.IgniteSystemProperties;
 import org.apache.ignite.internal.pagememory.DataRegion;
 import org.apache.ignite.internal.pagememory.PageMemory;
 import 
org.apache.ignite.internal.pagememory.configuration.schema.VolatilePageMemoryProfileConfiguration;
@@ -29,13 +30,16 @@ import 
org.apache.ignite.internal.pagememory.inmemory.VolatilePageMemory;
 import org.apache.ignite.internal.pagememory.io.PageIoRegistry;
 import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolderNoOp;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.storage.StorageException;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 
 /**
  * Implementation of {@link DataRegion} for in-memory case.
  */
 public class VolatilePageMemoryDataRegion implements 
DataRegion<VolatilePageMemory> {
+    /** Ignite page memory concurrency level. */
+    private static final String IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL = 
"IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL";
+
     private static final int FREE_LIST_GROUP_ID = 0;
 
     private static final int FREE_LIST_PARTITION_ID = 0;
@@ -72,7 +76,12 @@ public class VolatilePageMemoryDataRegion implements 
DataRegion<VolatilePageMemo
      * Starts the in-memory data region.
      */
     public void start() {
-        VolatilePageMemory pageMemory = new VolatilePageMemory(cfg, 
ioRegistry, pageSize);
+        int lockConcLvl = IgniteSystemProperties.getInteger(
+                IGNITE_OFFHEAP_LOCK_CONCURRENCY_LEVEL,
+                
Integer.highestOneBit(Runtime.getRuntime().availableProcessors() * 4)
+        );
+
+        var pageMemory = new VolatilePageMemory(cfg, ioRegistry, pageSize, new 
OffheapReadWriteLock(lockConcLvl));
 
         pageMemory.start();
 
@@ -93,7 +102,6 @@ public class VolatilePageMemoryDataRegion implements 
DataRegion<VolatilePageMemo
                 FREE_LIST_GROUP_ID,
                 FREE_LIST_PARTITION_ID,
                 pageMemory,
-                PageLockListenerNoOp.INSTANCE,
                 metaPageId,
                 true,
                 // Because in memory.
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
index 22185073df7..8cbe4ba9520 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/VolatilePageMemoryTableStorage.java
@@ -25,7 +25,6 @@ import java.util.concurrent.ExecutorService;
 import org.apache.ignite.internal.lang.IgniteInternalCheckedException;
 import org.apache.ignite.internal.logger.IgniteLogger;
 import org.apache.ignite.internal.logger.Loggers;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.storage.StorageException;
 import org.apache.ignite.internal.storage.engine.StorageTableDescriptor;
 import org.apache.ignite.internal.storage.index.StorageIndexDescriptorSupplier;
@@ -107,7 +106,6 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
                     Integer.toString(getTableId()),
                     partitionId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     metaPageId,
                     dataRegion.reuseList(),
@@ -127,7 +125,6 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
                     Integer.toString(getTableId()),
                     partitionId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     metaPageId,
                     dataRegion.reuseList(),
@@ -163,7 +160,6 @@ public class VolatilePageMemoryTableStorage extends 
AbstractPageMemoryTableStora
                     Integer.toString(getTableId()),
                     partId,
                     dataRegion.pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     engine.generateGlobalRemoveId(),
                     metaPageId,
                     dataRegion.reuseList(),
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
index aff2c71c78d..890668f7e5f 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
@@ -27,7 +27,6 @@ import 
org.apache.ignite.internal.pagememory.datapage.DataPageReader;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.storage.index.StorageHashIndexDescriptor;
 import 
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeInnerIo;
 import 
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeIo;
@@ -52,7 +51,6 @@ public class HashIndexTree extends BplusTree<HashIndexRowKey, 
HashIndexRow> {
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -64,12 +62,11 @@ public class HashIndexTree extends 
BplusTree<HashIndexRowKey, HashIndexRow> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList
     ) throws IgniteInternalCheckedException {
-        super("HashIndexTree", grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        super("HashIndexTree", grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         this.inlineSize = readInlineSizeFromMetaIo();
         this.dataPageReader = new DataPageReader(pageMem, grpId, 
statisticsHolder());
@@ -84,7 +81,6 @@ public class HashIndexTree extends BplusTree<HashIndexRowKey, 
HashIndexRow> {
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -97,13 +93,12 @@ public class HashIndexTree extends 
BplusTree<HashIndexRowKey, HashIndexRow> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             StorageHashIndexDescriptor indexDescriptor
     ) throws IgniteInternalCheckedException {
-        super("HashIndexTree", grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        super("HashIndexTree", grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         this.inlineSize = binaryTupleInlineSize(pageSize(), 
ITEM_SIZE_WITHOUT_COLUMNS, indexDescriptor);
         this.dataPageReader = new DataPageReader(pageMem, grpId, 
statisticsHolder());
@@ -131,13 +126,12 @@ public class HashIndexTree extends 
BplusTree<HashIndexRowKey, HashIndexRow> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             StorageHashIndexDescriptor indexDescriptor
     ) throws IgniteInternalCheckedException {
-        return new HashIndexTree(grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList, indexDescriptor);
+        return new HashIndexTree(grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList, indexDescriptor);
     }
 
     /**
@@ -148,12 +142,11 @@ public class HashIndexTree extends 
BplusTree<HashIndexRowKey, HashIndexRow> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList
     ) throws IgniteInternalCheckedException {
-        return new HashIndexTree(grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        return new HashIndexTree(grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
     }
 
     /**
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
index fb10c0ed1f2..63f9e018dcf 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
@@ -23,7 +23,6 @@ import org.apache.ignite.internal.pagememory.PageMemory;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import 
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaInnerIo;
 import org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaIo;
 import 
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaLeafIo;
@@ -41,7 +40,6 @@ public class IndexMetaTree extends BplusTree<IndexMetaKey, 
IndexMeta> {
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -55,13 +53,12 @@ public class IndexMetaTree extends BplusTree<IndexMetaKey, 
IndexMeta> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             boolean initNew
     ) throws IgniteInternalCheckedException {
-        super("IndexMetaTree", grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        super("IndexMetaTree", grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         setIos(IndexMetaInnerIo.VERSIONS, IndexMetaLeafIo.VERSIONS, 
IndexMetaTreeMetaIo.VERSIONS);
 
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/sorted/SortedIndexTree.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/sorted/SortedIndexTree.java
index c10ccf73c9e..c0c9d264141 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/sorted/SortedIndexTree.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/sorted/SortedIndexTree.java
@@ -27,7 +27,6 @@ import 
org.apache.ignite.internal.pagememory.datapage.DataPageReader;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.schema.BinaryTuple;
 import org.apache.ignite.internal.schema.BinaryTupleComparator;
 import org.apache.ignite.internal.storage.index.StorageSortedIndexDescriptor;
@@ -63,7 +62,6 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -78,14 +76,13 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             StorageSortedIndexDescriptor indexDescriptor,
             boolean initNew
     ) throws IgniteInternalCheckedException {
-        super("SortedIndexTree", grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        super("SortedIndexTree", grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         this.inlineSize = initNew
                 ? binaryTupleInlineSize(pageSize(), ITEM_SIZE_WITHOUT_COLUMNS, 
indexDescriptor)
@@ -103,7 +100,6 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
      * @param grpName Group name.
      * @param partId Partition ID.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -115,12 +111,11 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList
     ) throws IgniteInternalCheckedException {
-        super("SortedIndexTree", grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        super("SortedIndexTree", grpId, grpName, partId, pageMem, globalRmvId, 
metaPageId, reuseList);
 
         this.inlineSize = readInlineSizeFromMetaIo();
         this.dataPageReader = new DataPageReader(pageMem, grpId, 
statisticsHolder());
@@ -137,13 +132,12 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             StorageSortedIndexDescriptor indexDescriptor
     ) throws IgniteInternalCheckedException {
-        return new SortedIndexTree(grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList, indexDescriptor, true);
+        return new SortedIndexTree(grpId, grpName, partId, pageMem, 
globalRmvId, metaPageId, reuseList, indexDescriptor, true);
     }
 
     /**
@@ -154,13 +148,12 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
             @Nullable String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
             StorageSortedIndexDescriptor indexDescriptor
     ) throws IgniteInternalCheckedException {
-        return new SortedIndexTree(grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList, indexDescriptor, false);
+        return new SortedIndexTree(grpId, grpName, partId, pageMem, 
globalRmvId, metaPageId, reuseList, indexDescriptor, false);
     }
 
     /**
@@ -171,12 +164,11 @@ public class SortedIndexTree extends 
BplusTree<SortedIndexRowKey, SortedIndexRow
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList
     ) throws IgniteInternalCheckedException {
-        return new SortedIndexTree(grpId, grpName, partId, pageMem, lockLsnr, 
globalRmvId, metaPageId, reuseList);
+        return new SortedIndexTree(grpId, grpName, partId, pageMem, 
globalRmvId, metaPageId, reuseList);
     }
 
     private void init(boolean initNew) throws IgniteInternalCheckedException {
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorage.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorage.java
index b5f30da7b39..2ffc7fcc32c 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorage.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorage.java
@@ -29,7 +29,6 @@ import 
org.apache.ignite.internal.pagememory.reuse.LongListReuseBag;
 import org.apache.ignite.internal.pagememory.reuse.ReuseBag;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.util.PageHandler;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.storage.pagememory.mv.io.BlobFragmentIo;
 import org.jetbrains.annotations.Nullable;
 
@@ -56,7 +55,7 @@ public class BlobStorage extends DataStructure {
      * Creates a new instance.
      */
     public BlobStorage(ReuseList reuseList, PageMemory pageMemory, int 
groupId, int partitionId, IoStatisticsHolder statisticsHolder) {
-        super("BlobStorage", groupId, null, partitionId, pageMemory, 
PageLockListenerNoOp.INSTANCE, PageIdAllocator.FLAG_AUX);
+        super("BlobStorage", groupId, null, partitionId, pageMemory, 
PageIdAllocator.FLAG_AUX);
 
         super.reuseList = reuseList;
         this.statisticsHolder = statisticsHolder;
@@ -79,7 +78,6 @@ public class BlobStorage extends DataStructure {
                     pageMem,
                     grpId,
                     pageId,
-                    PageLockListenerNoOp.INSTANCE,
                     readFragment,
                     readState,
                     0,
@@ -132,7 +130,6 @@ public class BlobStorage extends DataStructure {
                     pageMem,
                     grpId,
                     state.pageId,
-                    PageLockListenerNoOp.INSTANCE,
                     writeFragment,
                     null,
                     state,
@@ -175,7 +172,7 @@ public class BlobStorage extends DataStructure {
         long pageId = startingPageId;
 
         while (pageId != NO_PAGE_ID) {
-            Long nextPageId = PageHandler.writePage(pageMem, grpId, pageId, 
PageLockListenerNoOp.INSTANCE,
+            Long nextPageId = PageHandler.writePage(pageMem, grpId, pageId,
                     recycleAndAddToReuseBag, null, reuseBag, 0, pageId, 
IoStatisticsHolderNoOp.INSTANCE);
 
             assert nextPageId != pageId : pageId;
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
index ce7b9bb09f1..56293ee654d 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/IndexStorageFactory.java
@@ -24,7 +24,6 @@ import 
org.apache.ignite.internal.lang.IgniteInternalCheckedException;
 import org.apache.ignite.internal.pagememory.PageIdAllocator;
 import org.apache.ignite.internal.pagememory.PageMemory;
 import org.apache.ignite.internal.pagememory.freelist.FreeListImpl;
-import org.apache.ignite.internal.pagememory.util.PageLockListenerNoOp;
 import org.apache.ignite.internal.storage.StorageException;
 import org.apache.ignite.internal.storage.index.StorageHashIndexDescriptor;
 import org.apache.ignite.internal.storage.index.StorageIndexDescriptor;
@@ -130,7 +129,6 @@ class IndexStorageFactory {
                         Integer.toString(tableStorage.getTableId()),
                         partitionId,
                         tableStorage.dataRegion().pageMemory(),
-                        PageLockListenerNoOp.INSTANCE,
                         tableStorage.engine().generateGlobalRemoveId(),
                         metaPageId,
                         freeList,
@@ -145,7 +143,6 @@ class IndexStorageFactory {
                     Integer.toString(tableStorage.getTableId()),
                     partitionId,
                     tableStorage.dataRegion().pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     tableStorage.engine().generateGlobalRemoveId(),
                     indexMeta.metaPageId(),
                     freeList
@@ -207,7 +204,6 @@ class IndexStorageFactory {
                         Integer.toString(tableStorage.getTableId()),
                         partitionId,
                         tableStorage.dataRegion().pageMemory(),
-                        PageLockListenerNoOp.INSTANCE,
                         tableStorage.engine().generateGlobalRemoveId(),
                         metaPageId,
                         freeList,
@@ -223,7 +219,6 @@ class IndexStorageFactory {
                     Integer.toString(tableStorage.getTableId()),
                     partitionId,
                     tableStorage.dataRegion().pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     tableStorage.engine().generateGlobalRemoveId(),
                     indexMeta.metaPageId(),
                     freeList,
@@ -241,7 +236,6 @@ class IndexStorageFactory {
                     Integer.toString(tableStorage.getTableId()),
                     partitionId,
                     tableStorage.dataRegion().pageMemory(),
-                    PageLockListenerNoOp.INSTANCE,
                     tableStorage.engine().generateGlobalRemoveId(),
                     indexMeta.metaPageId(),
                     freeList
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChainTree.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChainTree.java
index a17da8ea904..8b7f14e411d 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChainTree.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChainTree.java
@@ -23,7 +23,6 @@ import org.apache.ignite.internal.pagememory.PageMemory;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.storage.pagememory.mv.io.VersionChainInnerIo;
 import org.apache.ignite.internal.storage.pagememory.mv.io.VersionChainIo;
 import org.apache.ignite.internal.storage.pagememory.mv.io.VersionChainLeafIo;
@@ -41,7 +40,6 @@ public class VersionChainTree extends 
BplusTree<VersionChainKey, VersionChain> {
      * @param grpName Group name.
      * @param partId Partition id.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -55,7 +53,6 @@ public class VersionChainTree extends 
BplusTree<VersionChainKey, VersionChain> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
@@ -67,7 +64,6 @@ public class VersionChainTree extends 
BplusTree<VersionChainKey, VersionChain> {
                 grpName,
                 partId,
                 pageMem,
-                lockLsnr,
                 globalRmvId,
                 metaPageId,
                 reuseList
diff --git 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/gc/GcQueue.java
 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/gc/GcQueue.java
index 01627578076..8e50dbbb20d 100644
--- 
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/gc/GcQueue.java
+++ 
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/gc/GcQueue.java
@@ -24,7 +24,6 @@ import org.apache.ignite.internal.pagememory.PageMemory;
 import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import org.apache.ignite.internal.pagememory.tree.BplusTree;
 import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
-import org.apache.ignite.internal.pagememory.util.PageLockListener;
 import org.apache.ignite.internal.storage.RowId;
 import org.apache.ignite.internal.storage.StorageException;
 import org.apache.ignite.internal.storage.pagememory.mv.gc.io.GcInnerIo;
@@ -44,7 +43,6 @@ public class GcQueue extends BplusTree<GcRowVersion, 
GcRowVersion> {
      * @param grpName Group name.
      * @param partId Partition id.
      * @param pageMem Page memory.
-     * @param lockLsnr Page lock listener.
      * @param globalRmvId Global remove ID, for a tree that was created for 
the first time it can be {@code 0}, for restored ones it
      *      must be greater than or equal to the previous value.
      * @param metaPageId Meta page ID.
@@ -58,7 +56,6 @@ public class GcQueue extends BplusTree<GcRowVersion, 
GcRowVersion> {
             String grpName,
             int partId,
             PageMemory pageMem,
-            PageLockListener lockLsnr,
             AtomicLong globalRmvId,
             long metaPageId,
             @Nullable ReuseList reuseList,
@@ -70,7 +67,6 @@ public class GcQueue extends BplusTree<GcRowVersion, 
GcRowVersion> {
                 grpName,
                 partId,
                 pageMem,
-                lockLsnr,
                 globalRmvId,
                 metaPageId,
                 reuseList
diff --git 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java
 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java
index f56bd07b115..05217ecdaba 100644
--- 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java
+++ 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/PersistentPageMemoryNoLoadTest.java
@@ -467,7 +467,7 @@ public class PersistentPageMemoryNoLoadTest extends 
AbstractPageMemoryNoLoadSelf
                 checkpointManager == null ? mockCheckpointTimeoutLock(true) : 
checkpointManager.checkpointTimeoutLock(),
                 checkpointManager == null ? () -> null : 
checkpointManager::currentCheckpointProgress,
                 PAGE_SIZE,
-                new OffheapReadWriteLock(128)
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
         );
     }
 
diff --git 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
index dfaf6761087..829d619c010 100644
--- 
a/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
+++ 
b/modules/storage-page-memory/src/test/java/org/apache/ignite/internal/storage/pagememory/mv/BlobStorageTest.java
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.pagememory.reuse.ReuseList;
 import 
org.apache.ignite.internal.storage.configurations.StorageProfileConfiguration;
 import org.apache.ignite.internal.storage.pagememory.mv.io.BlobFragmentIo;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
+import org.apache.ignite.internal.util.OffheapReadWriteLock;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -80,7 +81,11 @@ class BlobStorageTest extends BaseIgniteAbstractTest {
         };
 
         pageMemory = spy(new VolatilePageMemory(
-                (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(dataRegionCfg), pageIoRegistry, PAGE_SIZE));
+                (VolatilePageMemoryProfileConfiguration) 
fixConfiguration(dataRegionCfg),
+                pageIoRegistry,
+                PAGE_SIZE,
+                new 
OffheapReadWriteLock(OffheapReadWriteLock.DEFAULT_CONCURRENCY_LEVEL)
+        ));
 
         pageMemory.start();
 

Reply via email to