Exemple #1
0
        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
        }