CompareExchange() public static method

public static CompareExchange ( IntPtr &location, IntPtr value, IntPtr comparand ) : IntPtr
location System.IntPtr
value System.IntPtr
comparand System.IntPtr
return System.IntPtr
コード例 #1
0
        public void EnterWriteLock()
        {
            ClientSpinWait sw = new ClientSpinWait();

            do
            {
                int state = rwlock;
                if (state < RwWrite)
                {
                    if (ClientInterlocked.CompareExchange(ref rwlock, RwWrite, state) == state)
                    {
                        return;
                    }
                    state = rwlock;
                }
                // We register our interest in taking the Write lock (if upgradeable it's already done)
                while ((state & RwWait) == 0 && ClientInterlocked.CompareExchange(ref rwlock, state | RwWait, state) != state)
                {
                    state = rwlock;
                }
                // Before falling to sleep
                while (rwlock > RwWait)
                {
                    sw.SpinOnce();
                }
            } while (true);
        }
コード例 #2
0
        public void Enter(ref bool lockTaken)
        {
            if (lockTaken)
            {
                throw new ArgumentException("lockTaken", "lockTaken must be initialized to false");
            }
            if (isThreadOwnerTrackingEnabled && IsHeldByCurrentThread)
            {
                throw new LockRecursionException();
            }

            int slot = -1;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                slot = ClientInterlocked.Increment(ref ticket.Users) - 1;

                ClientSpinWait wait = new ClientSpinWait();
                while (slot != ticket.Value)
                {
                    wait.SpinOnce();

                    while (stallTickets != null && ((ClientConcurrentOrderedList <int>)stallTickets).TryRemove(ticket.Value))
                    {
                        ++ticket.Value;
                    }
                }
            }
            finally
            {
                if (slot == ticket.Value)
                {
                    lockTaken         = true;
                    threadWhoTookLock = Thread.CurrentThread.ManagedThreadId;
                }
                else if (slot != -1)
                {
                    // We have been interrupted, initialize stallTickets
                    if (stallTickets == null)
                    {
                        ClientInterlocked.CompareExchange(ref stallTickets, new ClientConcurrentOrderedList <int>(), null);
                    }
                    ((ClientConcurrentOrderedList <int>)stallTickets).TryAdd(slot);
                }
            }
        }
コード例 #3
0
        public void TryEnter(int millisecondsTimeout, ref bool lockTaken)
        {
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("milliSeconds", "millisecondsTimeout is a negative number other than -1");
            }
            if (lockTaken)
            {
                throw new ArgumentException("lockTaken", "lockTaken must be initialized to false");
            }
            if (isThreadOwnerTrackingEnabled && IsHeldByCurrentThread)
            {
                throw new LockRecursionException();
            }

            long start = millisecondsTimeout == -1 ? 0 : sw.ElapsedMilliseconds;
            bool stop  = false;

            do
            {
                while (stallTickets != null && ((ClientConcurrentOrderedList <int>)stallTickets).TryRemove(ticket.Value))
                {
                    ++ticket.Value;
                }

                long u          = ticket.Users;
                long totalValue = (u << 32) | u;
                long newTotalValue
                    = BitConverter.IsLittleEndian ? (u << 32) | (u + 1) : ((u + 1) << 32) | u;

                RuntimeHelpers.PrepareConstrainedRegions();
                try { }
                finally
                {
                    lockTaken = ClientInterlocked.CompareExchange(ref ticket.TotalValue, newTotalValue, totalValue) == totalValue;

                    if (lockTaken)
                    {
                        threadWhoTookLock = Thread.CurrentThread.ManagedThreadId;
                        stop = true;
                    }
                }
            } while (!stop && (millisecondsTimeout == -1 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout));
        }