Пример #1
3
        public static void RunSpinLockTest0_Enter(int threadsCount, bool enableThreadIDs)
        {
            // threads array
            Task[] threads = new Task[threadsCount];
            //spinlock object
            SpinLock slock = new SpinLock(enableThreadIDs);
            // succeeded threads counter
            int succeeded = 0;
            // Semaphore used to make sure that there is no other threads in the critical section
            SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);

            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = Task.Run(delegate ()
                {
                    bool lockTaken = false;
                    try
                    {
                        slock.Enter(ref lockTaken);
                        //use semaphore to make sure that no other thread inside the critical section
                        if (!semaphore.Wait(0))
                        {
                            // This mean that there is another thread in the critical section
                            return;
                        }
                        succeeded++;
                        if (slock.IsThreadOwnerTrackingEnabled && !slock.IsHeldByCurrentThread)
                        {
                            // lock is obtained successfully
                            succeeded--;
                        }
                    }
                    catch
                    {
                        // decrement the count in case of exception
                        succeeded--;
                    }
                    finally
                    {
                        semaphore.Release();
                        if (lockTaken)
                        {
                            slock.Exit();
                        }
                    }
                });
            }
            // wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Wait();
            }
            // count must be equal to the threads count
            Assert.Equal(threadsCount, succeeded);
        }
Пример #2
0
        public static void EnterExit()
        {
            var sl = new SpinLock();
            Assert.True(sl.IsThreadOwnerTrackingEnabled);

            for (int i = 0; i < 4; i++)
            {
                Assert.False(sl.IsHeld);
                Assert.False(sl.IsHeldByCurrentThread);

                bool lockTaken = false;
                if (i % 2 == 0)
                    sl.Enter(ref lockTaken);
                else
                    sl.TryEnter(ref lockTaken);
                Assert.True(lockTaken);
                Assert.True(sl.IsHeld);
                Assert.True(sl.IsHeldByCurrentThread);
                Task.Factory.StartNew(() =>
                {
                    Assert.True(sl.IsHeld);
                    Assert.False(sl.IsHeldByCurrentThread);
                }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).GetAwaiter().GetResult();
                sl.Exit();
            }
        }
Пример #3
0
        private int _lockReleased; //0 : true | 1 : false


        public SpinLockBlock(SpinLock lockTarget)
        {
            _lockTarget = lockTarget;

            var lockTaken = false;

            _lockTarget.Enter(ref lockTaken);
            if (lockTaken)
            {
                _lockReleased = FALSE; // false
            }
        }
Пример #4
0
        public static void RunSpinLockTestExceptions()
        {
            SpinLock slock   = new SpinLock();
            bool     isTaken = true;

            Assert.Throws <ArgumentException>(() => slock.Enter(ref isTaken));
            // Failure Case: Enter didn't throw AE when isTaken is true

            slock = new SpinLock(false);
            Assert.Throws <InvalidOperationException>(() => { bool iHeld = slock.IsHeldByCurrentThread; });
            // Failure Case: IsHeldByCurrentThread didn't throw IOE when the thread tracking is disabled
        }
Пример #5
0
 public DisposableSpinLock(SpinLock thelock, bool tryLock)
 {
     this.mylock = thelock;
     if (tryLock)
     {
         mylock.TryEnter(ref isLocked);
     }
     else
     {
         mylock.Enter(ref isLocked);
     }
 }
Пример #6
0
        static void Main()
        {
#pragma warning disable 219
            int x = 0;
#pragma warning restore 219
            const int iterations = 10000000; // 10 миллионов

            // Note: Сколько времени займет инкремент x 10 миллионов раз?
            Stopwatch stopwatch = Stopwatch.StartNew();
            for (int i = 0; i < iterations; i++)
            {
                x++;
            }
            Console.WriteLine("Incrementing x: {0:N0}", stopwatch.ElapsedMilliseconds);

            // Note: Сколько времени займет инкремент x 10 миллионов раз, если
            // добавить вызов ничего не делающего метода?
            stopwatch.Restart();
            for (int i = 0; i < iterations; i++)
            {
                Dummy();
                x++;
                Dummy();
            }
            Console.WriteLine("Incrementing x in Dummy: {0:N0}", stopwatch.ElapsedMilliseconds);

            // Note: Сколько времени займет инкремент x 10 миллионов раз, если
            // добавить вызов неконкурирующего объекта SpinLock
            var spinLock = new SpinLock();
            stopwatch.Restart();
            for (int i = 0; i < iterations; i++)
            {
                bool lockTaken = false;
                spinLock.Enter(ref lockTaken);
                x++;
                spinLock.Exit();
            }
            Console.WriteLine("Incrementing x in SpinLock: {0:N0}", stopwatch.ElapsedMilliseconds);

            // Note: Сколько времени займет инкремент x 10 миллионов раз, если
            // добавить вызов неконкурирующего объекта SimpleWaitLock?
            using (var waitLock = new SimpleWaitLock())
            {
                stopwatch.Restart();
                for (int i = 0; i < iterations; i++)
                {
                    waitLock.Enter();
                    x++;
                    waitLock.Leave();
                }
                Console.WriteLine("Incrementing x in SimpleWaitLock: {0:N0}", stopwatch.ElapsedMilliseconds);
            }
        }
Пример #7
0
 public AsyncEntryBlockUC TryEnter()
 {
     using (SpinLock.Enter())
     {
         if (LockStatus == Status.Locked)
         {
             return(AsyncEntryBlockUC.RefusedEntry);
         }
         LockStatus = Status.Locked;
         return(new AsyncEntryBlockUC(ExclusiveEntry));
     }
 }
Пример #8
0
        /// <summary>
        /// Reads the scan code from the device
        /// </summary>
        protected void ReadScanCode()
        {
            spinLock.Enter();

            byte v = commandPort.Read8();

            AddToFIFO(v);

            HAL.DebugWrite(" scancode: " + v.ToString() + "   ");

            spinLock.Exit();
        }
Пример #9
0
        public bool TryGetInstance(bool throttle, float totalTime, out WrappedSoundEffectInstance result)
        {
            result = null;

            if (!(totalTime - lastPlayed > definition.MinimumTimeBetween) && throttle)
            {
                return(false);
            }

            bool lockTaken = false;

            spinLock.Enter(ref lockTaken);
            try
            {
                if (instanceCount < definition.InstanceLimit || !throttle)
                {
                    instanceCount++;
                }
                else
                {
                    return(false);
                }

                lastPlayed = totalTime;
            }
            finally
            {
                spinLock.Exit();
            }

            var pooledObject = instancePool.GetFree();

            result                 = pooledObject.Value;
            result.PoolObject      = pooledObject;
            result.Instance.Volume = MathHelper.Clamp(RandomExt.GetRandomFloat(definition.MinVolume, definition.MaxVolume), 0, 1);
            result.Instance.Pitch  = MathHelper.Clamp(RandomExt.GetRandomFloat(definition.MinPitchShift, definition.MaxPitchShift), 0, 1);


            return(true);
        }
        private BindingInfo?GetBindingForType(Type type, string?exchange, string?topic, Func <string, string, BindingInfo> createBindingFunc)
        {
            BindingInfo info;

            bool lockTaken = false;

            try
            {
                _spinLock.Enter(ref lockTaken);

                if (!_exchages.TryGetValue(type, out info))
                {
                    var attr = type.GetCustomAttribute <ExchangeRouteAttribute>();

                    if (exchange == null)
                    {
                        exchange = attr?.Exchange ?? _globalExchange;
                        if (exchange == null)
                        {
                            return(null);
                        }
                    }

                    if (topic == null)
                    {
                        topic = attr?.Topic ?? type.Name;
                    }
                    info = createBindingFunc(exchange, topic);
                    _exchages.Add(type, info);
                }
                return(info);
            }
            finally
            {
                if (lockTaken)
                {
                    _spinLock.Exit(true);
                }
            }
        }
Пример #11
0
            /// <summary>Takes an array from the bucket.  If the bucket is empty, returns null.</summary>
            internal T[] Rent()
            {
                T[][] buffers = _buffers;
                T[]   buffer  = null;

                // While holding the lock, grab whatever is at the next available index and
                // update the index.  We do as little work as possible while holding the spin
                // lock to minimize contention with other threads.  The try/finally is
                // necessary to properly handle thread aborts on platforms which have them.
                bool lockTaken = false, allocateBuffer = false;

                try
                {
                    _lock.Enter(ref lockTaken);

                    if (_index < buffers.Length)
                    {
                        buffer            = buffers[_index];
                        buffers[_index++] = null;
                        allocateBuffer    = buffer == null;
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        _lock.Exit(false);
                    }
                }

                // While we were holding the lock, we grabbed whatever was at the next available index, if
                // there was one.  If we tried and if we got back null, that means we hadn't yet allocated
                // for that slot, in which case we should do so now.
                if (allocateBuffer)
                {
                    buffer = new T[_bufferLength];
                }

                return(buffer);
            }
Пример #12
0
        public ActorReference ActorOf <T> (string name, object initializationData, Mailbox mailbox) where T : Actor, new ()
        {
            var reference = CreateActorReference(name, mailbox);

            Actor actor = new T();

            actor.Self = reference;

            reference.State = ActorStates.Initializing;
            actor.Initialize(initializationData);

            var lockTaken = false;

            try
            {
                Spin.Enter(ref lockTaken);

                reference.State = ActorStates.Idle;
                mailbox.EnqueueActor(actor);
            }
            finally
            {
                if (lockTaken)
                {
                    Spin.Exit(false);
                }
            }

            return(reference);
        }
        static void Main(string[] args)
        {
            // Create the bank account instance
            BankAccount account = new BankAccount();

            // Create the spinlock
            SpinLock spinlock = new SpinLock();

            // Create an array of tasks
            Task[] tasks = new Task[10];

            for (int i = 0; i < tasks.Length; i++)
            {
                // Create the new task
                tasks[i] = new Task(() =>
                {
                    // Enter a loop for 1000 balance updates
                    for (int j = 0; j < 1000; j++)
                    {
                        bool lockAcquired = false;
                        try
                        {
                            spinlock.Enter(ref lockAcquired);

                            // Update the balance
                            account.Balance++;
                        }
                        finally
                        {
                            if (lockAcquired)
                            {
                                spinlock.Exit();
                            }
                        }
                    }
                });

                // Start the new task
                tasks[i].Start();
            }

            // Wait for all of the tasks to complete
            Task.WaitAll(tasks);

            // Write out the counter value
            Console.WriteLine("Expected value {0}", 10000);
            Console.WriteLine("Balance: {0}", account.Balance);

            // Wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
        public void Execute(ITashaHousehold household, int iteration)
        {
            var  householdFitness = (float)EvaluateHousehold(household);
            bool taken            = false;

            FitnessUpdateLock.Enter(ref taken);
            Thread.MemoryBarrier();
            Fitness += householdFitness;
            if (taken)
            {
                FitnessUpdateLock.Exit(true);
            }
        }
Пример #15
0
        protected override void InternalEnqueue(Action action)
        {
            bool lockTaken = false;

            try
            {
                _spinLock.Enter(ref lockTaken);
                _queue.Add(action);
                if (!_flushPending)
                {
                    _taskFactory.StartNew(Flush);
                    _flushPending = true;
                }
            }
            finally
            {
                if (lockTaken)
                {
                    _spinLock.Exit();
                }
            }
        }
Пример #16
0
            public Memory Get()
            {
                var locked = false;

                try
                {
                    queueLock.Enter(ref locked);
                    if ((queue ?? throw new ObjectDisposedException(GetType().FullName)).Count > 0)
                    {
                        return(queue.Dequeue());
                    }
                }
                finally
                {
                    if (locked)
                    {
                        queueLock.Exit(false);
                    }
                }

                return(new Memory(this));
            }
            internal void Add(ITashaHousehold household)
            {
                var  expansionFactor = household.ExpansionFactor;
                bool taken           = false;

                Lock.Enter(ref taken);
                TotalExpansionFactor += expansionFactor;
                Households.Add(new ExpandedHousehold(household));
                if (taken)
                {
                    Lock.Exit(true);
                }
            }
Пример #18
0
        internal unsafe byte[]? Receive(TKey key,
                                        byte *src,
                                        int chunkLength,
                                        int chunkOffset,
                                        int length)
        {
            if (!_bigDataBuffers.TryGetValue(key, out Buffer bdb))
            {
                bool lockTaken = false;
                try
                {
                    _bigDataBufferLock.Enter(ref lockTaken);
                    if (!_bigDataBuffers.TryGetValue(key, out bdb))
                    {
                        _bigDataBuffers.Add(key, bdb = Create(key, length));
                    }
                }
                finally
                {
                    if (lockTaken)
                    {
                        _bigDataBufferLock.Exit(false);
                    }
                }
            }

            fixed(byte *dst = bdb._data)
            {
                Mem.Cpy(dst + chunkOffset, src, chunkLength);
            }

            if (bdb.AddBytes(chunkLength) == 0)
            {
                Remove(key);
                return(bdb._data);
            }

            return(null);
        }
Пример #19
0
        public static void MSSpinLock()
        {
            var ss2    = new SpinLock();
            var number = 0;

            Parallel.For(0, 100000, (i) =>
            {
                bool lockTaken = false;
                ss2.Enter(ref lockTaken);
                number++;
                ss2.Exit();
            });
        }
Пример #20
0
        /// <summary>
        /// Returns whether a new item can be accepted, and increments a counter if it can.
        /// </summary>
        bool TryAdd()
        {
            bool lockTaken = false;

            try {
                batchCountLock.Enter(ref lockTaken);

                if (options.MaxNumberOfGroups != -1 &&
                    numberOfGroups + batchCount / BatchSize >= options.MaxNumberOfGroups)
                {
                    return(false);
                }

                batchCount++;
                return(true);
            } finally {
                if (lockTaken)
                {
                    batchCountLock.Exit();
                }
            }
        }
Пример #21
0
		public void Enqueue(Action continuation) {
			bool lockTaken = false;

			try {
				gate.Enter(ref lockTaken);

				if (dequing) {
					// Ensure Capacity
					if (waitingList.Length == waitingListCount) {
						var newLength = waitingListCount * 2;

						if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength;

						var newArray = new Action[newLength];
						Array.Copy(waitingList, newArray, waitingListCount);
						waitingList = newArray;
					}

					waitingList[waitingListCount] = continuation;
					waitingListCount++;
				} else {
					// Ensure Capacity
					if (actionList.Length == actionListCount) {
						var newLength = actionListCount * 2;

						if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength;

						var newArray = new Action[newLength];
						Array.Copy(actionList, newArray, actionListCount);
						actionList = newArray;
					}

					actionList[actionListCount] = continuation;
					actionListCount++;
				}
			} finally {
				if (lockTaken) gate.Exit(false);
			}
		}
Пример #22
0
        public void SetParamValue(string variableName, string paramValue, object value)
        {
            if (_syncVariables.Contains(variableName))
            {
                _syncVarLock.EnterWriteLock();
                this._variables[variableName] = SetParamValue(paramValue, _variables[variableName], value);
                _syncVarLock.ExitWriteLock();
            }
            else
            {
                this._variables[variableName] = SetParamValue(paramValue, _variables[variableName], value);
            }

            // 监视变量值如果被更新,则添加到值更新列表中,在状态上报时上传该值
            if (_context.TraceVariables.Contains(variableName))
            {
                bool getlock = false;
                _keyVarLock.Enter(ref getlock);
                _keyVariables.Add(variableName);
                _keyVarLock.Exit();
            }
        }
Пример #23
0
        public void Enqueue(T item)
        {
            var lockTaken = false;

            try
            {
                _sync.Enter(ref lockTaken);
                if (_consumer.TryDequeue(out var tcs))
                {
                    Debug.Assert(_producer.Count == 0);
                    tcs.TrySetResult(item);
                }
                else
                {
                    _producer.Enqueue(item);
                }
            }
            finally
            {
                _sync.Exit(false);
            }
        }
Пример #24
0
        //TODO:  SPEED UP THESE ENQUEUES!

        /// <summary>
        /// Enqueues an element to the tail of the queue with locking.
        /// </summary>
        /// <param name="item">Dequeued element, if any.</param>
        /// <returns>True if an element could be dequeued, false otherwise.</returns>
        public void Enqueue(T item)
        {
            //bool taken = false;
            //locker.Enter(ref taken);
            locker.Enter();
            try
            {
                //Enqueues go to the tail only; it's like a queue.
                //head ----> tail

                if (count == array.Length)
                {
                    //Resize
                    //TODO: Better shift-resize
                    T[] oldArray = array;
                    array = new T[Math.Max(4, oldArray.Length * 2)];
                    //Copy the old first-end to the first part of the new array.
                    Array.Copy(oldArray, firstIndex, array, 0, oldArray.Length - firstIndex);
                    //Copy the old begin-first to the second part of the new array.
                    Array.Copy(oldArray, 0, array, oldArray.Length - firstIndex, firstIndex);
                    firstIndex = 0;
                    lastIndex  = count - 1;
                }


                lastIndex++;
                if (lastIndex == array.Length)
                {
                    lastIndex = 0;
                }
                array[lastIndex] = item;
                count++;
            }
            finally
            {
                //Console.WriteLine("file: ConcurrentDeque, line: {0}", 80);
                locker.Exit();
            }
        }
Пример #25
0
        /// <summary>
        /// AutoRegister method could be very complicated if it should call generic Register method...
        /// No sanity checks, called from inside.
        /// </summary>
        private void InternalRegister(Type interfaceType, Func <object> getInstanceFunc, List <Type> otherTypesWeAreDependingOn)
        {
            RegisteredTypeContainer c = new RegisteredTypeContainer(this, interfaceType, getInstanceFunc, otherTypesWeAreDependingOn);

            bool gotLock = false;

            try
            {
                syncRoot.Enter(ref gotLock);

                registeredTypes[interfaceType] = c;
            }
            finally
            {
                if (gotLock)
                {
                    syncRoot.Exit();
                }
            }

            System.Diagnostics.Debug.WriteLine("{0} registered for {1} with dependencies: {2}", getInstanceFunc.Method.ToString(), interfaceType.ToString(), (otherTypesWeAreDependingOn != null) ? String.Join(", ", otherTypesWeAreDependingOn.ToList().Select(t => t.ToString()).ToArray()) : "-"); //LOCSTR
        }
Пример #26
0
        // 异步flush的代码
        private void FlushCallBack(object obj)
        {
            bool getLock = false;

            try
            {
                WriteLock.Enter(ref getLock);
                if (NoDataInStream == _hasDataInStream)
                {
                    return;
                }
                LogStream.Flush();
                Thread.VolatileWrite(ref _hasDataInStream, NoDataInStream);
            }
            finally
            {
                if (getLock)
                {
                    WriteLock.Exit();
                }
            }
        }
Пример #27
0
        /// <summary>
        ///
        /// </summary>
        public void UpdateSlice(T dataT)
        {
            if (m_MultiThreadedCall == false && dataT.InLockProcessSlice() == false)
            {
                return;
            }

            m_LockSliceQueue.Enter();
            {
                m_SliceQueue.Enqueue(dataT);
            }
            m_LockSliceQueue.Exit();
        }
Пример #28
0
        private void TryComplete()
        {
            var lockTaken = false;

            _lock.Enter(ref lockTaken);

            if (_isFileWriterProcessorFinished && _isTreeWriterInfoTaskProcessorFinished)
            {
                Completed();
            }

            _lock.Exit();
        }
Пример #29
0
        public virtual Type CreateType(Type interfaceType, Type dynamicProxyBaseType)
        {
            Type ret;

            if (interfaceType == null)
            {
                throw new ArgumentNullException("interfaceType");
            }
            if (dynamicProxyBaseType == null)
            {
                throw new ArgumentNullException("dynamicProxyBaseType");
            }
            if (!TypeHelper.IsSubclassOf(dynamicProxyBaseType, typeof(DynamicProxy)))
            {
                throw new ArgumentException("dynamicProxyType must be a child of DynamicProxy"); //LOCSTR
            }

            string typeName = string.Concat(ownClassName, "+", interfaceType.FullName);
            bool   gotLock  = false;

            try
            {
                dynamicTypeEmitSyncRoot.Enter(ref gotLock);
                dynamicTypes.TryGetValue(typeName, out ret);

                if (ret == null)
                {
                    TypeBuilder tb = moduleBuilder.DefineType(typeName, TypeAttributes.Public);
                    tb.SetParent(dynamicProxyBaseType);
                    tb.AddInterfaceImplementation(interfaceType);

                    CreateConstructorBaseCalls(dynamicProxyBaseType, tb);

                    DynamicImplementInterface(new List <Type> {
                        interfaceType
                    }, new List <string>(), interfaceType, tb);
                    ret = tb.CreateType();

                    dynamicTypes.Add(typeName, ret);
                }
            }
            finally
            {
                if (gotLock)
                {
                    dynamicTypeEmitSyncRoot.Exit();
                }
            }

            return(ret);
        }
Пример #30
0
        public void RunBenchmark()
        {
            int       x         = 0;
            const int iteration = 10000000;

            Stopwatch sw = Stopwatch.StartNew();

            for (int i = 0; i < iteration; ++i)
            {
                ++x;
            }

            Console.WriteLine("{0:N0}", sw.ElapsedMilliseconds);

            sw.Restart();

            for (int i = 0; i < iteration; ++i)
            {
                DoNothing();
                x++;
                DoNothing();
            }

            Console.WriteLine(sw.ElapsedMilliseconds);

            SpinLock sl = new SpinLock(false);

            sw.Restart();
            for (int i = 0; i < iteration; ++i)
            {
                bool taken = false;
                sl.Enter(ref taken);
                x++;
                sl.Exit();
            }

            Console.WriteLine(sw.ElapsedMilliseconds);

            using (SimpleWaitLock simpleWaitLock = new SimpleWaitLock())
            {
                sw.Restart();
                for (int i = 0; i < iteration; ++i)
                {
                    simpleWaitLock.Enter();
                    x++;
                    simpleWaitLock.Leave();
                }

                Console.WriteLine(sw.ElapsedMilliseconds);
            }
        }
Пример #31
0
        public static void TestMethod2()
        {
            /*
             * 在实际的编程中需要注意的是:不要将SpinLock声明为只读字段,
             * 如果声明为只读字段,会导致每次调用都会返回一个SpinLock新副本,
             * 在多线程下,每个方法都会成功获得锁,而受到保护的临界区不会按照预期进行串行化。
             *
             */
            SpinLock sl = new SpinLock();

            CookTasks = new Task[Particpants];
            Thread.Sleep(4000);
            Stopwatch swTask1 = new Stopwatch();

            swTask1.Start();
            for (var taskIndex = 0; taskIndex < Particpants; taskIndex++)
            {
                CookTasks[taskIndex] = Task.Factory.StartNew((num) =>
                {
                    Parallel.For(1, 200000, (i) =>
                    {
                        var str        = "append message " + i;
                        bool lockTaken = false;
                        try
                        {
                            sl.Enter(ref lockTaken);
                            AppendStrMonitorLock.Append(str);
                        }
                        finally
                        {
                            if (lockTaken)
                            {
                                sl.Exit();
                            }
                        }
                    });
                }, taskIndex);
            }

            /*ContinueWhenAll 提供一组任务完成后 延续方法*/
            var finalTask = Task.Factory.ContinueWhenAll(CookTasks, (tasks) =>
            {
                /*等待任务完成*/
                Task.WaitAll(CookTasks);
                swTask1.Stop();
                Console.WriteLine($"采用SpinLock操作,字符串长度:{AppendStrMonitorLock.Length},耗时:{swTask1.ElapsedMilliseconds}");
                /*释放资源*/
            });

            Console.ReadLine();
        }
Пример #32
0
        public void QueueWorkItem([NotNull][Pooled] Action workItem)
        {
            bool lockTaken    = false;
            bool startNewTask = false;

            PooledDelegateHelper.AddReference(workItem);
            try
            {
                spinLock.Enter(ref lockTaken);
                workItems.Enqueue(workItem);
                workAvailable.Set();

                // We're only locking when potentially increasing aliveCount as we
                // don't want to go above our maximum amount of threads.
                int curBusyCount  = Interlocked.CompareExchange(ref busyCount, 0, 0);
                int curAliveCount = Interlocked.CompareExchange(ref aliveCount, 0, 0);
                if (curBusyCount + 1 >= curAliveCount && curAliveCount < maxThreadCount)
                {
                    // Start threads as busy otherwise only one thread will be created
                    // when calling this function multiple times in a row
                    Interlocked.Increment(ref busyCount);
                    Interlocked.Increment(ref aliveCount);
                    startNewTask = true;
                }
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit(true);
                }
            }
            // No point in wasting spins on the lock while creating the task
            if (startNewTask)
            {
                new Task(cachedTaskLoop, null, TaskCreationOptions.LongRunning).Start();
            }
        }
Пример #33
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;

            #region Recursive lock
            if (enableThreadIDs) // only valid if thread IDs are on
            {
                // Test recursive locks
                slock.Enter(ref lockTaken);
                try
                {
                    if (lockTaken)
                    {
                        bool dummy = false;
                        // reacquire the lock
                        slock.Enter(ref dummy);
                    }
                }
                catch (Exception ex)
                {
                    // LockRecursionException must be thrown
                    exception = ex;
                }
                if (lockTaken)
                {
                    slock.Exit();
                    if (exception == null || exception.GetType() != typeof(LockRecursionException))
                    {
                        Assert.True(false, string.Format("SpinLock.TryEnter() failed, recursive locks without exception"));
                    }
                    if (slock.IsHeldByCurrentThread)
                    {
                        Assert.True(false, string.Format("SpinLock.TryEnter() failed, IsHeld is true after calling Exit"));
                    }
                }
                else
                {
                    Assert.True(false, string.Format("LockRecursionException was not thrown?"));
                }
            }
            #endregion

            #region timeout > int.max
            // Test invalid argument handling, too long timeout
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(TimeSpan.MaxValue, ref lockTaken);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                Assert.True(false, string.Format(@"SpinLock.TryEnter() failed, timeout.Totalmilliseconds > int.maxValue
                 without throwing ArgumentOutOfRangeException " + exception));
            }
            #endregion

            #region Timeout > int.max
            // Test invalid argument handling, timeout < -1
            exception = null;
            try
            {
                lockTaken = false;
                slock.TryEnter(-2, ref lockTaken);
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            if (exception == null || exception.GetType() != typeof(ArgumentOutOfRangeException))
            {
                Assert.True(false, string.Format(@"SpinLock.TryEnter() failed, timeout < -1
                 without throwing ArgumentOutOfRangeException"));
            }
            #endregion
        }
Пример #34
0
        public static void RunSpinLockTestExceptions()
        {
            SpinLock slock = new SpinLock();
            bool isTaken = true;
            Assert.Throws<ArgumentException>(() => slock.Enter(ref isTaken));
            // Failure Case: Enter didn't throw AE when isTaken is true

            slock = new SpinLock(false);
            Assert.Throws<InvalidOperationException>(() => { bool iHeld = slock.IsHeldByCurrentThread; });
            // Failure Case: IsHeldByCurrentThread didn't throw IOE when the thread tracking is disabled
        }
Пример #35
0
 /// <summary>
 /// Test Exit
 /// </summary>
 /// <returns>True if succeeded, false otherwise</returns>
 private static void RunSpinLockTest4_Exit(bool enableThreadIDs)
 {
     SpinLock slock = new SpinLock(enableThreadIDs);
     bool lockTaken = false;
     slock.Enter(ref lockTaken);
     slock.Exit();
     if (enableThreadIDs)
     {
         Assert.False(slock.IsHeldByCurrentThread);
         Assert.Throws<SynchronizationLockException>(() => slock.Exit(true));
         Assert.Throws<SynchronizationLockException>(() => slock.Exit(false));
     }
     else
     {
         Assert.False(slock.IsHeld);
     }
 }
Пример #36
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;

            #region Recursive lock
            if (enableThreadIDs) // only valid if thread IDs are on
            {
                // Test recursive locks
                slock.Enter(ref lockTaken);
                Assert.True(lockTaken);
                Assert.Throws<LockRecursionException>(() => { bool dummy = false; slock.Enter(ref dummy); });

                slock.Exit();
                Assert.False(slock.IsHeldByCurrentThread);
            }
            #endregion

            #region timeout > int.max
            // Test invalid argument handling, too long timeout
            Assert.Throws<ArgumentOutOfRangeException>(() => { bool lt = false; slock.TryEnter(TimeSpan.MaxValue, ref lt); });

            #endregion timeout > int.max

            #region Timeout > int.max
            // Test invalid argument handling, timeout < -1
            Assert.Throws<ArgumentOutOfRangeException>(() => { bool lt = false; slock.TryEnter(-2, ref lt); });

            #endregion Timeout > int.max
        }
Пример #37
0
        /// <summary>
        /// Test Exit
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest4_Exit(bool enableThreadIDs)
        {
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;
            slock.Enter(ref lockTaken);
            slock.Exit();
            if (enableThreadIDs)
            {
                if (slock.IsHeldByCurrentThread)
                {
                    Assert.True(false, string.Format("SpinLock.Exit() failed, IsHeld is true after calling Exit"));
                }
            }
            else
            {
                if (slock.IsHeld)
                {
                    Assert.True(false, string.Format("SpinLock.Exit() failed, IsHeld is true after calling Exit"));
                }
            }

            for (int i = 0; i < 2; i++)
            {
                bool useBarrier = i == 0;
                // Calling Exit without owning the lock
                try
                {
                    slock.Exit(useBarrier);
                }
                catch (Exception ex)
                {
                    // SynchronizationLockException must be thrown
                    exception = ex;
                }
            }
            if (enableThreadIDs)
            {
                if (exception == null || exception.GetType() != typeof(SynchronizationLockException))
                {
                    Assert.True(false, string.Format(@"SpinLock.Exit() failed, calling Exit without owning the lock"));
                }
            }
        }