mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
RWLock performance: make unnecessarily volatile fields final
GitOrigin-RevId: 23781a6883d170d350627a3b340046a012494c28
This commit is contained in:
committed by
intellij-monorepo-bot
parent
95d2d94a47
commit
1cc7204197
+4
-1
@@ -58,6 +58,7 @@ import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ApplicationImpl extends ComponentManagerImpl implements ApplicationEx {
|
||||
@@ -142,6 +143,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
|
||||
gatherStatistics = LOG.isDebugEnabled() || isUnitTestMode() || isInternal();
|
||||
|
||||
Activity activity = StartUpMeasurer.startActivity("AppDelayQueue instantiation");
|
||||
AtomicReference<Thread> edtThread = new AtomicReference<>();
|
||||
Runnable runnable = () -> {
|
||||
// instantiate AppDelayQueue which starts "Periodic task thread" which we'll mark busy to prevent this EDT to die
|
||||
// that thread was chosen because we know for sure it's running
|
||||
@@ -151,9 +153,10 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
|
||||
Disposer.register(this, () -> {
|
||||
AWTAutoShutdown.getInstance().notifyThreadFree(thread); // allow for EDT to exit - needed for Upsource
|
||||
});
|
||||
edtThread.set(Thread.currentThread());
|
||||
};
|
||||
EdtInvocationManager.invokeAndWaitIfNeeded(runnable);
|
||||
myLock = new ReadMostlyRWLock();
|
||||
myLock = new ReadMostlyRWLock(edtThread.get());
|
||||
// Acquire IW lock on EDT indefinitely in legacy mode
|
||||
if (!USE_SEPARATE_WRITE_THREAD || isUnitTestMode) {
|
||||
EdtInvocationManager.invokeAndWaitIfNeeded(() -> acquireWriteIntentLock(getClass()));
|
||||
|
||||
+4
-17
@@ -23,7 +23,6 @@ import com.intellij.util.containers.ConcurrentList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -45,8 +44,7 @@ import java.util.concurrent.locks.LockSupport;
|
||||
* Write lock: sets global {@link #writeRequested} bit and waits for all readers (in global {@link #readers} list) to release their locks by checking {@link Reader#readRequested} for all readers.
|
||||
*/
|
||||
class ReadMostlyRWLock {
|
||||
volatile Thread writeThread;
|
||||
private volatile Thread writeIntendedThread;
|
||||
final Thread writeThread;
|
||||
@VisibleForTesting
|
||||
volatile boolean writeRequested; // this writer is requesting or obtained the write access
|
||||
private final AtomicBoolean writeIntent = new AtomicBoolean(false);
|
||||
@@ -59,7 +57,8 @@ class ReadMostlyRWLock {
|
||||
// (we have to reduce frequency of this "dead readers GC" activity because Thread.isAlive() turned out to be too expensive)
|
||||
private volatile long deadReadersGCStamp;
|
||||
|
||||
ReadMostlyRWLock() {
|
||||
ReadMostlyRWLock(@NotNull Thread writeThread) {
|
||||
this.writeThread = writeThread;
|
||||
}
|
||||
|
||||
// Each reader thread has instance of this struct in its thread local. it's also added to global "readers" list.
|
||||
@@ -91,15 +90,6 @@ class ReadMostlyRWLock {
|
||||
return status;
|
||||
});
|
||||
|
||||
@TestOnly
|
||||
void setWriteThread(@NotNull Thread thread) {
|
||||
assert !writeAcquired;
|
||||
assert !writeRequested;
|
||||
assert writeThread == null;
|
||||
|
||||
writeThread = thread;
|
||||
}
|
||||
|
||||
boolean isWriteThread() {
|
||||
return Thread.currentThread() == writeThread;
|
||||
}
|
||||
@@ -212,13 +202,11 @@ class ReadMostlyRWLock {
|
||||
|
||||
void writeIntentLock() {
|
||||
//checkWriteThreadAccess();
|
||||
writeIntendedThread = Thread.currentThread();
|
||||
for (int iter=0; ;iter++) {
|
||||
if (writeIntent.compareAndSet(false, true)) {
|
||||
assert !writeRequested;
|
||||
assert !writeAcquired;
|
||||
|
||||
writeThread = Thread.currentThread();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -237,9 +225,8 @@ class ReadMostlyRWLock {
|
||||
assert !writeAcquired;
|
||||
assert !writeRequested;
|
||||
|
||||
writeThread = null;
|
||||
writeIntent.set(false);
|
||||
LockSupport.unpark(writeIntendedThread);
|
||||
LockSupport.unpark(writeThread);
|
||||
}
|
||||
|
||||
void writeLock() {
|
||||
|
||||
+2
-2
@@ -525,8 +525,8 @@ public class ApplicationImplTest extends LightPlatformTestCase {
|
||||
UIUtil.dispatchAllInvocationEvents();
|
||||
}
|
||||
int readIterations = 200_000_000;
|
||||
ReadMostlyRWLock lock = new ReadMostlyRWLock();
|
||||
lock.setWriteThread(Thread.currentThread());
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
ReadMostlyRWLock lock = new ReadMostlyRWLock(Thread.currentThread());
|
||||
final int numOfThreads = JobSchedulerImpl.getJobPoolParallelism();
|
||||
final Field myThreadLocalsField = Objects.requireNonNull(ReflectionUtil.getDeclaredField(Thread.class, "threadLocals"));
|
||||
//noinspection Convert2Lambda
|
||||
|
||||
Reference in New Issue
Block a user