public void VirtualMemory_TryToReserveInvalidPageSize()
    {
        // Reserve 1 page with invalid page size
        BaselibErrorState errorState = default;
        var addressSpace             = VirtualMemoryUtility.ReserveAddressSpace(1, 69420, out errorState);

        VirtualMemoryUtility.ReportWrappedBaselibError(errorState);
        LogAssert.Expect(LogType.Error, new Regex("Baselib error:*"));
        VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState);
    }
    public unsafe void VirtualMemory_OvercommitReservedMemory()
    {
        BaselibErrorState errorState = default;

        // Reserve 1 page
        var addressSpace = VirtualMemoryUtility.ReserveAddressSpace(1, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState);

        {
            // Try to commit 2 pages (will fail).
            VMRange pages = new VMRange {
                ptr = addressSpace.ptr, log2PageSize = addressSpace.log2PageSize, pageCount = 2
            };
            VirtualMemoryUtility.CommitMemory(pages, out errorState);
            VirtualMemoryUtility.ReportWrappedBaselibError(errorState);
            LogAssert.Expect(LogType.Error, new Regex("Baselib error:*"));

            var coolByte = (byte *)pages.ptr;

            // Try to write to uncommitted memory (will fail and throw an exception).
            Assert.Throws <NullReferenceException>(() => *coolByte = 0);
        }
        VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState);
    }
    public unsafe void VirtualMemory_AllocateAndFreeFromBurst()
    {
        BaselibErrorState errorState = default;

        // Reserve 1GB
        var addressSpace = VirtualMemoryUtility.ReserveAddressSpace(1024ul * 256ul, VirtualMemoryUtility.DefaultPageSizeInBytes, out errorState);

        {
            // 100 pages of ints
            const int allocationCount = 100;

            var errorStates = new NativeArray <BaselibErrorState>(allocationCount, Allocator.Persistent);
            {
                for (int i = 0; i < allocationCount; i++)
                {
                    errorStates[i] = default;
                }

                var commitJob = new CommitJob
                {
                    jobAddressRangePtr = addressSpace.ptr,
                    jobLog2PageSize    = addressSpace.log2PageSize,
                    jobPageCount       = 1,
                    jobErrorStates     = errorStates
                };
                commitJob.Schedule(allocationCount, 1).Complete();

                for (int i = 0; i < allocationCount; i++)
                {
                    VirtualMemoryUtility.ReportWrappedBaselibError(errorStates[i]);
                }

                // for each page allocated
                for (int i = 0; i < allocationCount; i++)
                {
                    var page      = (void *)((ulong)addressSpace.ptr + (ulong)i * VirtualMemoryUtility.DefaultPageSizeInBytes);
                    var allocator = new UnsafeScratchAllocator((void *)addressSpace.ptr, (int)VirtualMemoryUtility.DefaultPageSizeInBytes * allocationCount);

                    var intCount      = ((int)VirtualMemoryUtility.DefaultPageSizeInBytes / sizeof(int));
                    var numbersInPage = (int *)allocator.Allocate <int>(intCount);
                    // for each int in the allocated page
                    for (int j = 0; j < intCount; j++)
                    {
                        Assert.AreEqual(j, numbersInPage[j]);
                    }
                }

                var decommitJob = new DecommitJob
                {
                    jobAddressRangePtr = addressSpace.ptr,
                    jobLog2PageSize    = addressSpace.log2PageSize,
                    jobPageCount       = 1,
                    jobErrorStates     = errorStates
                };
                decommitJob.Schedule(allocationCount, 1).Complete();
            }
            errorStates.Dispose();
        }

        VirtualMemoryUtility.FreeAddressSpace(addressSpace, out errorState);
    }