mirror of https://github.com/apache/cassandra
SEPExecutor.maybeExecuteImmediately does not always execute tasks immediately despite available worker capacity
Additional improvement: use a wait-free logic to return a task or work permit patch by Dmitry Konstantinov; reviewed by Benedict Elliott Smith for CASSANDRA-21429
This commit is contained in:
parent
22eb0f9fb7
commit
88aa5b6807
|
|
@ -1,4 +1,5 @@
|
||||||
6.0-alpha2
|
6.0-alpha2
|
||||||
|
* SEPExecutor.maybeExecuteImmediately does not always execute tasks immediately despite available worker capacity (CASSANDRA-21429)
|
||||||
* Safely regain ranges and delete retired command stores (CASSANDRA-21212)
|
* Safely regain ranges and delete retired command stores (CASSANDRA-21212)
|
||||||
* Reduce memory allocations in miscellaneous places along read path (CASSANDRA-21360)
|
* Reduce memory allocations in miscellaneous places along read path (CASSANDRA-21360)
|
||||||
* Avoid ByteBuffer wrapping in cql3.selection.Selector.InputRow to reduce memory allocation rate (CASSANDRA-21362)
|
* Avoid ByteBuffer wrapping in cql3.selection.Selector.InputRow to reduce memory allocation rate (CASSANDRA-21362)
|
||||||
|
|
|
||||||
|
|
@ -123,18 +123,9 @@ public class SEPExecutor implements LocalAwareExecutorPlus, SEPExecutorMBean
|
||||||
// we add to the queue first, so that when a worker takes a task permit it can be certain there is a task available
|
// we add to the queue first, so that when a worker takes a task permit it can be certain there is a task available
|
||||||
// this permits us to schedule threads non-spuriously; it also means work is serviced fairly
|
// this permits us to schedule threads non-spuriously; it also means work is serviced fairly
|
||||||
tasks.add(task);
|
tasks.add(task);
|
||||||
int taskPermits;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
long current = permits.get();
|
|
||||||
taskPermits = taskPermits(current);
|
|
||||||
// because there is no difference in practical terms between the work permit being added or not (the work is already in existence)
|
|
||||||
// we always add our permit, but block after the fact if we breached the queue limit
|
|
||||||
if (permits.compareAndSet(current, updateTaskPermits(current, taskPermits + 1)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (taskPermits == 0)
|
long prev = permits.getAndAdd(updateTaskPermits(0, 1));
|
||||||
|
if (taskPermits(prev) == 0)
|
||||||
{
|
{
|
||||||
// we only need to schedule a thread if there are no tasks already waiting to be processed, as
|
// we only need to schedule a thread if there are no tasks already waiting to be processed, as
|
||||||
// the original enqueue will have started a thread to service its work which will have itself
|
// the original enqueue will have started a thread to service its work which will have itself
|
||||||
|
|
@ -193,11 +184,11 @@ public class SEPExecutor implements LocalAwareExecutorPlus, SEPExecutorMBean
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
long current = permits.get();
|
long current = permits.get();
|
||||||
int workPermits = workPermits(current);
|
int newWorkPermits = workPermits(current) - 1;
|
||||||
int taskPermits = taskPermits(current);
|
int newTaskPermits = taskPermits(current) - taskDelta;
|
||||||
if (workPermits <= 0 || taskPermits == 0)
|
if (newWorkPermits < 0 || newTaskPermits < 0)
|
||||||
return false;
|
return false;
|
||||||
if (permits.compareAndSet(current, combine(taskPermits - taskDelta, workPermits - 1)))
|
if (permits.compareAndSet(current, combine(newTaskPermits, newWorkPermits)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -207,13 +198,7 @@ public class SEPExecutor implements LocalAwareExecutorPlus, SEPExecutorMBean
|
||||||
// gives up a work permit
|
// gives up a work permit
|
||||||
void returnWorkPermit()
|
void returnWorkPermit()
|
||||||
{
|
{
|
||||||
while (true)
|
permits.addAndGet(updateWorkPermits(0, 1));
|
||||||
{
|
|
||||||
long current = permits.get();
|
|
||||||
int workPermits = workPermits(current);
|
|
||||||
if (permits.compareAndSet(current, updateWorkPermits(current, workPermits + 1)))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue