示例#1
0
        public static void Create(MemStorage* storage, int blockSize)
        {
            if (blockSize <= 0) throw new ArgumentException("blockSize must > 0.");

            blockSize = Align(blockSize, 8);
            storage = (MemStorage*)Marshal.AllocHGlobal(sizeof(MemStorage));
            storage->BlockSize = blockSize;
            Std.Memset(storage, 0, sizeof(MemStorage));
        }
示例#2
0
        public static void ClearMemStorage(MemStorage* storage)
        {
            if (storage == null) return;

            if (storage->Parent != null)
                DestroyMemStorage(storage);
            else
            {
                storage->Top = storage->Bottom;
                storage->FreeSpace = (storage->Bottom != null) ? storage->BlockSize - sizeof(MemBlock) : 0;
            }
        }
示例#3
0
        public static void DestroyMemStorage(MemStorage* storage)
        {
            int k = 0;

            MemBlock* block;
            MemBlock* dst_top = null;

            if (storage == null) return;

            if (storage->Parent != null)
                dst_top = storage->Parent->Top;

            for (block = storage->Bottom; block != null; k++)
            {
                MemBlock* temp = block;

                block = block->Next;
                if (storage->Parent != null)
                {
                    if (dst_top != null)
                    {
                        temp->Prev = dst_top;
                        temp->Next = dst_top->Next;
                        if (temp->Next != null)
                            temp->Next->Prev = temp;
                        dst_top = dst_top->Next = temp;
                    }
                    else
                    {
                        dst_top = storage->Parent->Bottom = storage->Parent->Top = temp;
                        temp->Prev = temp->Next = null;
                        storage->FreeSpace = storage->BlockSize - sizeof(MemBlock);
                    }
                }
                else
                {
                    Marshal.FreeHGlobal((IntPtr)temp);
                }
            }

            storage->Top = storage->Bottom = null;
            storage->FreeSpace = 0;
        }
示例#4
0
        /// <summary>
        /// Moves stack pointer to next block. 
        /// If no blocks, allocate new one and link it to the storage.
        /// </summary>
        /// <param name="storage"></param>
        public static void GoNextMemBlock(MemStorage* storage)
        {
            if (storage == null) return;

            if (storage->Top == null || storage->Top->Next == null)
            {
                MemBlock* block;

                if ((storage->Parent) == null)
                {
                    block = (MemBlock*)Marshal.AllocHGlobal(storage->BlockSize);
                }
                else
                {
                    MemStorage* parent = storage->Parent;
                    MemStoragePos parent_pos;

                    SaveMemStoragePos(parent, &parent_pos);
                    GoNextMemBlock(parent);

                    block = parent->Top;
                    RestoreMemStoragePos(parent, &parent_pos);

                    if (block == parent->Top)  /* the single allocated block */
                    {
                        parent->Top = parent->Bottom = null;
                        parent->FreeSpace = 0;
                    }
                    else
                    {
                        /* cut the block from the parent's list of blocks */
                        parent->Top->Next = block->Next;
                        if (block->Next != null)
                            block->Next->Prev = parent->Top;
                    }
                }

                /* link block */
                block->Next = null;
                block->Prev = storage->Top;

                if (storage->Top != null)
                    storage->Top->Next = block;
                else
                    storage->Top = storage->Bottom = block;
            }

            if (storage->Top->Next != null)
                storage->Top = storage->Top->Next;
            storage->FreeSpace = storage->BlockSize - sizeof(MemBlock);
        }
示例#5
0
        /// <summary>
        /// Restore memory storage position
        /// </summary>
        /// <param name="storage"></param>
        /// <param name="pos"></param>
        public static void RestoreMemStoragePos(MemStorage* storage, MemStoragePos* pos)
        {
            if (storage == null || pos == null) return;

            if (pos->FreeSpace > storage->BlockSize) throw new Exception("bad size");

            storage->Top = pos->Top;
            storage->FreeSpace = pos->FreeSpace;

            if (storage->Top == null)
            {
                storage->Top = storage->Bottom;
                storage->FreeSpace = (storage->Top != null) ? storage->BlockSize - sizeof(MemBlock) : 0;
            }
        }
示例#6
0
        /* Remember memory storage position: */
        public static void SaveMemStoragePos(MemStorage* storage, MemStoragePos* pos)
        {
            if (storage == null || pos == null) return;

            pos->Top = storage->Top;
            pos->FreeSpace = storage->FreeSpace;
        }
示例#7
0
        public static void* Alloc(MemStorage* storage, int size)
        {
            Byte* ptr = null;

            if (storage == null) return null;

            if (size > Int32.MaxValue) return null;

            if ((SizeT)storage->FreeSpace < size)
            {
                SizeT max_free_space = AlignLeft(storage->BlockSize - sizeof(MemBlock), 8);
                if (max_free_space < size) return null;

                GoNextMemBlock(storage);
            }

            ptr = ((Byte*)(storage)->Top + (storage)->BlockSize - (storage)->FreeSpace);
            storage->FreeSpace = AlignLeft(storage->FreeSpace - (int)size, 8);

            return ptr;
        }
示例#8
0
        public static void ReleaseMemStorage(MemStorage** storage)
        {
            if (storage == null) return;

            MemStorage* st = *storage;
            *storage = null;
            if (st != null)
            {
                DestroyMemStorage(st);
                Marshal.FreeHGlobal((IntPtr)st);
            }
        }