/// <summary> /// try to rent some memory /// </summary> /// <param name="length">the length of memory</param> /// <param name="rentedMemory">rented memory</param> /// <returns>if false, rent operation is failed</returns> public bool TryRent(int length, out RentedMemory rentedMemory) { if (indexer.TryLock(length, out var range)) { rentedMemory = new RentedMemory(this, range, bytes[range]); return(true); } rentedMemory = default; return(false); }
/// <summary> /// try to rent some memory /// </summary> /// <param name="length">the length of memory</param> /// <param name="rentedMemory">rented memory</param> /// <returns>if false, rent operation is failed</returns> public bool TryRent(int length, out RentedMemory rentedMemory) { if (length > BlockSize) { rentedMemory = default; return(false); } rentableResetEvent.WaitOne(); Interlocked.Increment(ref rentingCount); try { foreach (var rentableMemories in pool) { if (rentableMemories.TryRent(length, out rentedMemory)) { return(true); } } if (BlockCount < MaxBlockCount) { rentableResetEvent.Reset(); expansionRequiredResetEvent.Set(); } rentedMemory = default; return(false); } finally { Interlocked.Decrement(ref rentingCount); } }
/// <summary> /// return rented memory /// </summary> /// <param name="rentedMemory">rented memory</param> public void Return(RentedMemory rentedMemory) { indexer.Unlock(rentedMemory.RentedRange); rentedMemory.Memory.Span.Fill(0); }