415062 SelectorManager wakeup optimisation

removed wakeup spin
This commit is contained in:
Greg Wilkins 2013-08-16 19:23:59 +10:00
parent edbf6e07aa
commit 2f0becff8f
1 changed files with 10 additions and 35 deletions

View File

@ -60,7 +60,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
protected static final Logger LOG = Log.getLogger(SelectorManager.class);
protected static final int SELECT_PERIOD=Integer.valueOf(System.getProperty("org.eclipse.jetty.io.SELECT_PERIOD","1000"));
protected static final int WAKEUP_SPIN_PERIOD=Integer.valueOf(System.getProperty("org.eclipse.jetty.io.WAKEUP_SPIN_PERIOD","1"));
/**
* The default connect timeout, in milliseconds
*/
@ -324,10 +324,9 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dumpable
{
private final Queue<Runnable> _changes = new ConcurrentArrayQueue<>();
private final AtomicReference<SelectorState> _state = new AtomicReference<>(SelectorState.PROCESSING);
private final AtomicReference<SelectorState> _state = new AtomicReference<>(null);
private final int _id;
private Selector _selector;
private volatile int _sequence;
private Thread _thread;
@ -368,7 +367,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
{
// If we are already iterating over the changes, just add this change to the list.
// No race here because it is this thread that is iterating over the changes.
if (_state.get()==SelectorState.CHANGING)
if (_state.compareAndSet(SelectorState.CHANGING,SelectorState.MORE_CHANGES))
_changes.offer(change);
else
{
@ -400,29 +399,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
// If we are SELECTING, goto WAKING state so only one caller will spin on wakeup.
if (!_state.compareAndSet(SelectorState.SELECTING,SelectorState.WAKING))
continue;
// Spin doing wakeups until we see the select has moved to the next sequence.
// This spin handles the race of doing a wakeup just before a select call.
final long sequence=_sequence;
try
{
do
{
wakeup();
// We don't want to spin too fast as wakeup is not cheap, but sleeping might sleep for a long
// time, so this might need to be profiled and tuned?
if (WAKEUP_SPIN_PERIOD==0)
Thread.yield();
else
Thread.sleep(WAKEUP_SPIN_PERIOD);
}
while(sequence==_sequence);
}
catch(InterruptedException e)
{
LOG.ignore(e);
}
wakeup();
break loop;
default:
@ -450,7 +427,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
public void run()
{
_thread = Thread.currentThread();
_sequence++; // volatile increment for memory barrier
_state.set(SelectorState.PROCESSING);
String name = _thread.getName();
try
{
@ -465,7 +442,7 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
LOG.debug("Stopped {} on {}", _thread, this);
_thread.setName(name);
_thread=null;
_sequence++; // volatile increment for memory barrier
_state.set(null);
}
}
@ -511,9 +488,6 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
if (debug)
LOG.debug("Selector loop waiting on select");
int selected = _selector.select(SELECT_PERIOD);
// increment the sequence number to end any spinning wakeups
_sequence++;
// we are now definitely switching to PROCESSING state
_state.set(SelectorState.PROCESSING);
@ -706,10 +680,11 @@ public abstract class SelectorManager extends AbstractLifeCycle implements Dumpa
public String toString()
{
Selector selector = _selector;
return String.format("%s keys=%d selected=%d",
return String.format("%s state=%s keys=%d/%d",
super.toString(),
selector != null && selector.isOpen() ? selector.keys().size() : -1,
selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1);
_state.get(),
selector != null && selector.isOpen() ? selector.selectedKeys().size() : -1,
selector != null && selector.isOpen() ? selector.keys().size() : -1);
}
private class DumpKeys implements Runnable