private NvInternalResult AllocSpace(ref AllocSpaceArguments arguments) { AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize; NvInternalResult result = NvInternalResult.Success; lock (addressSpaceContext) { // Note: When the fixed offset flag is not set, // the Offset field holds the alignment size instead. if ((arguments.Flags & AddressSpaceFlags.FixedOffset) != 0) { bool regionInUse = _memoryAllocator.IsRegionInUse(arguments.Offset, size, out ulong freeAddressStartPosition); ulong address; if (!regionInUse) { _memoryAllocator.AllocateRange(arguments.Offset, size, freeAddressStartPosition); address = freeAddressStartPosition; } else { address = NvMemoryAllocator.PteUnmapped; } arguments.Offset = address; } else { ulong address = _memoryAllocator.GetFreeAddress(size, out ulong freeAddressStartPosition, arguments.Offset); if (address != NvMemoryAllocator.PteUnmapped) { _memoryAllocator.AllocateRange(address, size, freeAddressStartPosition); } arguments.Offset = address; } if (arguments.Offset == NvMemoryAllocator.PteUnmapped) { arguments.Offset = 0; Logger.Warning?.Print(LogClass.ServiceNv, $"Failed to allocate size {size:x16}!"); result = NvInternalResult.OutOfMemory; } else { addressSpaceContext.AddReservation(arguments.Offset, size); } } return(result); }
private NvInternalResult AllocSpace(ref AllocSpaceArguments arguments) { AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context); ulong size = (ulong)arguments.Pages * (ulong)arguments.PageSize; NvInternalResult result = NvInternalResult.Success; lock (addressSpaceContext) { // Note: When the fixed offset flag is not set, // the Offset field holds the alignment size instead. if ((arguments.Flags & AddressSpaceFlags.FixedOffset) != 0) { arguments.Offset = (long)addressSpaceContext.Gmm.ReserveFixed((ulong)arguments.Offset, size); } else { arguments.Offset = (long)addressSpaceContext.Gmm.Reserve((ulong)size, (ulong)arguments.Offset); } if (arguments.Offset < 0) { arguments.Offset = 0; Logger.PrintWarning(LogClass.ServiceNv, $"Failed to allocate size {size:x16}!"); result = NvInternalResult.OutOfMemory; } else { addressSpaceContext.AddReservation(arguments.Offset, (long)size); } } return(result); }