docs: public void flipPhase(long yieldTimeNsec) {
          if (!readerLock.isHeldByCurrentThread()) {
              throw new IllegalStateException("flipPhase() can only be called while holding the readerLock()");
          }
  
          boolean nextPhaseIsEven = (startEpoch < 0); // Current phase is odd...
  
          long initialStartValue;
          // First, clear currently unused [next] phase end epoch (to proper initial value for phase):
          if (nextPhaseIsEven) {
              initialStartValue = 0;
              evenEndEpochUpdater.lazySet(this, initialStartValue);
          } else {
              initialStartValue = Long.MIN_VALUE;
              oddEndEpochUpdater.lazySet(this, initialStartValue);
          }
  
          // Next, reset start value, indicating new phase, and retain value at flip:
          long startValueAtFlip = startEpochUpdater.getAndSet(this, initialStartValue);
  
          // Now, spin until previous phase end value catches up with start value at flip:
          boolean caughtUp = false;
          do {
              if (nextPhaseIsEven) {
                  caughtUp = (oddEndEpoch == startValueAtFlip);
              } else {
                  caughtUp = (evenEndEpoch == startValueAtFlip);
              }
              if (!caughtUp) {
                  if (yieldTimeNsec == 0) {
                      Thread.yield();
                  } else {
                      try {
                          TimeUnit.NANOSECONDS.sleep(yieldTimeNsec);
                      } catch (InterruptedException ex) {
                      }
                  }
              }
          } while (!caughtUp);
      }