Skip to content

Commit

Permalink
Use updater to avoid indirecting
Browse files Browse the repository at this point in the history
Status is set heavily for any blocking operations so make this
lighter weight.
  • Loading branch information
headius committed Mar 2, 2021
1 parent f3e8f3b commit 67fd7fc
Showing 1 changed file with 17 additions and 15 deletions.
32 changes: 17 additions & 15 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

Expand Down Expand Up @@ -179,7 +179,9 @@ public enum Status {
}

/** Current status in an atomic reference */
private final AtomicReference<Status> status = new AtomicReference<>(Status.RUN);
private volatile Status status = Status.RUN;
private final static AtomicReferenceFieldUpdater<RubyThread, Status> STATUS =
AtomicReferenceFieldUpdater.newUpdater(RubyThread.class, Status.class, "status");

/** Mail slot for cross-thread events */
private final Queue<IRubyObject> pendingInterruptQueue = new ConcurrentLinkedQueue<>();
Expand Down Expand Up @@ -298,7 +300,7 @@ private boolean pendingInterruptActive() {

private void toKill() {
pendingInterruptClear();
status.set(Status.ABORTING);
STATUS.set(this, Status.ABORTING);
throwThreadKill();
}

Expand Down Expand Up @@ -725,7 +727,7 @@ public synchronized void cleanTerminate(IRubyObject result) {
}

public void beDead() {
status.set(Status.DEAD);
STATUS.set(this, Status.DEAD);
}

public void pollThreadEvents() {
Expand Down Expand Up @@ -1275,12 +1277,12 @@ public static IRubyObject stop(ThreadContext context, IRubyObject receiver) {
rubyThread.pollThreadEvents(context);
Status oldStatus = rubyThread.getStatus();
try {
rubyThread.status.set(Status.SLEEP);
STATUS.set(rubyThread, Status.SLEEP);
rubyThread.wait();
} catch (InterruptedException ie) {
} finally {
rubyThread.pollThreadEvents(context);
rubyThread.status.set(oldStatus);
STATUS.set(rubyThread, oldStatus);
}
}

Expand Down Expand Up @@ -1312,7 +1314,7 @@ public synchronized RubyThread wakeup() {
throw getRuntime().newThreadError("killed thread");
}

status.set(Status.RUN);
STATUS.set(this, Status.RUN);
interrupt();

return this;
Expand Down Expand Up @@ -1606,37 +1608,37 @@ public <Data, Return> Return executeTask(ThreadContext context, Data data, Task<
}

public <Data, Return> Return executeTask(ThreadContext context, Data data, Status status, Task<Data, Return> task) throws InterruptedException {
Status oldStatus = this.status.get();
Status oldStatus = STATUS.get(this);
try {
this.unblockArg = data;
this.unblockFunc = task;

// check for interrupt before going into blocking call
pollThreadEvents(context);

this.status.set(status);
STATUS.set(this, status);

return task.run(context, data);
} finally {
this.status.set(oldStatus);
STATUS.set(this, oldStatus);
this.unblockFunc = null;
this.unblockArg = null;
pollThreadEvents(context);
}
}

public void enterSleep() {
status.set(Status.SLEEP);
STATUS.set(this, Status.SLEEP);
}

public void exitSleep() {
if (getStatus() != Status.ABORTING) {
status.set(Status.RUN);
if (status != Status.ABORTING) {
STATUS.set(this, Status.RUN);
}
}

private Status getStatus() {
Status status = this.status.get();
Status status = STATUS.get(this);

if (status != Status.NATIVE) return status;

Expand Down Expand Up @@ -1668,7 +1670,7 @@ public IRubyObject kill() {
// rb_exit to hard exit process...not quite right for us
}

status.set(Status.ABORTING);
STATUS.set(this, Status.ABORTING);

return genericKill(runtime, currentThread);
}
Expand Down

0 comments on commit 67fd7fc

Please sign in to comment.