private static void AddTimer(Timer timer, long delay) { #if DEBUG_TIMERS var originalDelay = delay; #endif delay = Math.Max(0, delay); var resolutionPowerOf2 = _tickRatePowerOf2; for (var i = 0; i < _ringLayers; i++) { var resolution = 1L << resolutionPowerOf2; var nextResolutionPowerOf2 = resolutionPowerOf2 + _ringSizePowerOf2; var max = 1L << nextResolutionPowerOf2; if (delay < max) { var remaining = delay & (resolution - 1); var slot = (delay >> resolutionPowerOf2) + _ringIndexes[i] + (remaining > 0 ? 1 : 0); // Round up if we have a delay of 0 if (delay == 0) { slot++; remaining = 0; } if (slot >= _ringSize) { slot -= _ringSize; } timer.Attach(_rings[i][slot]); timer._remaining = remaining; timer._ring = i; timer._slot = (int)slot; _rings[i][slot] = timer; return; } // The remaining amount until we turn this ring delay -= resolution * (_ringSize - _ringIndexes[i]); resolutionPowerOf2 = nextResolutionPowerOf2; } // TODO: Handle timers > 17yrs #if DEBUG_TIMERS logger.Error($"Timer is more than max duration. ({originalDelay})"); #endif }