Ejemplo n.º 1
0
        public unsafe void TestAllocPages()         // ensure that we fail gracefully when memory gets full
        {
            var xRAM = new byte[10 * RAT.PageSize]; // 10 Pages - 1 for RAT and 9 for values

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);
                Assert.AreEqual((uint)1, RAT.GetPageCount(RAT.PageType.RAT));

                try
                {
                    for (int i = 0; i < 10000; i++)
                    {
                        byte *ptr = Heap.Alloc(40);
                        FillRandom(ptr, 40);
                        if (ptr == null)
                        {
                            Assert.Fail();
                        }
                        Assert.AreEqual((uint)1, RAT.GetPageCount(RAT.PageType.RAT));
                    }
                }
                catch (Exception e)
                {
                    Assert.AreEqual("289", e.Message);
                }
            }
        }
Ejemplo n.º 2
0
        public unsafe void RATTest()
        {
            var xRAM = new byte[128 * 1024 * 1024]; // 128 MB

            xRAM[0] = 1;
            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                //RAT.Init(xPtr, (Native)xRAM.LongLength);
                RAT.Init(xPtr, (Native)xRAM.Length);

                Native xRatPages = RAT.GetPageCount(RAT.PageType.RAT);

                Assert.IsTrue(xRatPages > 0);

                var xFreePages = RAT.GetPageCount(RAT.PageType.Empty);

                Assert.IsTrue(xFreePages > 0);

                var x1          = (Int32 *)Heap.Alloc(sizeof(Int32));
                var xFreePages2 = RAT.GetPageCount(RAT.PageType.Empty);

                Assert.IsTrue(xFreePages - xFreePages2 == 1);
                //
                Heap.Free(x1);
                var xFreePages3 = RAT.GetPageCount(RAT.PageType.Empty);

                Assert.IsTrue(xFreePages3 == xFreePages2 + 1);
            }
        }
Ejemplo n.º 3
0
        public unsafe void InitTest()
        {
            var xRAM = new byte[128 * 1024 * 1024]; // 128 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);

                Assert.IsTrue(HeapSmall.mMaxItemSize > 512);

                uint xRatPages = RAT.GetPageCount(RAT.PageType.RAT);

                Assert.IsTrue(xRatPages > 0);

                var xFreePages = RAT.GetPageCount(RAT.PageType.Empty);

                Assert.IsTrue(xFreePages > 0);

                Assert.IsTrue(RAT.GetPageCount(RAT.PageType.HeapSmall) > 0);

                Assert.AreEqual(0, HeapSmall.GetAllocatedObjectCount());

                Assert.AreEqual((uint)8, RAT.GetPageCount(RAT.PageType.RAT));
            }
        }
Ejemplo n.º 4
0
        static void CreatePage(Native aItemSize)
        {
            if (aItemSize == 0)
            {
                throw new Exception("ItemSize cannot be 0.");
            }
            else if (aItemSize % sizeof(Native) != 0)
            {
                throw new Exception("Item size must be word aligned.");
            }
            else if (mMaxItemSize == 0)
            {
                throw new Exception("SMT is not initialized.");
            }
            else if (aItemSize > mMaxItemSize)
            {
                throw new Exception("Cannot allocate more than MaxItemSize in SmallHeap.");
            }

            var xPtr = (Native *)RAT.Alloc(RAT.PageType.HeapSmall);

            *xPtr = 0;
            for (void **p = mSMT + aItemSize; ; p--)
            {
                // TODO - Make a free list, put a ptr in item header and first page header - how to keep compact?
            }
            // Header
            // Ptr to next page of same size

            // Each Item
            //xPtr[0] = aSize; // Actual data size
            //xPtr[1] = 0; // Ref count
            //xPtr[2] = 0; // Ptr to first
        }
Ejemplo n.º 5
0
        static void InitSMT(Native aMaxItemSize)
        {
            mMaxItemSize = aMaxItemSize;
            Native xPageCount = mMaxItemSize * (Native)sizeof(void *) / RAT.PageSize;

            mSMT = (void **)RAT.Alloc(RAT.PageType.HeapSmall, xPageCount);
        }
Ejemplo n.º 6
0
        static public void Free(void *aPtr)
        {
            // TODO - Should check the page type before freeing to make sure it is a Large?
            // or just trust the caller to avoid adding overhead?
            var xPageIdx = RAT.GetFirstRAT(aPtr);

            RAT.Free(xPageIdx);
        }
Ejemplo n.º 7
0
        static public byte *Alloc(Native aSize)
        {
            Native xPages = (Native)((aSize + PrefixBytes) / RAT.PageSize) + 1;
            var    xPtr   = (Native *)RAT.Alloc(RAT.PageType.HeapLarge, xPages);

            xPtr[0] = xPages * RAT.PageSize - PrefixBytes; // Allocated data size
            xPtr[1] = aSize;                               // Actual data size
            xPtr[2] = 0;                                   // Ref count
            xPtr[3] = 0;                                   // Ptr to first

            return((byte *)xPtr + PrefixBytes);
        }
Ejemplo n.º 8
0
        // Keep as void* and not byte* or other. Reduces typecasting from callers
        // who may have typed the pointer to their own needs.
        static public void Free(void *aPtr)
        {
            //TODO find a better way to remove the double look up here for GetPageType and then again in the
            // .Free methods which actually free the entries in the RAT.
            var xType = RAT.GetPageType(aPtr);

            switch (xType)
            {
            case RAT.PageType.HeapLarge:
                HeapLarge.Free(aPtr);
                break;

            default:
                throw new Exception("Heap item not found in RAT.");
            }
        }
Ejemplo n.º 9
0
        public unsafe void RATMethods()
        {
            var xRAM = new byte[1024 * 1024];

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;

                RAT.Init(xPtr, (uint)xRAM.Length);

                var largePage = RAT.AllocPages(RAT.PageType.HeapLarge, 3);

                Assert.AreEqual(RAT.PageType.HeapLarge, RAT.GetPageType(largePage));
                Assert.AreEqual(RAT.GetFirstRATIndex(largePage), RAT.GetFirstRATIndex((byte *)largePage + 20));
                Assert.AreEqual(RAT.PageType.HeapLarge, RAT.GetPageType((byte *)largePage + RAT.PageSize));
            }
        }
Ejemplo n.º 10
0
        unsafe public void TestMethod1()
        {
            var xRAM = new byte[128 * 1024 * 1024];

            xRAM[0] = 1;
            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (UInt32)xRAM.LongLength);

                Native xRatPages = RAT.GetPageCount(RAT.PageType.RAT);

                Assert.IsTrue(xRatPages > 0);

                Native xFreePages = RAT.GetPageCount(RAT.PageType.Empty);
            }
        }
Ejemplo n.º 11
0
        public unsafe void SmallHeapMultiPageAllocationTest()
        {
            var xRAM = new byte[1024 * 1024]; // 4 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;

                RAT.Init(xPtr, (uint)xRAM.Length);

                uint smallPages = RAT.GetPageCount(RAT.PageType.HeapSmall);


                var ptr1 = Heap.Alloc(HeapSmall.mMaxItemSize); // 4 of them should fit on one page
                var ptr2 = Heap.Alloc(HeapSmall.mMaxItemSize);
                var ptr3 = Heap.Alloc(HeapSmall.mMaxItemSize);
                var ptr4 = Heap.Alloc(HeapSmall.mMaxItemSize);

                Assert.AreEqual((uint)ptr2 - (uint)ptr1, (uint)ptr4 - (uint)ptr3);
                Assert.AreEqual((uint)RAT.GetPagePtr(ptr1), (uint)RAT.GetPagePtr(ptr2));
                Assert.AreEqual(4, HeapSmall.GetAllocatedObjectCount());
                Heap.Free(ptr4);
                var nptr4 = Heap.Alloc(HeapSmall.mMaxItemSize);

                Assert.AreEqual((uint)RAT.GetPagePtr(ptr1), (uint)RAT.GetPagePtr(ptr4));
                var ptr5 = Heap.Alloc(HeapSmall.mMaxItemSize); // this should cause a new page to have to be created

                uint largePages = RAT.GetPageCount(RAT.PageType.HeapLarge);

                Assert.AreEqual((uint)0, largePages);
                Assert.AreEqual(smallPages + 1, RAT.GetPageCount(RAT.PageType.HeapSmall));
                Assert.AreNotEqual((uint)ptr1, (uint)ptr5);
                Assert.IsTrue(((uint)ptr5 - (uint)ptr1) % RAT.PageSize == 0);
                Assert.AreEqual(5, HeapSmall.GetAllocatedObjectCount());


                // now lets force them to allocate 2 more pages
                for (int i = 0; i < 8; i++)
                {
                    Heap.Alloc(HeapSmall.mMaxItemSize - 2);
                }
                Assert.AreEqual(smallPages + 3, RAT.GetPageCount(RAT.PageType.HeapSmall));
                Assert.AreEqual(13, HeapSmall.GetAllocatedObjectCount());
            }
        }
Ejemplo n.º 12
0
        public unsafe void SmallHeapTestExpansion()
        {
            var xRAM = new byte[1024 * 1024]; // 4 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);

                uint smallPages = RAT.GetPageCount(RAT.PageType.HeapSmall);

                for (int i = 0; i < 9; i++)
                {
                    Heap.Alloc(600);
                }

                Assert.AreEqual(smallPages + 2, RAT.GetPageCount(RAT.PageType.HeapSmall));
            }
        }
Ejemplo n.º 13
0
        public unsafe void SmallAllocTest()
        {
            var xRAM = new byte[32 * 1024 * 1024]; // 32 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;

                RAT.Init(xPtr, (uint)xRAM.Length);

                uint smallPages = RAT.GetPageCount(RAT.PageType.HeapSmall);
                uint largePages = RAT.GetPageCount(RAT.PageType.HeapLarge);

                // the following allocations should all go on the same page
                var ptr1 = Heap.Alloc(8);
                var ptr2 = Heap.Alloc(3);

                ptr2[0] = 12;
                ptr2[1] = 101;
                var ptr3 = Heap.Alloc(8);
                var ptr4 = Heap.Alloc(20);
                var ptr5 = Heap.Alloc(22);

                Assert.AreNotEqual((uint)ptr1, (uint)ptr2);
                Assert.AreEqual((uint)ptr2 - (uint)ptr1, (uint)ptr3 - (uint)ptr2);
                Assert.AreEqual(24 + HeapSmall.PrefixItemBytes, (uint)ptr5 - (uint)ptr4);
                Assert.AreEqual(RAT.PageSize, (uint)ptr4 - (uint)ptr1);
                Assert.AreEqual(12, ptr2[0]);
                Assert.AreEqual(smallPages, RAT.GetPageCount(RAT.PageType.HeapSmall));
                Assert.AreEqual(largePages, RAT.GetPageCount(RAT.PageType.HeapLarge));
                Assert.AreEqual(5, HeapSmall.GetAllocatedObjectCount());

                Heap.Free(ptr2);
                Assert.AreEqual(4, HeapSmall.GetAllocatedObjectCount());
                Assert.AreEqual(0, ptr2[0]);
                var nptr2 = Heap.Alloc(10);

                Heap.Alloc(10);
                Assert.AreEqual((uint)ptr2, (uint)nptr2); // we use the earliest free position
                Assert.AreEqual(6, HeapSmall.GetAllocatedObjectCount());
            }
        }
Ejemplo n.º 14
0
        public unsafe void TestRATHeapMethods()
        {
            var xRAM = new byte[10 * RAT.PageSize]; // 10 Pages - 1 for RAT and 9 for values

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);

                var ptr1 = Heap.Alloc(10);
                var ptr2 = Heap.Alloc(10);
                var ptr3 = Heap.Alloc(10);

                Assert.AreNotEqual((uint)ptr1, (uint)ptr2);
                Assert.AreNotEqual((uint)ptr1, (uint)ptr3);
                Assert.AreNotEqual((uint)ptr2, (uint)ptr3);
                Assert.AreEqual(RAT.GetFirstRATIndex(ptr1), RAT.GetFirstRATIndex(ptr2));
                Assert.AreEqual(RAT.GetFirstRATIndex(ptr1), RAT.GetFirstRATIndex(ptr3));
                Assert.AreEqual((uint)RAT.GetPagePtr(ptr1), (uint)RAT.GetPagePtr(ptr2));
                Assert.AreEqual((uint)RAT.GetPagePtr(ptr1), (uint)RAT.GetPagePtr(ptr3));
            }
        }
Ejemplo n.º 15
0
        public unsafe void SmallHeapStressTest() // this test is important since it tests that the SMT table can grow to multiple pages
        {
            var xRAM = new byte[1024 * 1024];    // 4 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);


                Random random = new Random();

                for (int i = 0; i < 1000; i++)
                {
                    if (Heap.Alloc((uint)random.Next(4, (int)HeapSmall.mMaxItemSize)) == null)
                    {
                        Assert.Fail();
                    }
                }
                Assert.AreEqual(1000, HeapSmall.GetAllocatedObjectCount());
            }
        }
Ejemplo n.º 16
0
        public unsafe void MediumLargeHeapTest() // as long as medium just does the same as the large heap, we can test them together
        {
            var xRAM = new byte[1024 * 1024];    // 4 MB

            fixed(byte *xPtr = xRAM)
            {
                RAT.Debug = true;
                RAT.Init(xPtr, (uint)xRAM.Length);

                var largeCount  = RAT.GetPageCount(RAT.PageType.HeapLarge);
                var mediumCount = RAT.GetPageCount(RAT.PageType.HeapMedium);

                var ptr1 = Heap.Alloc(HeapMedium.MaxItemSize); // this will allocate two pages,
                                                               // since we simplify the math by assuming we never want only one full page
                var ptr2 = Heap.Alloc(HeapMedium.MaxItemSize - 10);
                var ptr3 = Heap.Alloc(HeapMedium.MaxItemSize + 10);

                Assert.AreEqual(largeCount + 2, RAT.GetPageCount(RAT.PageType.HeapLarge));
                Assert.AreEqual(mediumCount + 3, RAT.GetPageCount(RAT.PageType.HeapMedium));

                var ptr4 = Heap.Alloc(RAT.PageSize * 5 - HeapLarge.PrefixBytes - 1);

                Assert.AreEqual(largeCount + 7, RAT.GetPageCount(RAT.PageType.HeapLarge));
                Assert.AreEqual(6, (int)RAT.GetPageCount(RAT.PageType.Extension));

                Heap.Free(ptr4);
                Assert.AreEqual(largeCount + 2, RAT.GetPageCount(RAT.PageType.HeapLarge));
                Assert.AreEqual(2, (int)RAT.GetPageCount(RAT.PageType.Extension));

                Heap.Free(ptr1);
                Heap.Free(ptr2);

                Assert.AreEqual(mediumCount, RAT.GetPageCount(RAT.PageType.HeapMedium));
                Assert.AreEqual(largeCount + 2, RAT.GetPageCount(RAT.PageType.HeapLarge));
            }
        }