/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.fibers;
import co.paralleluniverse.common.monitoring.MonitorType;
import co.paralleluniverse.strands.Strand;
import co.paralleluniverse.strands.StrandFactory;
import co.paralleluniverse.strands.SuspendableCallable;
import com.google.common.collect.MapMaker;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* A thread-pool based scheduler for fibers. Internally, this scheduler uses a {@code ForkJoinPool} to schedule fiber execution.
*
* @author pron
*/
public abstract class FiberScheduler implements FiberFactory, StrandFactory {
static final FibersMonitor NOOP_FIBERS_MONITOR = new NoopFibersMonitor();
private final String name;
private final FibersMonitor fibersMonitor;
final ConcurrentMap<SchedulerLocal, SchedulerLocal.Entry<?>> schedLocals = new MapMaker().weakKeys().makeMap();
FiberScheduler(String name, MonitorType monitorType, boolean detailedInfo) {
this.name = name;
fibersMonitor = createFibersMonitor(name, this, monitorType, detailedInfo);
}
private static FibersMonitor createFibersMonitor(String name, FiberScheduler scheduler, MonitorType monitorType, boolean detailedInfo) {
if (monitorType == null)
monitorType = MonitorType.NONE;
switch (monitorType) {
case JMX:
return new JMXFibersMonitor(name, scheduler, detailedInfo);
case METRICS:
return new MetricsFibersMonitor(name, scheduler);
case NONE:
return NOOP_FIBERS_MONITOR;
default:
throw new RuntimeException("Unsupported monitor type: " + monitorType);
}
}
public String getName() {
return name;
}
protected FibersMonitor getMonitor() {
return fibersMonitor;
}
@Override
public <T> Fiber<T> newFiber(SuspendableCallable<T> target) {
return new Fiber<T>(this, target);
}
@Override
public Strand newStrand(final SuspendableCallable<?> target) {
return newFiber(target);
}
abstract Future<Void> schedule(Fiber<?> fiber, Object blocker, long delay, TimeUnit unit);
abstract Map<Thread, Fiber> getRunningFibers();
protected abstract int getQueueLength();
abstract int getTimedQueueLength();
protected abstract boolean isCurrentThreadInScheduler();
void setCurrentFiber(Fiber fiber, Thread currentThread) {
Fiber.setCurrentStrand(fiber);
}
abstract void setCurrentTarget(Object target, Thread currentThread);
abstract Object getCurrentTarget(Thread currentThread);
abstract <V> FiberTask<V> newFiberTask(Fiber<V> fiber);
public abstract Executor getExecutor();
}