private void logUnsuccessfulInterrupt(String methodName, long now, long timeoutAt, long waitMillis, int unsuccessfulAttempts) {
    System.err.printf(
      "[spock.lang.Timeout] Method '%s' has not stopped after timing out %1.2f seconds ago - interrupting. Next try in %1.2f seconds.\n%n",
      methodName,
      TimeUtil.toSeconds(Duration.ofNanos(now - timeoutAt)),
      waitMillis / 1000d
    );

    if (unsuccessfulAttempts <= configuration.maxInterruptAttemptsWithThreadDumps) {
      logThreadDumpOfCurrentJvm();
      configuration.interruptAttemptListeners.forEach(Runnable::run);

      if (unsuccessfulAttempts == configuration.maxInterruptAttemptsWithThreadDumps) {
        System.out.println("[spock.lang.Timeout] No further thread dumps will be logged and no timeout listeners will be run, as the number of unsuccessful interrupt attempts exceeds configured maximum of logged attempts");
      }
    }
  }
Times out a method invocation if it takes too long. The method invocation
will occur on the regular test framework thread. This can be important
for integration tests with thread-local state.

@author Peter Niederwieser
spock-core/src/main/java/org/spockframework/runtime/extension/builtin/TimeoutInterceptor.java