private bool ScheduleCallbackHelper(Action <object> callback, object state) { // See if there's a free slot. Fortunately the overflow bit is simply lost. int slot = Interlocked.Add(ref _headTail, Bits.HiOne); // If this brings us to 'empty', then the IOTS used to be 'idle'. Remember that, and increment // again. This doesn't need to be in a loop, because until we call Post(), we can't go back to idle. bool wasIdle = Bits.Count(slot) == 0; if (wasIdle) { slot = Interlocked.Add(ref _headTail, Bits.HiOne); Fx.Assert(Bits.Count(slot) != 0, "IOTS went idle when it shouldn't have."); } // Check if we wrapped *around* to idle. if (Bits.Count(slot) == -1) { // Since the capacity is limited to 32k, this means we wrapped the array at least twice. That's bad // because headTail no longer knows how many work items we have - it looks like zero. This can // only happen if 32k threads come through here while one is swapped out. throw Fx.AssertAndThrowFatal("Head/Tail overflow!"); } bool queued = _slots[slot >> Bits.HiShift & SlotMask].TryEnqueueWorkItem(callback, state, out bool wrapped); if (wrapped) { // Wrapped around the circular buffer. Create a new, bigger IoThreadScheduler. var next = new IoThreadScheduler(Math.Min(_slots.Length * 2, MaximumCapacity), _slotsLowPri.Length); Interlocked.CompareExchange(ref current, next, this); } if (wasIdle) { // It's our responsibility to kick off the overlapped. overlapped.Post(this); } return(queued); }