예제 #1
0
        internal static Cookie ReserveMiss()
        {
            // try to search in the array of all memory blocks
            ThreadMemoryHolder h;

            if (SearchAndReserve(out h))
            {
                return(new Cookie(h));
            }
            if (AllocateNew(out h))
            {
                return(new Cookie(h, causedAllocation: true));
            }

            // All items in array blocks are busy and not available, increase the array size and try once more
            lock (ourLock)
            {
                var newBlocks = new ThreadMemoryHolder[ourBlocks.Length * 2];
                Array.Copy(ourBlocks, newBlocks, ourBlocks.Length);
                ourBlocks = newBlocks;

                if (SearchAndReserve(out h))
                {
                    return(new Cookie(h));
                }
                if (AllocateNew(out h))
                {
                    return(new Cookie(h, causedAllocation: true));
                }
            }

            Assertion.Fail("Unable to reserve a native memory block");
            return(new Cookie());


            bool SearchAndReserve(out ThreadMemoryHolder holder)
            {
                var blocks = ourBlocks;
                var start  = Thread.CurrentThread.ManagedThreadId % blocks.Length;

                for (int i = start; i < blocks.Length; i++)
                {
                    holder = blocks[i];
                    if (holder == null)
                    {
                        break;
                    }
                    if (holder.TryReserve())
                    {
                        ourThreadMemory = holder;
                        return(true);
                    }
                }
                for (int i = 0; i < start; i++)
                {
                    holder = blocks[i];
                    if (holder == null)
                    {
                        break;
                    }
                    if (holder.TryReserve())
                    {
                        ourThreadMemory = holder;
                        return(true);
                    }
                }

                holder = null;
                return(false);
            }

            bool AllocateNew(out ThreadMemoryHolder holder)
            {
                lock (ourLock)
                {
                    for (int i = 0; i < ourBlocks.Length; i++)
                    {
                        if (ourBlocks[i] != null)
                        {
                            continue;
                        }

                        ourThreadMemory = holder = new ThreadMemoryHolder();
                        if (holder.TryReserve())
                        {
                            ourBlocks[i] = holder;
                            return(true);
                        }

                        Assertion.Fail("Unable to reserve newly created memory block");
                    }
                }

                holder = null;
                return(false);
            }
        }
예제 #2
0
 internal Cookie([NotNull] ThreadMemoryHolder holder, bool causedAllocation = false)
 {
     myHolder         = holder ?? throw new ArgumentNullException(nameof(holder));
     CausedAllocation = causedAllocation;
 }