MonotonicSystemClock.java

  1. /*
  2.  * Copyright (C) 2016, Google Inc. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.util.time;

  11. import static java.util.concurrent.TimeUnit.MICROSECONDS;
  12. import static java.util.concurrent.TimeUnit.MILLISECONDS;

  13. import java.time.Duration;
  14. import java.util.concurrent.TimeUnit;
  15. import java.util.concurrent.atomic.AtomicLong;

  16. /**
  17.  * A {@link org.eclipse.jgit.util.time.MonotonicClock} based on
  18.  * {@code System.currentTimeMillis}.
  19.  *
  20.  * @since 4.6
  21.  */
  22. public class MonotonicSystemClock implements MonotonicClock {
  23.     private static final AtomicLong before = new AtomicLong();

  24.     private static long nowMicros() {
  25.         long now = MILLISECONDS.toMicros(System.currentTimeMillis());
  26.         for (;;) {
  27.             long o = before.get();
  28.             long n = Math.max(o + 1, now);
  29.             if (before.compareAndSet(o, n)) {
  30.                 return n;
  31.             }
  32.         }
  33.     }

  34.     /** {@inheritDoc} */
  35.     @Override
  36.     public ProposedTimestamp propose() {
  37.         final long u = nowMicros();
  38.         return new ProposedTimestamp() {
  39.             @Override
  40.             public long read(TimeUnit unit) {
  41.                 return unit.convert(u, MICROSECONDS);
  42.             }

  43.             @Override
  44.             public void blockUntil(Duration maxWait) {
  45.                 // Assume system clock never goes backwards.
  46.             }
  47.         };
  48.     }
  49. }