private void doAccurateTimeMaintenance()

in util/src/main/java/com/epam/deltix/util/time/TimeKeeper.java [246:334]


    private void            doAccurateTimeMaintenance () {
        long                    sysNanoTime = nanoTime ();
        long                    cpuTimeNanos = sysNanoTime + offset;
        boolean                 sysClockChanged = getSystemTimeNoRollBack ();        

        if (!sysClockChanged && !isRunawayConfirmed ()) {  
            // Keep ticking
            set (cpuTimeNanos);
            return;
        }

        long                    cpuTimeMillis = cpuTimeNanos / M;
        long                    keeperAhead = cpuTimeMillis - lastTimeMillis;

        if (keeperAhead < 0) {
            runawayAt = IN_SYNC;
            //
            //  Assumption: system clock is never early. Therefore,
            //  adjust offset just enough so that model time catches up right away
            //
            cpuTimeNanos = lastTimeMillis * M;

            if (DEBUG) {
                System.out.printf (
                    "TK: + %,d ns\n",
                    cpuTimeNanos - sysNanoTime - offset
                );
            }

            offset = cpuTimeNanos - sysNanoTime;

            set (cpuTimeNanos);
            return;
        }

        if (keeperAhead == 0) {
            runawayAt = IN_SYNC;
            set (cpuTimeNanos);
            return;
        }
        //
        //  keeper is ahead by at least 1ms
        //
        if (runawayAt == IN_SYNC) {
            if (DEBUG) {
                System.out.print (
                    "TK: Ahead, raising runaway suspicion\n"                    
                );
            }
            
            runawayAt = lastTimeMillis + RUNAWAY_THRESHOLD_MS;
        }
        
        if (lastTimeMillis >= runawayAt) {
            //
            //  Keeper has been consistently ahead for RUNAWAY_THRESHOLD_MS.
            //  Keeper time can never go back, however.
            //
            long        maxCompliantTimeNanos = lastTimeMillis * M + (M - 1);
            long        minPossibleOffset = currentTimeNanos - sysNanoTime;
            long        targetOffset = maxCompliantTimeNanos - sysNanoTime;

            if (targetOffset >= minPossibleOffset) {
                if (DEBUG) {
                    System.out.printf (
                        "TK: -%,d (FINAL)\n",
                        offset - targetOffset
                    );
                }
                
                offset = targetOffset;
                runawayAt = IN_SYNC;
                
                set (maxCompliantTimeNanos);
            }
            else {
                if (DEBUG) {
                    System.out.printf (
                        "TK: STAYING PUT; -%,d (STILL RUNAWAY)\n", 
                        offset - minPossibleOffset
                    );
                }
                
                offset = minPossibleOffset;                          
            }
        }
        else
            set (cpuTimeNanos);
    }