rpuch commented on a change in pull request #414:
URL: https://github.com/apache/ignite-3/pull/414#discussion_r738117516
##########
File path:
modules/core/src/main/java/org/apache/ignite/internal/util/IgniteSpinReadWriteLock.java
##########
@@ -17,77 +17,122 @@
package org.apache.ignite.internal.util;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
import java.util.concurrent.TimeUnit;
+
import org.apache.ignite.internal.tostring.S;
/**
- * Spin read-write lock.
+ * <p>Spin read-write lock.
+ * Its blocking methods use spinwait strategy. When they do so, they are not
interruptible (that is, they do not
+ * break their loop on interruption signal).
+ * </p>
+ * <p>The locks are reentrant (that is, the same thread can acquire the same
lock a few times in a row and then
+ * release them same number of times.</p>
+ * <p>
+ * Write lock acquire requests are prioritized over read lock acquire
requests. That is, if both read and write lock
+ * acquire requests are received when the write lock is held by someone else,
then, on its release, write lock attempt
+ * will be served first.
+ * </p>
*/
public class IgniteSpinReadWriteLock {
- /** */
- private static final long PENDING_WLOCKS_OFFS;
+ /** Signals that nobody currently owns read lock. */
+ private static final long NO_OWNER = -1;
- /** */
- private static final long STATE_OFFS;
+ /**
+ * State -1 means that the write lock is acquired.
+ *
+ * @see #state
+ */
+ private static final int WRITE_LOCKED = -1;
/**
- * TODO: replace UNSAFE usage using VarHandle
https://issues.apache.org/jira/browse/IGNITE-15536
+ * State 0 means that both read and write locks are available for
acquiring.
+ *
+ * @see #state
*/
+ private static final int AVAILABLE = 0;
+
+ /** {@link VarHandle} used to access pendingWLocks field. */
+ private static final VarHandle PENDING_WLOCKS_VH;
+
+ /** {@link VarHandle} used to access state field. */
+ private static final VarHandle STATE_VH;
+
static {
try {
- STATE_OFFS =
GridUnsafe.objectFieldOffset(IgniteSpinReadWriteLock.class.getDeclaredField("state"));
+ STATE_VH = MethodHandles.lookup()
+ .findVarHandle(IgniteSpinReadWriteLock.class, "state",
int.class);
- PENDING_WLOCKS_OFFS =
-
GridUnsafe.objectFieldOffset(IgniteSpinReadWriteLock.class.getDeclaredField("pendingWLocks"));
+ PENDING_WLOCKS_VH = MethodHandles.lookup()
+ .findVarHandle(IgniteSpinReadWriteLock.class,
"pendingWLocks", int.class);
}
- catch (NoSuchFieldException e) {
+ catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
- /** */
- private final ThreadLocal<Integer> readLockEntryCnt = new
ThreadLocal<Integer>() {
- @Override protected Integer initialValue() {
+ /** Number of times read lock was acquired, per thread (used to track
reentrance). */
+ private final ThreadLocal<Integer> readLockEntryCnt = new ThreadLocal<>() {
+ @Override
+ protected Integer initialValue() {
Review comment:
Fixed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]