javachronicle

Is DistributedUniqueTimeProvider from net.openhft.chronicle.bytes thread-safe?


Following the article https://chronicle.software/unique-timestamp-identifiers/, I have checked the implementation of DistributedUniqueTimeProvider.currentTimeNanos method.

    long time = provider.currentTimeNanos();
    long time0 = bytes.readVolatileLong(LAST_TIME);
    long timeN = timestampFor(time) + hostId;

    if (timeN > time0 && bytes.compareAndSwapLong(LAST_TIME, time0, timeN))
        return timeN;

    return currentTimeNanosLoop();

By default, it uses SystemTimeProvider

If we look inside net.openhft.chronicle.core.time.SystemTimeProvider#currentTimeNanos

    long nowNS = System.nanoTime();
    long nowMS = currentTimeMillis() * NANOS_PER_MILLI;
    long estimate = nowNS + delta;

    if (estimate < nowMS) {
        delta = nowMS - nowNS;
        return nowMS;

    } else if (estimate > nowMS + NANOS_PER_MILLI) {
        nowMS += NANOS_PER_MILLI;
        delta = nowMS - nowNS;
        return nowMS;
    }
    return estimate;

we can see that it uses non-volatile, non-atomic variable

    private long delta = 0;

So the question is: Is DistributedUniqueTimeProvider.currentTimeNanos thread-safe after all? If yes, why is that?


Solution

  • The value delta is an estimate of the difference between the wall clock and the monotonic clock. In the worst case, this could be up to 1 ms in different threads as there is always at least one check of milliseconds vs nanoseconds. However, when used with the DistributedUniqueTimeProvider which has a full memory barrier and it's own enforcement of a monotonically increasing value, it won't be significant

    The reason this memory barrier check is dropped is to reduce the cost of this operation by about 20%