Fix bugs in threading in C backend

This commit is contained in:
Alexey Andreev 2019-03-13 18:47:30 +03:00
parent eeaa71072a
commit 731beb5cd5
4 changed files with 24 additions and 14 deletions

View File

@ -190,8 +190,8 @@ public class TThread extends TObject implements TRunnable {
@Async @Async
public static native void sleep(long millis) throws TInterruptedException; public static native void sleep(long millis) throws TInterruptedException;
private static void sleep(long millis, final AsyncCallback<Void> callback) { private static void sleep(long millis, AsyncCallback<Void> callback) {
final TThread current = currentThread(); TThread current = currentThread();
SleepHandler handler = new SleepHandler(current, callback); SleepHandler handler = new SleepHandler(current, callback);
if (PlatformDetector.isLowLevel()) { if (PlatformDetector.isLowLevel()) {
handler.scheduleId = EventQueue.offer(handler, System.currentTimeMillis() + millis); handler.scheduleId = EventQueue.offer(handler, System.currentTimeMillis() + millis);

View File

@ -58,6 +58,7 @@ import org.teavm.model.util.BasicBlockMapper;
import org.teavm.model.util.InstructionVariableMapper; import org.teavm.model.util.InstructionVariableMapper;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;
import org.teavm.model.util.TransitionExtractor; import org.teavm.model.util.TransitionExtractor;
import org.teavm.runtime.Fiber;
public class Inlining { public class Inlining {
private IntArrayList depthsByBlock; private IntArrayList depthsByBlock;
@ -177,7 +178,7 @@ public class Inlining {
if (step == null) { if (step == null) {
return false; return false;
} }
List<PlanEntry> plan = buildPlan(program, -1, step); List<PlanEntry> plan = buildPlan(program, -1, step, method);
if (plan.isEmpty()) { if (plan.isEmpty()) {
return false; return false;
} }
@ -328,7 +329,7 @@ public class Inlining {
execPlan(program, planEntry.innerPlan, firstInlineBlock.getIndex()); execPlan(program, planEntry.innerPlan, firstInlineBlock.getIndex());
} }
private List<PlanEntry> buildPlan(Program program, int depth, InliningStep step) { private List<PlanEntry> buildPlan(Program program, int depth, InliningStep step, MethodReference method) {
List<PlanEntry> plan = new ArrayList<>(); List<PlanEntry> plan = new ArrayList<>();
int originalDepth = depth; int originalDepth = depth;
@ -355,6 +356,11 @@ public class Inlining {
continue; continue;
} }
if (invoke.getMethod().getClassName().equals(Fiber.class.getName())
!= method.getClassName().equals(Fiber.class.getName())) {
continue;
}
MethodReader invokedMethod = getMethod(invoke.getMethod()); MethodReader invokedMethod = getMethod(invoke.getMethod());
if (invokedMethod == null || invokedMethod.getProgram() == null if (invokedMethod == null || invokedMethod.getProgram() == null
|| invokedMethod.getProgram().basicBlockCount() == 0 || invokedMethod.getProgram().basicBlockCount() == 0
@ -376,7 +382,7 @@ public class Inlining {
entry.targetBlock = block.getIndex(); entry.targetBlock = block.getIndex();
entry.targetInstruction = insn; entry.targetInstruction = insn;
entry.program = invokedProgram; entry.program = invokedProgram;
entry.innerPlan.addAll(buildPlan(invokedProgram, depth + 1, innerStep)); entry.innerPlan.addAll(buildPlan(invokedProgram, depth + 1, innerStep, invokedMethod.getReference()));
entry.depth = depth; entry.depth = depth;
entry.method = invokedMethod.getReference(); entry.method = invokedMethod.getReference();
plan.add(entry); plan.add(entry);

View File

@ -64,7 +64,7 @@ public final class EventQueue {
} }
public static void process() { public static void process() {
while (!finished) { while (size > 0 && !finished) {
next(); next();
} }
} }
@ -86,7 +86,16 @@ public final class EventQueue {
} }
private static void remove(int index) { private static void remove(int index) {
Node item = data[size - 1]; --size;
if (index < size) {
data[index] = data[size];
update(index);
}
data[size] = null;
}
private static void update(int index) {
Node item = data[index];
while (true) { while (true) {
int left = index * 2 + 1; int left = index * 2 + 1;
int right = left + 1; int right = left + 1;

View File

@ -211,12 +211,7 @@ public class Fiber {
} }
static void startMain() { static void startMain() {
start(() -> { start(Fiber::runMain);
runMain();
if (!current().isSuspending()) {
EventQueue.stop();
}
});
} }
static native void runMain(); static native void runMain();
@ -228,7 +223,7 @@ public class Fiber {
current = former; current = former;
} }
private void resume() { void resume() {
state = STATE_RESUMING; state = STATE_RESUMING;
start(); start();
} }