Exit() private method

private Exit ( ) : void
return void
Esempio n. 1
1
        private static void Main(string[] args)
        {
            SpinLock slock = new SpinLock(false);
            long sum1 = 0;
            long sum2 = 0;
            Parallel.For(0, 10000, i => { sum1 += i; });

            Parallel.For(0, 10000, i =>
            {
                bool lockTaken = false;
                try
                {
                    slock.Enter(ref lockTaken);
                    sum2 += i;
                }
                finally
                {
                    if (lockTaken)
                        slock.Exit(false);
                }
            });

            Console.WriteLine("Num1的值为:{0}", sum1);
            Console.WriteLine("Num2的值为:{0}", sum2);
        }
        // SpinLock работает на interlocked-конструкции
        // соответственно, применять можно, когда
        // время нахождения в критической секции минимально
        // и/или необходимо много блокировок
        public static void SpinLockUsage()
        {
            SpinLock spinLock = new SpinLock();
            bool lockTaken = false;

            spinLock.Enter(ref lockTaken);

            // код критической секции

            spinLock.Exit();
        }
 static void Main(string[] args)
 {
     var slock = new SpinLock();
     bool taken = false;
     try
     {
         slock.Enter(ref taken);
         DoSomething();
     }
     finally
     {
         if (taken) slock.Exit();
     }
 }
Esempio n. 4
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 {
#if SERVERSIDE
                _lock.Enter(ref lockTaken);
#endif
                if (_index < buffers.Length)
                {
                    buffer            = buffers[_index];
                    buffers[_index++] = null;
                    allocateBuffer    = buffer == null;
                }
            }
            finally {
#if SERVERSIDE
                if (lockTaken)
                {
                    _lock.Exit(false);
                }
#endif
            }

            // 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];
#if SERVERSIDE
                var log = ArrayPoolEventSource.Log;
                if (log.IsEnabled())
                {
                    log.BufferAllocated(buffer.GetHashCode(), _bufferLength, _poolId, Id,
                                        ArrayPoolEventSource.BufferAllocatedReason.Pooled);
                }
#endif
            }

            return(buffer);
        }
Esempio n. 5
0
        private static int CreateTypeIndexThreadSafe(Type type)
        {
            int  num2;
            bool lockTaken = false;

            try
            {
                s_CreateTypeLock.Enter(ref lockTaken);
                int index = FindTypeIndex(type, s_Count);
                if (index != -1)
                {
                    num2 = index;
                }
                else
                {
                    s_Count++;
                    index          = s_Count;
                    s_Types[index] = BuildComponentType(type);
                    num2           = index;
                }
            }
            finally
            {
                if (lockTaken)
                {
                    s_CreateTypeLock.Exit(true);
                }
            }
            return(num2);
        }
Esempio n. 6
0
        private void WriteToFile()
        {
            bool isLockTaken = false;

            spin.Enter(ref isLockTaken);
            File.AppendAllText(_fileName, $"{nameof(SpinLock)}: {DateTime.Now:hh:mm:ss:ffff} {Environment.NewLine}");
            spin.Exit(false);
        }
		public void SemanticCorrectnessTest ()
		{
			sl = new SpinLock (false);

			bool taken = false;
			bool taken2 = false;

			sl.Enter (ref taken);
			Assert.IsTrue (taken, "#1");
			sl.TryEnter (ref taken2);
			Assert.IsFalse (taken2, "#2");
			sl.Exit ();

			sl.TryEnter (ref taken2);
			Assert.IsTrue (taken2, "#3");
		}
Esempio n. 8
0
        public void WithLock(Action action)
        {
            bool lockAcquired = false;

            try
            {
                _lock.Enter(ref lockAcquired);
                action();
            }
            finally
            {
                if (lockAcquired)
                {
                    _lock.Exit(true);
                }
            }
        }
        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 < 10; i++) {
                // create a 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 = account.Balance + 1;
                        } 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}, Balance: {1}",
                10000, account.Balance);

            // wait for input before exiting
            Console.WriteLine("Press enter to finish");
            Console.ReadLine();
        }
Esempio n. 10
0
            public void LocalPush(IThreadPoolWorkItem obj)
            {
                int tail = m_tailIndex;

                // We're going to increment the tail; if we'll overflow, then we need to reset our counts
                if (tail == int.MaxValue)
                {
                    bool lockTaken = false;
                    try
                    {
                        m_foreignLock.Enter(ref lockTaken);

                        if (m_tailIndex == int.MaxValue)
                        {
                            //
                            // Rather than resetting to zero, we'll just mask off the bits we don't care about.
                            // This way we don't need to rearrange the items already in the queue; they'll be found
                            // correctly exactly where they are.  One subtlety here is that we need to make sure that
                            // if head is currently < tail, it remains that way.  This happens to just fall out from
                            // the bit-masking, because we only do this if tail == int.MaxValue, meaning that all
                            // bits are set, so all of the bits we're keeping will also be set.  Thus it's impossible
                            // for the head to end up > than the tail, since you can't set any more bits than all of
                            // them.
                            //
                            m_headIndex = m_headIndex & m_mask;
                            m_tailIndex = tail = m_tailIndex & m_mask;
                            Debug.Assert(m_headIndex <= m_tailIndex);
                        }
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            m_foreignLock.Exit(useMemoryBarrier: true);
                        }
                    }
                }

                // When there are at least 2 elements' worth of space, we can take the fast path.
                if (tail < m_headIndex + m_mask)
                {
                    Volatile.Write(ref m_array[tail & m_mask], obj);
                    m_tailIndex = tail + 1;
                }
                else
                {
                    // We need to contend with foreign pops, so we lock.
                    bool lockTaken = false;
                    try
                    {
                        m_foreignLock.Enter(ref lockTaken);

                        int head  = m_headIndex;
                        int count = m_tailIndex - m_headIndex;

                        // If there is still space (one left), just add the element.
                        if (count >= m_mask)
                        {
                            // We're full; expand the queue by doubling its size.
                            var newArray = new IThreadPoolWorkItem[m_array.Length << 1];
                            for (int i = 0; i < m_array.Length; i++)
                            {
                                newArray[i] = m_array[(i + head) & m_mask];
                            }

                            // Reset the field values, incl. the mask.
                            m_array     = newArray;
                            m_headIndex = 0;
                            m_tailIndex = tail = count;
                            m_mask      = (m_mask << 1) | 1;
                        }

                        Volatile.Write(ref m_array[tail & m_mask], obj);
                        m_tailIndex = tail + 1;
                    }
                    finally
                    {
                        if (lockTaken)
                        {
                            m_foreignLock.Exit(useMemoryBarrier: false);
                        }
                    }
                }
            }
Esempio n. 11
0
        string getFileName()
        {
            //  Find name of database file
            try
            {
                //string databaseFilePath = (string)ConfigurationManager.AppSettings["databaseFile"];

                string databaseFilePath = Properties.Settings.Default.databaseFile;

                if (databaseFilePath == null || databaseFilePath.Length == 0)
                {
                    throw new Exception("No database file path exists in user settings");
                }

                bool done = false;

                string messageToDisplay = "An Acry database has been used on this user's profile before.  The database was:\n\n" + databaseFilePath + "\n\nWould you like to continue to use that data file?";

                //  We need to ask the user a yes/no question, but we are running on the background worker thread.
                //  Init the Messagebox with a value that a yes/no could never give
                MessageBoxResult usrRslt = MessageBoxResult.None;

                //  Outermost loop that forces the worker to raise a single request to the UI thread and then wait in a loop
                do
                {
                    bool slaveHasLock = false;

                    //  Tell the program dispatcher to get the main thread to handle the UI dialog
                    this.Dispatcher.BeginInvoke((Action)(() =>
                    {
                        bool lockAcq = false;
                        //   Grab the spinlock
                        usrLock.Enter(ref lockAcq);
                        //   If we have the spinlock, update the value of usrRslt with the response
                        if (lockAcq)
                        {
                            usrRslt = System.Windows.MessageBox.Show(messageToDisplay, "Acry Database file found", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Question);
                        }
                        usrLock.Exit();
                    }
                                                         ));

                    do
                    {
                        //   After queueing the work for the main thread the worker thread enters here and tries to grab the spinlock
                        usrLock.Enter(ref slaveHasLock);
                        //   If we have the lock (must be checked first before checking value of usrRslt to ensure sync with main thread) then proceed with our logic
                        if (slaveHasLock && usrRslt != MessageBoxResult.None)
                        {
                            switch (usrRslt)
                            {
                            case System.Windows.MessageBoxResult.Yes:
                                //   Make sure we release the lock before we return
                                usrLock.Exit();
                                return(databaseFilePath);

                            case System.Windows.MessageBoxResult.No:
                                done = true;
                                break;

                            default:
                                acryWrite("Invalid response.");
                                done = true;
                                break;
                            }
                        }
                        //   Release the lock
                        usrLock.Exit();
                        slaveHasLock = false;
                    } while (!done);
                } while (!done);
                throw new Exception("A new database file must be selected!");
            }
            catch (Exception ex)
            {
                //  For one reason or another we cannot find the database file.  Select a new one.
                acryWrite(ex.Message, true);

                acryWrite("Please select database file");

                //  Set the file name to something impossible
                string toBeOutput = "merp";

                //  Ask the dispatcher to send the main thread to go get the file name
                this.Dispatcher.BeginInvoke((Action)(() =>
                {
                    bool haveLock = false;
                    usrLock.Enter(ref haveLock);
                    if (haveLock)
                    {
                        toBeOutput = getNewFilePath();
                    }
                    usrLock.Exit();
                }
                                                     ));

                bool done = false;

                //  Send the worker thread into a look of acquiring the lock and checking the output
                do
                {
                    bool haveLock = false;
                    usrLock.Enter(ref haveLock);
                    if (haveLock && !toBeOutput.Equals("merp"))
                    {
                        usrLock.Exit();
                        done = true;
                    }
                    else
                    {
                        usrLock.Exit();
                        System.Threading.Thread.Sleep(100);
                    }
                } while (!done);

                return(toBeOutput);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Test SpinLock.Enter by launching n threads that increment a variable inside a critical section
        /// the final count variable must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest0_Enter(int threadsCount, bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.Enter(" + threadsCount + " threads)");

            // threads array
            Thread[] threads = new Thread[threadsCount];
            //spinlock object
            SpinLock slock = new SpinLock(enableThreadIDs);
            // scceeded threads counter
            int succeeded = 0;
            // Semaphore used to make sure that there is no other threads in the critical section
            Semaphore semaphore = new Semaphore(1, 1);

            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = new Thread(delegate()
                {
                    bool lockTaken = false;
                    try
                    {
                        slock.Enter(ref lockTaken);
                        //use semaphore to make sure that no other thread inside the critical section
                        if (!semaphore.WaitOne(0, false))
                        {
                            // 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();
                        }
                    }
                });
                threads[i].Start();

            }
            // wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Join();
            }
            // count must be equal to the threads count
            if (succeeded != threadsCount)
            {
                TestHarness.TestLog("SpinLock.Enter() failed, actual count: " + succeeded + " expected: " + threadsCount);
                return false;
            }
            TestHarness.TestLog("SpinLock.Enter() passed.");
            return true;
        }
Esempio n. 13
0
        /// <summary>
        /// Test Exit
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest4_Exit(bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.Exit()");
            Exception exception = null;
            SpinLock slock = new SpinLock(enableThreadIDs);
            bool lockTaken = false;
            slock.Enter(ref lockTaken);
            slock.Exit();
            if (enableThreadIDs && slock.IsHeldByCurrentThread)
            {
                TestHarness.TestLog("SpinLock.Exit() failed, IsHeld is true after calling Exit");
                return false;
            }

            // Calling Exit without owning the lock
            try
            {
                slock.Exit();
            }
            catch (Exception ex)
            {
                // SynchronizationLockException must be thrown
                exception = ex;
            }
            if (enableThreadIDs)
            {
                if (exception == null || exception.GetType() != typeof(SynchronizationLockException))
                {
                    TestHarness.TestLog(@"SpinLock.Exit() failed, calling Exit without owning the lock");
                    return false;
                }
            }

            TestHarness.TestLog("SpinLock.Exit() passed.");
            return true;

        }
Esempio n. 14
0
        /// <summary>
        /// Test TryEnter invalid cases
        /// </summary>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest3_TryEnter(bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(invalid cases)");
            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();
                    //TODO: uncomment after finishing type forwarding in clr integration
                    if (exception == null /*|| exception.GetType() != typeof(LockRecursionException)*/)
                    {
                        TestHarness.TestLog("SpinLock.TryEnter() failed, recursive locks without exception");
                        return false;
                    }
                    if (slock.IsHeldByCurrentThread)
                    {
                        TestHarness.TestLog("SpinLock.TryEnter() failed, IsHeld is true after calling Exit");
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            #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))
            {
                TestHarness.TestLog(@"SpinLock.TryEnter() failed, timeout.Totalmilliseconds > int.maxValue
                 without throwing ArgumentOutOfRangeException " + exception);
                return false;
            }
            #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))
            {
                TestHarness.TestLog(@"SpinLock.TryEnter() failed, timeout < -1
                 without throwing ArgumentOutOfRangeException");
                return false;
            }
            #endregion

            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 15
0
        /// <summary>
        /// Test SpinLock.TryEnter() by launching n threads, each one calls TryEnter, the succeeded threads increment
        /// a counter variable and failed threads increment failed variable, count + failed must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest1_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(" + threadsCount + " threads)");

            Thread[] threads = new Thread[threadsCount];
            SpinLock slock = new SpinLock(enableThreadIDs);
            int succeeded = 0;
            int failed = 0;


            // Run threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = new Thread(delegate()
                {
                    bool lockTaken = false;
                    slock.TryEnter(ref lockTaken);
                    if (lockTaken)
                    {
                        // Increment succeeded counter 
                        Interlocked.Increment(ref succeeded);
                        slock.Exit();
                    }
                    else
                    {
                        // Increment failed counter
                        Interlocked.Increment(ref failed);
                    }
                });
                threads[i].Start();
            }
            // Wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Join();
            }
            // succeeded + failed must be equal to the threads count.
            if (succeeded + failed != threadsCount)
            {
                TestHarness.TestLog("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                    " expected :" + threadsCount);
                return false;
            }
            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 16
0
        private static void RemoveNoise(NeuralComputation computation, string path, double noiseLevel)
        {
            var comps = Enumerable.Range(0, 15).Select(idx => new NoiseRemovalComputation(computation.Clone())).ToList();
            comps.Add(new NoiseRemovalComputation(computation));
            int compIdx = 0;
            
            ImageBuffer source, dest;
            using (var sourceBmp = new Bitmap(path))
            {
                source = new ImageBuffer(sourceBmp);
                AddNoise(source, noiseLevel);
                dest = new ImageBuffer(source.Width, source.Height);
            }

            int size = 7, blockSize = 16;
            int w = source.Width, h = source.Height, soFar = 0, msTime = 0;
            SpinLock infoLock = new SpinLock(), compLock = new SpinLock();

            Parallel.For(0, h / blockSize + 1, (idx, state) =>
            {
                NoiseRemovalComputation comp;
                bool compTaken = false;
                try
                {
                    compLock.Enter(ref compTaken);
                    comp = comps[compIdx++ % comps.Count];
                }
                finally
                {
                    if (compTaken) compLock.Exit();
                }

                //Console.WriteLine(compIdx);

                int pos = idx * blockSize;
                var rBytes = new byte[size * size];
                var bBytes = new byte[size * size];
                var gBytes = new byte[size * size];
                Color[] sourceColors = new Color[size * size];
                for (int y = pos; y < pos + blockSize && y < h; y++)
                {
                    var sw = new Stopwatch();
                    for (int x = 0; x < w; x++)
                    {
                        ReadBytes(source, rBytes, gBytes, bBytes, size, x, y);

                        sw.Start();
                        byte destByteR = comp.Compute(rBytes, noiseLevel);
                        byte destByteG = comp.Compute(gBytes, noiseLevel);
                        byte destByteB = comp.Compute(bBytes, noiseLevel);
                        sw.Stop();

                        WriteByte(dest, x, y, destByteR, destByteG, destByteB);
                    }

                    bool infoTaken = false;
                    try
                    {
                        infoLock.Enter(ref infoTaken);
                        msTime += (int)sw.ElapsedMilliseconds;
                        Console.WriteLine("Processing line: {0} / {1}", ++soFar, h);
                    }
                    finally
                    {
                        if (infoTaken) infoLock.Exit();
                    }
                }
            });

            Console.WriteLine("Comp: {0}ms", msTime);

            dest.Save("result.png", ImageFormat.Png);  
        }
Esempio n. 17
0
        /// <summary>
        /// Test SpinLock.Enter by launching n threads that increment a variable inside a critical section
        /// the final count variable must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private 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
            if (succeeded != threadsCount)
            {
                Assert.True(false, string.Format("SpinLock.Enter() failed, actual count: " + succeeded + " expected: " + threadsCount));
            }
        }
Esempio n. 18
0
   public static void Go() {
      Int32 x = 0;
      const Int32 iterations = 10000000;  // 10 million

      // How long does it take to increment x 10 million times?
      Stopwatch sw = Stopwatch.StartNew();
      for (Int32 i = 0; i < iterations; i++) {
         x++;
      }
      Console.WriteLine("Incrementing x: {0:N0}", sw.ElapsedMilliseconds);

      // How long does it take to increment x 10 million times 
      // adding the overhead of calling a method that does nothing?
      sw.Restart();
      for (Int32 i = 0; i < iterations; i++) {
         M(); x++; M();
      }
      Console.WriteLine("Incrementing x in M: {0:N0}", sw.ElapsedMilliseconds);

      // How long does it take to increment x 10 million times 
      // adding the overhead of calling an uncontended SimpleSpinLock?
      SimpleSpinLock ssl = new SimpleSpinLock();
      sw.Restart();
      for (Int32 i = 0; i < iterations; i++) {
         ssl.Enter(); x++; ssl.Leave();
      }
      Console.WriteLine("Incrementing x in SimpleSpinLock: {0:N0}", sw.ElapsedMilliseconds);

      // How long does it take to increment x 10 million times 
      // adding the overhead of calling an uncontended SpinLock?
      SpinLock sl = new SpinLock(false);
      sw.Restart();
      for (Int32 i = 0; i < iterations; i++) {
         Boolean taken = false;
         sl.Enter(ref taken); x++; sl.Exit(false);
      }
      Console.WriteLine("Incrementing x in SpinLock: {0:N0}", sw.ElapsedMilliseconds);

      // How long does it take to increment x 10 million times 
      // adding the overhead of calling an uncontended SimpleWaitLock?
      using (SimpleWaitLock swl = new SimpleWaitLock()) {
         sw.Restart();
         for (Int32 i = 0; i < iterations; i++) {
            swl.Enter(); x++; swl.Leave();
         }
         Console.WriteLine("Incrementing x in SimpleWaitLock: {0:N0}", sw.ElapsedMilliseconds);
      }
      Console.ReadLine();
   }
Esempio n. 19
0
        public static void Do(int workItemsCount, bool parallelize, Action<DataParallelContext> workItemRangeProcessor)
        {
            if (workItemsCount <= 0 || workItemRangeProcessor == null) return;

            if (!parallelize)
            {
                workItemRangeProcessor(new DataParallelContext(IntRange.CreateExclusive(0, workItemsCount), workItemsCount));
                return;
            }

            if (workItemsCount == 1)
            {
                workItemRangeProcessor(new DataParallelContext(IntRange.CreateFixed(0), workItemsCount));
            } 
            else if (workItemsCount < procCount)
            {
                Parallel.For(0, workItemsCount, (i) =>
                {
                    workItemRangeProcessor(new DataParallelContext(IntRange.CreateFixed(i), workItemsCount));
                });
            }
            else
            {
                int workSize = workItemsCount / procCount;
                int mod = workItemsCount % procCount;

                if (mod == 0)
                {
                    Parallel.For(0, procCount, (i) =>
                    {
                        int begin = i * workSize;
                        workItemRangeProcessor(new DataParallelContext(IntRange.CreateExclusive(begin, begin + workSize), workItemsCount));
                    });
                }
                else
                {
                    int to = 0;
                    var spinLock = new SpinLock(false);
                    Parallel.For(0, procCount, (i) =>
                    {
                        int begin = to;
                        bool lockTaken = false;
                        try
                        {
                            spinLock.Enter(ref lockTaken);
                            if (mod != 0)
                            {
                                to += workSize + 1;
                                mod--;
                            }
                            else
                            {
                                to += workSize;
                            }
                        }
                        finally
                        {
                            if (lockTaken) spinLock.Exit();
                        }
                        workItemRangeProcessor(new DataParallelContext(IntRange.CreateExclusive(begin, to), workItemsCount));
                    });
                }
            }
        }
Esempio n. 20
0
 public TurnInfo NextControl(GameModel gm, out int cx, out int cr)
 {
     long callCount = 0, boaderScore = 0;
     int nowLevel = 0, ci = 0;
     TurnInfo turnInfo = new TurnInfo();
     try
     {
         while (!MaxToControl(out ci, boaderScore) && nowLevel++ < maxLevel)
         {
             if (!parallel)
             {
                 SearchStorage ss = CreateLocalStorage(gm, nowLevel, boaderScore);
                 turnInfo = SearchNode(rootNode, 0, ss);
                 boaderScore = ss.MinimaxScore;
                 callCount = ss.CallCount;
             }
             else
             {
                 long minScore = long.MaxValue;
                 long minimaxScore = 0;
                 SpinLock sl = new SpinLock();
                 if (!rootNode.IsExistChild())
                 {
                     rootNode.GenerateChild(W, T);
                 }
                 ParallelLoopResult plr = Parallel.For<SearchStorage>(0, rootNode.Length,
                     () => CreateLocalStorage(gm, nowLevel, boaderScore),
                     (index, state, local) =>
                     {
                         local.MinimaxScore = long.MinValue;
                         local.CallCount = 0;
                         Debug.Assert(local.GMC.Level == 1);
                         local.resultInfo = AppraiseNode(rootNode[index], 1, 0, local);
                         return local;
                     },
                     (local) =>
                     {
                         bool lockTaken = false;
                         while (!lockTaken) sl.Enter(ref lockTaken);
                         if (turnInfo.AppraisalScore < local.resultInfo.AppraisalScore)
                         {
                             turnInfo = local.resultInfo;
                         }
                         if (local.resultInfo.AppraisalScore >= local.BoaderScore)
                         {
                             minScore = Math.Min(minScore, local.resultInfo.AppraisalScore);
                         }
                         minimaxScore = Math.Max(minimaxScore, local.MinimaxScore);
                         callCount += local.CallCount;
                         sl.Exit();
                     }
                 );
                 Debug.Assert(plr.IsCompleted);
                 if (minScore < long.MaxValue)
                 {
                     boaderScore = Math.Max(minimaxScore, minScore);
                 }
                 else
                 {
                     boaderScore = minimaxScore;
                 }
             }
             Trace.TraceInformation("Turn {0}, Level {1}, CallCount {2}, BoaderScore {3}, {4}, {5}",
                 gm.Turn + 1, nowLevel, callCount, boaderScore, turnInfo.ToString(), rootNode.ToString());
         }
     }
     catch (OutOfMemoryException e)
     {
         Trace.TraceWarning("{0}", e.ToString());
     }
     if (ci != -1)
     {
         rootNode = rootNode[ci];
         cx = rootNode.CX;
         cr = rootNode.CR;
     }
     else
     {
         rootNode = new AppraisalTree();
         cx = 0; cr = 0;
     }
     return turnInfo;
 }
Esempio n. 21
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"));
                }
            }
        }
Esempio n. 22
0
        /// <summary>
        /// Test SpinLock.TryEnter(Timespan) by generating random timespan milliseconds
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static bool RunSpinLockTest2_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            TestHarness.TestLog("SpinLock.TryEnter(" + threadsCount + " threads)");

            Thread[] threads = new Thread[threadsCount];
            SpinLock slock = new SpinLock(enableThreadIDs);
            int succeeded = 0;
            int failed = 0;

            // Run threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i] = new Thread(delegate(object x)
                {
                    // Generate random timespan
                    Random rand = new Random(33);
                    bool lockTaken = false;
                    TimeSpan time = TimeSpan.FromMilliseconds(rand.Next(-1, 20));
                    slock.TryEnter(time, ref lockTaken);
                    if (lockTaken)
                    {
                        // add some delay in the critical section
                        Thread.Sleep(15);
                        Interlocked.Increment(ref succeeded);
                        slock.Exit();
                    }
                    else
                    {
                        // Failed to get the lock within the timeout
                        Interlocked.Increment(ref failed);
                    }
                });
                threads[i].Start(i);
            }
            // Wait all threads
            for (int i = 0; i < threadsCount; i++)
            {
                threads[i].Join();
            }
            // succeeded + failed must be equal to the threads count.
            if (succeeded + failed != threadsCount)
            {
                TestHarness.TestLog("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                    " expected :" + threadsCount);
                return false;
            }
            TestHarness.TestLog("SpinLock.TryEnter() passed.");
            return true;
        }
Esempio n. 23
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
        }
Esempio n. 24
0
        /// <summary>
        /// Test SpinLock.TryEnter() by launching n threads, each one calls TryEnter, the succeeded threads increment
        /// a counter variable and failed threads increment failed variable, count + failed must be equal to n
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest1_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            for (int j = 0; j < 2; j++)
            {
                bool useMemoryBarrier = j == 0;
                Task[] threads = new Task[threadsCount];
                SpinLock slock = new SpinLock(enableThreadIDs);
                int succeeded = 0;
                int failed = 0;


                // Run threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i] = Task.Run(delegate ()
                    {
                        bool lockTaken = false;
                        slock.TryEnter(ref lockTaken);
                        if (lockTaken)
                        {
                            // Increment succeeded counter 
                            Interlocked.Increment(ref succeeded);
                            slock.Exit(useMemoryBarrier);
                        }
                        else
                        {
                            // Increment failed counter
                            Interlocked.Increment(ref failed);
                        }
                    });
                }
                // Wait all threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i].Wait();
                }
                // succeeded + failed must be equal to the threads count.
                if (succeeded + failed != threadsCount)
                {
                    Assert.True(false, string.Format("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                        " expected :" + threadsCount));
                }
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Test SpinLock.TryEnter(Timespan) by generating random timespan milliseconds
        /// </summary>
        /// <param name="threadsCount">Number of threads that call enter/exit</param>
        /// <returns>True if succeeded, false otherwise</returns>
        private static void RunSpinLockTest2_TryEnter(int threadsCount, bool enableThreadIDs)
        {
            for (int j = 0; j < 2; j++)
            {
                bool useMemoryBarrier = j == 0;
                Task[] threads = new Task[threadsCount];
                SpinLock slock = new SpinLock(enableThreadIDs);
                int succeeded = 0;
                int failed = 0;

                // Run threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i] = new Task(delegate (object x)
                    {
                        // Generate random timespan
                        bool lockTaken = false;
                        TimeSpan time = TimeSpan.FromMilliseconds(20);
                        slock.TryEnter(time, ref lockTaken);
                        if (lockTaken)
                        {
                            // add some delay in the critical section
                            Task.WaitAll(Task.Delay(15));
                            Interlocked.Increment(ref succeeded);
                            slock.Exit(useMemoryBarrier);
                        }
                        else
                        {
                            // Failed to get the lock within the timeout
                            Interlocked.Increment(ref failed);
                        }
                    }, i);
                    threads[i].Start(TaskScheduler.Default);
                }
                // Wait all threads
                for (int i = 0; i < threadsCount; i++)
                {
                    threads[i].Wait();
                }
                // succeeded + failed must be equal to the threads count.
                if (succeeded + failed != threadsCount)
                {
                    Assert.True(false, string.Format("SpinLock.TryEnter() failed, actual count: " + (succeeded + failed) +
                        " expected :" + threadsCount));
                }
            }
        }
Esempio n. 26
-1
        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();
            }
        }