Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define and enforce locking order during runtime #8014

Merged

Conversation

JaroslavTulach
Copy link
Member

@JaroslavTulach JaroslavTulach commented Oct 10, 2023

Pull Request Description

There are many locks in Locking trait. We need to define their ordering if we want to provably avoid deadlocks among them. Adding such ordering and runtime checks to make sure it is obeyed.

Important Notes

According to deadlock avoidance theory, ordering of locks avoids deadlocks as it prevents (random) incremental requests.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • All code follows the
    Scala,
  • All code has been tested:
    • All unit tests continue to pass.

@JaroslavTulach JaroslavTulach added CI: No changelog needed Do not require a changelog entry for this PR. -compiler -language-server labels Oct 10, 2023
@JaroslavTulach JaroslavTulach self-assigned this Oct 10, 2023
logger.log(Level.SEVERE, msg, ex)
} catch {
case ise: IllegalStateException =>
// Thread using TruffleLogger has to have a current context or the TruffleLogger has to be bound to an engine
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simulate the problem:

enso$ git diff
diff --git engine/runtime-instrument-common/src/main/scala/org/enso/interpreter/instrument/execution/ReentrantLocking.scala engine/runtime-instrument-common/src/main/scala/org/enso/interpreter/instrument/execution/ReentrantLocking.scala
index 8cb4b0b5c4..0b84019fd0 100644
--- engine/runtime-instrument-common/src/main/scala/org/enso/interpreter/instrument/execution/ReentrantLocking.scala
+++ engine/runtime-instrument-common/src/main/scala/org/enso/interpreter/instrument/execution/ReentrantLocking.scala
@@ -153,6 +153,8 @@ class ReentrantLocking(logger: TruffleLogger) extends Locking {
 
   /** @inheritdoc */
   override def acquireFileLock(file: File): Long = {
+    assertNotLocked(compilationLock, false, "wrong")
+    assertNotLocked(compilationLock, true, "wrong")
     // cannot have pendings lock as of EnsureCompiledJob.applyEdits
     assertNotLocked(
       pendingEditsLock,
$ sbt  runtime-with-instruments/test

and one gets:

java.lang.IllegalStateException: Thread using TruffleLogger has to have a current context or the TruffleLogger has to be bound to an engine., took 0.025 sec
[error]     at com.oracle.truffle.api.TruffleLogger$LoggerCache.noContext(TruffleLogger.java:1011)
[error]     at com.oracle.truffle.api.TruffleLogger$LoggerCache.isLoggable(TruffleLogger.java:993)
[error]     at com.oracle.truffle.api.TruffleLogger.isLoggableSlowPath(TruffleLogger.java:727)
[error]     at com.oracle.truffle.api.TruffleLogger.isLoggable(TruffleLogger.java:722)
[error]     at com.oracle.truffle.api.TruffleLogger.log(TruffleLogger.java:544)
[error]     at org.enso.interpreter.instrument.command.SynchronousCommand.execute(SynchronousCommand.scala:30)
[error]     at org.enso.interpreter.instrument.command.SynchronousCommand.execute(SynchronousCommand.scala:11)
[error]     at org.enso.interpreter.instrument.execution.CommandExecutionEngine.invoke(CommandExecutionEngine.scala:63)
[error]     at org.enso.interpreter.instrument.Handler.onMessage(Handler.scala:128)
[error]     at org.enso.interpreter.instrument.Endpoint.$anonfun$sendBinary$1(Handler.scala:66)
[error]     at org.enso.interpreter.instrument.Endpoint.$anonfun$sendBinary$1$adapted(Handler.scala:64)
[error]     at scala.Option.foreach(Option.scala:437)
[error]     at org.enso.interpreter.instrument.Endpoint.sendBinary(Handler.scala:64)
[error]     at com.oracle.truffle.api.instrumentation.TruffleInstrument$Env$MessageTransportProxy$MessageEndpointProxy.sendBinary(TruffleInstrument.java:1090)
[error]     at org.enso.interpreter.test.instrument.RuntimeServerEmulator.sendToRuntime(RuntimeServerEmulator.scala:53)
[error]     at org.enso.interpreter.test.instrument.RuntimeServerTest$TestContext.send(RuntimeServerTest.scala:94)
[error]     at org.enso.interpreter.test.instrument.IncrementalUpdatesTest.sendUpdatesWhenFunctionBodyIsChanged(IncrementalUpdatesTest.java:202)
[error]     at org.enso.interpreter.test.instrument.IncrementalUpdatesTest.sendUpdatesWhenFunctionBodyIsChangedBySettingValue(IncrementalUpdatesTest.java:150)
[error]     at org.enso.interpreter.test.instrument.IncrementalUpdatesTest.sendUpdatesWhenTextIsChangedBySettingValue(IncrementalUpdatesTest.java:105)

maybe we should be using normal logger and not Truffle logger here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This remains an open question, @hubertp: Shall we use regular, non-truffle logger here?

Copy link
Collaborator

@hubertp hubertp Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, very much so #8147 (better to file a separate ticket or the problem will get lost).

@JaroslavTulach JaroslavTulach changed the title Wip/jtulach/ensure lock ordering during runtime 7898 Define and enforce locking order during runtime Oct 10, 2023
@JaroslavTulach JaroslavTulach merged commit ef76df4 into develop Oct 11, 2023
@JaroslavTulach JaroslavTulach deleted the wip/jtulach/EnsureLockOrderingDuringRuntime_7898 branch October 11, 2023 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-compiler -language-server CI: No changelog needed Do not require a changelog entry for this PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants