From 97cf39a3145fe0a7bf9de99a3d82af23b7822a7c Mon Sep 17 00:00:00 2001 From: Dominik Aumayr Date: Wed, 2 Sep 2020 18:35:42 +0200 Subject: [PATCH] fix racy promise message corner case --- .../interpreter/actors/ReceivedRootNode.java | 5 +---- .../actors/RegisterOnPromiseNode.java | 5 +++++ src/som/interpreter/actors/SPromise.java | 18 ++---------------- src/tools/concurrency/TracingActors.java | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/som/interpreter/actors/ReceivedRootNode.java b/src/som/interpreter/actors/ReceivedRootNode.java index a4a0f4889..024ead72a 100644 --- a/src/som/interpreter/actors/ReceivedRootNode.java +++ b/src/som/interpreter/actors/ReceivedRootNode.java @@ -13,7 +13,6 @@ import som.interpreter.SomLanguage; import som.interpreter.actors.EventualMessage.PromiseMessage; import som.interpreter.actors.SPromise.SResolver; -import som.interpreter.actors.SPromise.STracingPromise; import som.vm.VmSettings; import tools.concurrency.KomposTrace; import tools.concurrency.TracingActors.TracingActor; @@ -93,9 +92,7 @@ public final Object execute(final VirtualFrame frame) { if (VmSettings.RECEIVER_SIDE_TRACING) { if (msg instanceof PromiseMessage) { - PromiseMessage pmsg = (PromiseMessage) msg; - STracingPromise tprom = (STracingPromise) pmsg.getPromise(); - promiseMessageTracer.record(tprom.getResolvingActor()); + promiseMessageTracer.record(msg.messageId); } messageTracer.record(((TracingActor) msg.getSender()).getId()); } diff --git a/src/som/interpreter/actors/RegisterOnPromiseNode.java b/src/som/interpreter/actors/RegisterOnPromiseNode.java index 354fa332a..2e74c9c14 100644 --- a/src/som/interpreter/actors/RegisterOnPromiseNode.java +++ b/src/som/interpreter/actors/RegisterOnPromiseNode.java @@ -11,6 +11,7 @@ import som.interpreter.actors.SPromise.SReplayPromise; import som.interpreter.actors.SPromise.STracingPromise; import som.vm.VmSettings; +import tools.concurrency.TracingActors.TracingActor; import tools.dym.DynamicMetrics; import tools.replay.ReplayRecord; import tools.replay.TraceRecord; @@ -72,6 +73,8 @@ public void register(final SPromise promise, final PromiseMessage msg, ((SReplayPromise) promise).registerOnResolvedReplay(msg); return; } + } else if (VmSettings.RECEIVER_SIDE_TRACING || VmSettings.RECEIVER_SIDE_REPLAY) { + msg.messageId = ((TracingActor) current).getNextPromiseMsgNumber(); } if (!promise.isResolvedUnsync()) { @@ -154,6 +157,8 @@ public void register(final SPromise promise, final PromiseMessage msg, ((SReplayPromise) promise).registerOnErrorReplay(msg); return; } + } else if (VmSettings.RECEIVER_SIDE_TRACING || VmSettings.RECEIVER_SIDE_REPLAY) { + msg.messageId = ((TracingActor) current).getNextPromiseMsgNumber(); } if (!promise.isErroredUnsync()) { diff --git a/src/som/interpreter/actors/SPromise.java b/src/som/interpreter/actors/SPromise.java index 24f4e306f..143556e16 100644 --- a/src/som/interpreter/actors/SPromise.java +++ b/src/som/interpreter/actors/SPromise.java @@ -23,7 +23,6 @@ import som.vmobjects.SObjectWithClass; import tools.concurrency.KomposTrace; import tools.concurrency.TracingActivityThread; -import tools.concurrency.TracingActors.TracingActor; import tools.debugger.entities.PassiveEntityType; import tools.dym.DynamicMetrics; import tools.replay.PassiveEntityWithEvents; @@ -203,9 +202,6 @@ public final synchronized SPromise getChainedPromiseFor(final Actor target, if (isCompleted()) { remote.value = value; remote.resolutionState = resolutionState; - if (VmSettings.RECEIVER_SIDE_TRACING || VmSettings.RECEIVER_SIDE_REPLAY) { - ((STracingPromise) remote).resolvingActor = ((STracingPromise) this).resolvingActor; - } } else { if (VmSettings.SENDER_SIDE_TRACING) { @@ -377,19 +373,12 @@ protected STracingPromise(final Actor owner, final boolean haltOnResolver, version = 0; } - protected int version; - protected long resolvingActor; + protected int version; @Override public int getNextEventNumber() { return version; } - - public long getResolvingActor() { - assert VmSettings.RECEIVER_SIDE_TRACING || VmSettings.RECEIVER_SIDE_REPLAY; - assert isCompleted(); - return resolvingActor; - } } public static class SReplayPromise extends STracingPromise { @@ -826,10 +815,7 @@ protected static void resolveAndTriggerListenersUnsynced(final Resolution type, final RecordOneEvent tracePromiseResolutionEnd2) { assert !(result instanceof SPromise); - if (VmSettings.RECEIVER_SIDE_TRACING || VmSettings.RECEIVER_SIDE_REPLAY) { - ((STracingPromise) p).resolvingActor = - ((TracingActor) EventualMessage.getActorCurrentMessageIsExecutionOn()).getId(); - } else if (VmSettings.KOMPOS_TRACING) { + if (VmSettings.KOMPOS_TRACING) { if (type == Resolution.SUCCESSFUL && p.resolutionState != Resolution.CHAINED) { KomposTrace.promiseResolution(p.getPromiseId(), result); } else if (type == Resolution.ERRONEOUS) { diff --git a/src/tools/concurrency/TracingActors.java b/src/tools/concurrency/TracingActors.java index ce1e387ea..42c581cea 100644 --- a/src/tools/concurrency/TracingActors.java +++ b/src/tools/concurrency/TracingActors.java @@ -16,7 +16,6 @@ import som.interpreter.actors.Actor; import som.interpreter.actors.EventualMessage; import som.interpreter.actors.EventualMessage.PromiseMessage; -import som.interpreter.actors.SPromise.STracingPromise; import som.vm.VmSettings; import tools.debugger.WebDebugger; import tools.replay.PassiveEntityWithEvents; @@ -34,6 +33,7 @@ public static class TracingActor extends Actor { protected SnapshotRecord snapshotRecord; private int traceBufferId; protected int version; + private long nextPMsgNumber; /** * Flag that indicates if a step-to-next-turn action has been made in the previous message. @@ -142,6 +142,15 @@ public static void handleBreakpointsAndStepping(final EventualMessage msg, public DeserializationBuffer getDeserializationBuffer() { return null; } + + /** + * Only to be used by the thread executing this actor + * + * @return + */ + public long getNextPromiseMsgNumber() { + return nextPMsgNumber++; + } } public static final class ReplayActor extends TracingActor @@ -306,7 +315,7 @@ protected boolean replayCanProcess(final MessageRecord expected, // handle promise messages if (msg instanceof PromiseMessage - && (((STracingPromise) ((PromiseMessage) msg).getPromise()).getResolvingActor() != expected.getResolver())) { + && msg.getMessageId() != expected.getMessageId()) { return false; } @@ -517,7 +526,7 @@ public long getSender() { return sender; } - public long getResolver() { + public long getMessageId() { return resolver; }