示例#1
0
        public static void IOCallback(object scheduler)
        {
            IOThreadScheduler iots = scheduler as IOThreadScheduler;

            Contract.Assert(iots != null, "Overlapped completed without a scheduler.");

            SendOrPostCallback callback;
            object             state;

            try { }
            finally
            {
                // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                iots.CompletionCallback(out callback, out state);
            }

            bool found = true;

            while (found)
            {
                // The callback can be null if synchronization misses result in unsuable slots.  Keep going onto
                // the next slot in such cases until there are no more slots.
                callback?.Invoke(state);

                try { }
                finally
                {
                    // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                    found = iots.TryCoalesce(out callback, out state);
                }
            }
        }
示例#2
0
            private unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
            {
                Action <object>   action;
                object            obj2;
                IOThreadScheduler scheduler = this.scheduler;

                this.scheduler = null;
                try
                {
                }
                finally
                {
                    scheduler.CompletionCallback(out action, out obj2);
                }
                bool flag = true;

                while (flag)
                {
                    if (action != null)
                    {
                        action(obj2);
                    }
                    try
                    {
                        continue;
                    }
                    finally
                    {
                        flag = scheduler.TryCoalesce(out action, out obj2);
                    }
                }
            }
示例#3
0
        private bool ScheduleCallbackLowPriHelper(Action <object> callback, object state)
        {
            bool flag2;
            int  slot = Interlocked.Add(ref this.headTailLowPri, 0x10000);
            bool flag = false;

            if (Bits.CountNoIdle(slot) == 1)
            {
                int headTail = this.headTail;
                if (Bits.Count(headTail) == -1)
                {
                    int num3 = Interlocked.CompareExchange(ref this.headTail, headTail + 0x10000, headTail);
                    if (headTail == num3)
                    {
                        flag = true;
                    }
                }
            }
            if (Bits.CountNoIdle(slot) == 0)
            {
                throw Fx.AssertAndThrowFatal("Low-priority Head/Tail overflow!");
            }
            bool flag3 = this.slotsLowPri[(slot >> 0x10) & this.SlotMaskLowPri].TryEnqueueWorkItem(callback, state, out flag2);

            if (flag2)
            {
                IOThreadScheduler scheduler = new IOThreadScheduler(this.slots.Length, Math.Min(this.slotsLowPri.Length * 2, 0x8000));
                Interlocked.CompareExchange <IOThreadScheduler>(ref current, scheduler, this);
            }
            if (flag)
            {
                this.overlapped.Post(this);
            }
            return(flag3);
        }
示例#4
0
 public void Post(IOThreadScheduler iots)
 {
     this.scheduler = iots;
     unsafe {
         ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped);
     }
 }
示例#5
0
        private bool ScheduleCallbackHelper(Action <object> callback, object state)
        {
            bool flag2;
            int  slot = Interlocked.Add(ref this.headTail, 0x10000);
            bool flag = Bits.Count(slot) == 0;

            if (flag)
            {
                slot = Interlocked.Add(ref this.headTail, 0x10000);
            }
            if (Bits.Count(slot) == -1)
            {
                throw Fx.AssertAndThrowFatal("Head/Tail overflow!");
            }
            bool flag3 = this.slots[(slot >> 0x10) & this.SlotMask].TryEnqueueWorkItem(callback, state, out flag2);

            if (flag2)
            {
                IOThreadScheduler scheduler = new IOThreadScheduler(Math.Min(this.slots.Length * 2, 0x8000), this.slotsLowPri.Length);
                Interlocked.CompareExchange <IOThreadScheduler>(ref current, scheduler, this);
            }
            if (flag)
            {
                this.overlapped.Post(this);
            }
            return(flag3);
        }
示例#6
0
        private bool ScheduleCallbackHelper(Action <object> callback, object state)
        {
            bool flag  = false;
            int  num   = Interlocked.Add(ref this.headTail, 0x10000);
            bool flag1 = IOThreadScheduler.Bits.Count(num) == 0;

            if (flag1)
            {
                num = Interlocked.Add(ref this.headTail, 0x10000);
            }
            if (IOThreadScheduler.Bits.Count(num) != -1)
            {
                bool flag2 = this.slots[num >> 16 & this.SlotMask].TryEnqueueWorkItem(callback, state, out flag);
                if (flag)
                {
                    IOThreadScheduler oThreadScheduler = new IOThreadScheduler(Math.Min((int)this.slots.Length * 2, 0x8000), (int)this.slotsLowPri.Length);
                    Interlocked.CompareExchange <IOThreadScheduler>(ref IOThreadScheduler.current, oThreadScheduler, this);
                }
                if (flag1)
                {
                    this.overlapped.Post(this);
                }
                return(flag2);
            }
            else
            {
                throw Fx.AssertAndThrowFatal("Head/Tail overflow!");
            }
        }
示例#7
0
            void IOCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
            {
                // Unhook the IOThreadScheduler ASAP to prevent it from leaking.
                IOThreadScheduler iots = this.scheduler;

                this.scheduler = null;
                Fx.Assert(iots != null, "Overlapped completed without a scheduler.");

                Action <object> callback;
                object          state;

                try { } finally
                {
                    // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                    iots.CompletionCallback(out callback, out state);
                }

                bool found = true;

                while (found)
                {
                    // The callback can be null if synchronization misses result in unsuable slots.  Keep going onto
                    // the next slot in such cases until there are no more slots.
                    if (callback != null)
                    {
                        callback(state);
                    }

                    try { } finally
                    {
                        // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                        found = iots.TryCoalesce(out callback, out state);
                    }
                }
            }
示例#8
0
            public void Post(IOThreadScheduler iots)
            {
                Fx.Assert(this.scheduler == null, "Post called on an overlapped that is already posted.");
                Fx.Assert(iots != null, "Post called with a null scheduler.");

                this.scheduler = iots;
                ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped);
            }
示例#9
0
            public void Post(IOThreadScheduler iots)
            {
                Fx.Assert(_scheduler == null, "Post called on an overlapped that is already posted.");
                Fx.Assert(iots != null, "Post called with a null scheduler.");

                _scheduler = iots;
                _postDelegate();
            }
示例#10
0
        bool ScheduleCallbackLowPriHelper(Action <object> callback, object state)
        {
            // See if there's a free slot.  Fortunately the overflow bit is simply lost.
            int slot = Interlocked.Add(ref this.headTailLowPri, Bits.HiOne);

            // If this is the first low-priority work item, make sure we're not idle.
            bool wasIdle = false;

            if (Bits.CountNoIdle(slot) == 1)
            {
                // Since Interlocked calls create a full thread barrier, this will read the value of headTail
                // at the time of the Interlocked.Add or later.  The invariant is that the IOTS is unidle at some
                // point after the Add.
                int ht = this.headTail;

                if (Bits.Count(ht) == -1)
                {
                    // Use a temporary local here to store the result of the Interlocked.CompareExchange.  This
                    // works around a codegen
                    int interlockedResult = Interlocked.CompareExchange(ref this.headTail, ht + Bits.HiOne, ht);
                    if (ht == interlockedResult)
                    {
                        wasIdle = true;
                    }
                }
            }

            // Check if we wrapped *around* to empty.
            if (Bits.CountNoIdle(slot) == 0)
            {
                // 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("Low-priority Head/Tail overflow!");
            }

            bool wrapped;
            bool queued = this.slotsLowPri[slot >> Bits.HiShift & SlotMaskLowPri].TryEnqueueWorkItem(
                callback, state, out wrapped);

            if (wrapped)
            {
                IOThreadScheduler next =
                    new IOThreadScheduler(this.slots.Length, Math.Min(this.slotsLowPri.Length * 2, MaximumCapacity));
                Interlocked.CompareExchange <IOThreadScheduler>(ref IOThreadScheduler.current, next, this);
            }

            if (wasIdle)
            {
                // It's our responsibility to kick off the overlapped.
                this.overlapped.Post(this);
            }

            return(queued);
        }
 private static void ScheduleCallback(Action <object> callback, object state, bool lowPriority)
 {
     if (lowPriority)
     {
         IOThreadScheduler.ScheduleCallbackLowPriNoFlow(callback, state);
     }
     else
     {
         IOThreadScheduler.ScheduleCallbackNoFlow(callback, state);
     }
 }
示例#12
0
 static void ScheduleCallback(Action <object> callback, object state, bool lowPriority)
 {
     Fx.Assert(callback != null, "Cannot schedule a null callback");
     if (lowPriority)
     {
         IOThreadScheduler.ScheduleCallbackLowPriNoFlow(callback, state);
     }
     else
     {
         IOThreadScheduler.ScheduleCallbackNoFlow(callback, state);
     }
 }
示例#13
0
        // Returns true if successfully scheduled, false otherwise.
        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);
                Contract.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 wrapped;
            bool queued = _slots[slot >> Bits.HiShift & SlotMask].TryEnqueueWorkItem(callback, state, out wrapped);

            if (wrapped)
            {
                // Wrapped around the circular buffer.  Create a new, bigger IOThreadScheduler.
                IOThreadScheduler next =
                    new IOThreadScheduler(Math.Min(_slots.Length * 2, MaximumCapacity));
                Interlocked.CompareExchange(ref s_current, next, this);
            }

            if (wasIdle)
            {
                // It's our responsibility to kick off the runner thread.
                _overlapped.Post(this);
            }

            return(queued);
        }
示例#14
0
        private bool ScheduleCallbackLowPriHelper(Action <object> callback, object state)
        {
            bool flag  = false;
            int  num   = Interlocked.Add(ref this.headTailLowPri, 0x10000);
            bool flag1 = false;

            if (IOThreadScheduler.Bits.CountNoIdle(num) == 1)
            {
                int num1 = this.headTail;
                if (IOThreadScheduler.Bits.Count(num1) == -1)
                {
                    int num2 = Interlocked.CompareExchange(ref this.headTail, num1 + 0x10000, num1);
                    if (num1 == num2)
                    {
                        flag1 = true;
                    }
                }
            }
            if (IOThreadScheduler.Bits.CountNoIdle(num) != 0)
            {
                bool flag2 = this.slotsLowPri[num >> 16 & this.SlotMaskLowPri].TryEnqueueWorkItem(callback, state, out flag);
                if (flag)
                {
                    IOThreadScheduler oThreadScheduler = new IOThreadScheduler((int)this.slots.Length, Math.Min((int)this.slotsLowPri.Length * 2, 0x8000));
                    Interlocked.CompareExchange <IOThreadScheduler>(ref IOThreadScheduler.current, oThreadScheduler, this);
                }
                if (flag1)
                {
                    this.overlapped.Post(this);
                }
                return(flag2);
            }
            else
            {
                throw Fx.AssertAndThrowFatal("Low-priority Head/Tail overflow!");
            }
        }
示例#15
0
        bool ScheduleCallbackLowPriHelper(Action<object> callback, object state)
        {
            // See if there's a free slot.  Fortunately the overflow bit is simply lost.
            int slot = Interlocked.Add(ref this.headTailLowPri, Bits.HiOne);

            // If this is the first low-priority work item, make sure we're not idle.
            bool wasIdle = false;
            if (Bits.CountNoIdle(slot) == 1)
            {
                // Since Interlocked calls create a full thread barrier, this will read the value of headTail
                // at the time of the Interlocked.Add or later.  The invariant is that the IOTS is unidle at some
                // point after the Add.
                int ht = this.headTail;

                if (Bits.Count(ht) == -1)
                {
                    // Use a temporary local here to store the result of the Interlocked.CompareExchange.  This
                    // works around a codegen 
                    int interlockedResult = Interlocked.CompareExchange(ref this.headTail, ht + Bits.HiOne, ht);
                    if (ht == interlockedResult)
                    {
                        wasIdle = true;
                    }
                }
            }

            // Check if we wrapped *around* to empty.
            if (Bits.CountNoIdle(slot) == 0)
            {
                // 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("Low-priority Head/Tail overflow!");
            }

            bool wrapped;
            bool queued = this.slotsLowPri[slot >> Bits.HiShift & SlotMaskLowPri].TryEnqueueWorkItem(
                callback, state, out wrapped);

            if (wrapped)
            {
                IOThreadScheduler next =
                    new IOThreadScheduler(this.slots.Length, Math.Min(this.slotsLowPri.Length * 2, MaximumCapacity));
                Interlocked.CompareExchange<IOThreadScheduler>(ref IOThreadScheduler.current, next, this);
            }

            if (wasIdle)
            {
                // It's our responsibility to kick off the overlapped.
                this.overlapped.Post(this);
            }

            return queued;
        }
示例#16
0
 static IOThreadScheduler()
 {
     IOThreadScheduler.current = new IOThreadScheduler(32, 32);
 }
示例#17
0
		private bool ScheduleCallbackHelper(Action<object> callback, object state)
		{
			bool flag = false;
			int num = Interlocked.Add(ref this.headTail, 0x10000);
			bool flag1 = IOThreadScheduler.Bits.Count(num) == 0;
			if (flag1)
			{
				num = Interlocked.Add(ref this.headTail, 0x10000);
			}
			if (IOThreadScheduler.Bits.Count(num) != -1)
			{
				bool flag2 = this.slots[num >> 16 & this.SlotMask].TryEnqueueWorkItem(callback, state, out flag);
				if (flag)
				{
					IOThreadScheduler oThreadScheduler = new IOThreadScheduler(Math.Min((int)this.slots.Length * 2, 0x8000), (int)this.slotsLowPri.Length);
					Interlocked.CompareExchange<IOThreadScheduler>(ref IOThreadScheduler.current, oThreadScheduler, this);
				}
				if (flag1)
				{
					this.overlapped.Post(this);
				}
				return flag2;
			}
			else
			{
				throw Fx.AssertAndThrowFatal("Head/Tail overflow!");
			}
		}
示例#18
0
		private bool ScheduleCallbackLowPriHelper(Action<object> callback, object state)
		{
			bool flag = false;
			int num = Interlocked.Add(ref this.headTailLowPri, 0x10000);
			bool flag1 = false;
			if (IOThreadScheduler.Bits.CountNoIdle(num) == 1)
			{
				int num1 = this.headTail;
				if (IOThreadScheduler.Bits.Count(num1) == -1)
				{
					int num2 = Interlocked.CompareExchange(ref this.headTail, num1 + 0x10000, num1);
					if (num1 == num2)
					{
						flag1 = true;
					}
				}
			}
			if (IOThreadScheduler.Bits.CountNoIdle(num) != 0)
			{
				bool flag2 = this.slotsLowPri[num >> 16 & this.SlotMaskLowPri].TryEnqueueWorkItem(callback, state, out flag);
				if (flag)
				{
					IOThreadScheduler oThreadScheduler = new IOThreadScheduler((int)this.slots.Length, Math.Min((int)this.slotsLowPri.Length * 2, 0x8000));
					Interlocked.CompareExchange<IOThreadScheduler>(ref IOThreadScheduler.current, oThreadScheduler, this);
				}
				if (flag1)
				{
					this.overlapped.Post(this);
				}
				return flag2;
			}
			else
			{
				throw Fx.AssertAndThrowFatal("Low-priority Head/Tail overflow!");
			}
		}
 private bool ScheduleCallbackHelper(Action<object> callback, object state)
 {
     bool flag2;
     int slot = Interlocked.Add(ref this.headTail, 0x10000);
     bool flag = Bits.Count(slot) == 0;
     if (flag)
     {
         slot = Interlocked.Add(ref this.headTail, 0x10000);
     }
     if (Bits.Count(slot) == -1)
     {
         throw Fx.AssertAndThrowFatal("Head/Tail overflow!");
     }
     bool flag3 = this.slots[(slot >> 0x10) & this.SlotMask].TryEnqueueWorkItem(callback, state, out flag2);
     if (flag2)
     {
         IOThreadScheduler scheduler = new IOThreadScheduler(Math.Min(this.slots.Length * 2, 0x8000), this.slotsLowPri.Length);
         Interlocked.CompareExchange<IOThreadScheduler>(ref current, scheduler, this);
     }
     if (flag)
     {
         this.overlapped.Post(this);
     }
     return flag3;
 }
 public unsafe void Post(IOThreadScheduler iots)
 {
     this.scheduler = iots;
     ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped);
 }
 private unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
 {
     Action<object> action;
     object obj2;
     IOThreadScheduler scheduler = this.scheduler;
     this.scheduler = null;
     try
     {
     }
     finally
     {
         scheduler.CompletionCallback(out action, out obj2);
     }
     bool flag = true;
     while (flag)
     {
         if (action != null)
         {
             action(obj2);
         }
         try
         {
             continue;
         }
         finally
         {
             flag = scheduler.TryCoalesce(out action, out obj2);
         }
     }
 }
 private bool ScheduleCallbackLowPriHelper(Action<object> callback, object state)
 {
     bool flag2;
     int slot = Interlocked.Add(ref this.headTailLowPri, 0x10000);
     bool flag = false;
     if (Bits.CountNoIdle(slot) == 1)
     {
         int headTail = this.headTail;
         if (Bits.Count(headTail) == -1)
         {
             int num3 = Interlocked.CompareExchange(ref this.headTail, headTail + 0x10000, headTail);
             if (headTail == num3)
             {
                 flag = true;
             }
         }
     }
     if (Bits.CountNoIdle(slot) == 0)
     {
         throw Fx.AssertAndThrowFatal("Low-priority Head/Tail overflow!");
     }
     bool flag3 = this.slotsLowPri[(slot >> 0x10) & this.SlotMaskLowPri].TryEnqueueWorkItem(callback, state, out flag2);
     if (flag2)
     {
         IOThreadScheduler scheduler = new IOThreadScheduler(this.slots.Length, Math.Min(this.slotsLowPri.Length * 2, 0x8000));
         Interlocked.CompareExchange<IOThreadScheduler>(ref current, scheduler, this);
     }
     if (flag)
     {
         this.overlapped.Post(this);
     }
     return flag3;
 }
 public override void Post(SendOrPostCallback d, object state)
 {
     IOThreadScheduler.ScheduleCallbackNoFlow(d, state);
 }
示例#24
0
		static IOThreadScheduler()
		{
			IOThreadScheduler.current = new IOThreadScheduler(32, 32);
		}
示例#25
0
        // Returns true if successfully scheduled, false otherwise.
        bool ScheduleCallbackHelper(SendOrPostCallback 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);
                Contract.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 wrapped;
            bool queued = slots[slot >> Bits.HiShift & SlotMask].TryEnqueueWorkItem(callback, state, out wrapped);

            if (wrapped)
            {
                // Wrapped around the circular buffer.  Create a new, bigger IOThreadScheduler.
                IOThreadScheduler next =
                    new IOThreadScheduler(Math.Min(slots.Length * 2, MaximumCapacity));
                Interlocked.CompareExchange<IOThreadScheduler>(ref current, next, this);
            }

            if (wasIdle)
            {
                // It's our responsibility to kick off the runner thread.
                Task.Factory.StartNew(IOCallback, this, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            }

            return queued;
        }
示例#26
0
            void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
            {
                // Unhook the IOThreadScheduler ASAP to prevent it from leaking.
                IOThreadScheduler iots = this.scheduler;
                this.scheduler = null;
                Fx.Assert(iots != null, "Overlapped completed without a scheduler.");

                Action<object> callback;
                object state;
                try { } finally
                {
                    // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                    iots.CompletionCallback(out callback, out state);
                }

                bool found = true;
                while (found)
                {
                    // The callback can be null if synchronization misses result in unsuable slots.  Keep going onto
                    // the next slot in such cases until there are no more slots.
                    if (callback != null)
                    {
                        callback(state);
                    }

                    try { } finally
                    {
                        // Called in a finally because it needs to run uninterrupted in order to maintain consistency.
                        found = iots.TryCoalesce(out callback, out state);
                    }
                }
            }
示例#27
0
            public void Post(IOThreadScheduler iots)
            {
                Fx.Assert(this.scheduler == null, "Post called on an overlapped that is already posted.");
                Fx.Assert(iots != null, "Post called with a null scheduler.");

                this.scheduler = iots;
                ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped);
            }
示例#28
0
 private static void ScheduleCallback(Action <object> callback, object state)
 {
     Fx.Assert(callback != null, "Cannot schedule a null callback");
     IOThreadScheduler.ScheduleCallbackNoFlow(callback, state);
 }