/// <summary> /// DirectOwnedBuffer constructor. Takes a buffer to store interlocked values for locking and versions. /// The buffer could be null. DirectOwnedBuffer owns the lockers buffer. /// </summary> internal DirectOwnedBuffer(DirectOwnedBuffer <byte> lockersBuffer, T[] array, int arrayOffset, int length, IntPtr pointer = new IntPtr()) : base(array, arrayOffset, length, pointer) { if (lockersBuffer != null && lockersBuffer.Length != 64) { throw new ArgumentException("Lockers buffer must have length of 64 bytes."); } Init(lockersBuffer); }
// NB this is recursive, the input lockersBuffer should have their own lockersBuffer set to null // This is to have access to protected Initialize method on the lockersBuffer. /// <summary> /// DirectOwnedBuffer constructor. Takes a lockers buffer to store interlocked values for locking and versions. /// The buffer could be null. DirectOwnedBuffer owns the lockers buffer. /// </summary> internal DirectOwnedBuffer(DirectOwnedBuffer <byte> lockersBuffer, T[] array) : base(array) { if (lockersBuffer != null && lockersBuffer.Length != 64) { throw new ArgumentException("Lockers buffer must have length of 64 bytes."); } // locker, version, next version, size, process ref count + padding to fill cache line Init(lockersBuffer); }
private void Init(DirectOwnedBuffer <byte> lockers) { if (lockers != null) { _lockers = lockers; _lockersHandle = _lockers.Buffer.Pin(); Interlocked.Increment(ref *_processCount); } if (TypeHelper <T> .IsPinnable) { _dataHandle = this.Buffer.Pin(); } else { if (Array == null) { throw new NotSupportedException("Native storage for non-blittable types is not supported"); } } }