Struct LogMemoryManager
Interface for allocating and managing Payload buffers for Log
Inherited Members
Namespace: Unity.Logging
Assembly: Unity.Logging.dll
Syntax
[BurstCompile]
[GenerateTestsForBurstCompatibility]
public struct LogMemoryManager
Remarks
A Payload buffer is allocated when creating a new log message, the actual message data, i.e. the "Payload", is serialized
into this buffer by the log producer. A Payload
Fields
MaximumRingBufferGrowFactor
Maximum value for Buffer
Declaration
public const float MaximumRingBufferGrowFactor = 1000
Field Value
Type | Description |
---|---|
float |
MaximumRingBufferGrowThreshold
Maximum value for Buffer
Declaration
public const float MaximumRingBufferGrowThreshold = 1
Field Value
Type | Description |
---|---|
float |
MaximumRingBufferSampleCount
Maximum value for Buffer
Declaration
public const uint MaximumRingBufferSampleCount = 10000
Field Value
Type | Description |
---|---|
uint |
MaximumRingBufferShrinkFactor
Maximum value for Buffer
Declaration
public const float MaximumRingBufferShrinkFactor = 1
Field Value
Type | Description |
---|---|
float |
MaximumRingBufferShrinkThreshold
Maximum value for Buffer
Declaration
public const float MaximumRingBufferShrinkThreshold = 1
Field Value
Type | Description |
---|---|
float |
MinimumRingBufferGrowFactor
Minimum value for Buffer
Declaration
public const float MinimumRingBufferGrowFactor = 1
Field Value
Type | Description |
---|---|
float |
MinimumRingBufferGrowThreshold
Minimum value for Buffer
Declaration
public const float MinimumRingBufferGrowThreshold = 0
Field Value
Type | Description |
---|---|
float |
MinimumRingBufferShrinkFactor
Minimum value for Buffer
Declaration
public const float MinimumRingBufferShrinkFactor = 0.01
Field Value
Type | Description |
---|---|
float |
MinimumRingBufferShrinkThreshold
Minimum value for Buffer
Declaration
public const float MinimumRingBufferShrinkThreshold = 0
Field Value
Type | Description |
---|---|
float |
Properties
IsInitialized
Returns if this Log
Declaration
public bool IsInitialized { get; }
Property Value
Type | Description |
---|---|
bool |
Parameters
Parameter values provided to Initialize(Log
Declaration
public LogMemoryManagerParameters Parameters { get; }
Property Value
Type | Description |
---|---|
Log |
Methods
AllocateDisjointedBuffer(ref FixedList512Bytes<ushort>, NativeList<PayloadHandle>)
Allocates a new Disjointed buffer, which includes allocating the individual Payloads that make up the entire buffer.
Declaration
public PayloadHandle AllocateDisjointedBuffer(ref FixedList512Bytes<ushort> payloadSizes, NativeList<PayloadHandle> payloadHandles = default)
Parameters
Type | Name | Description |
---|---|---|
Fixed |
payloadSizes | Set of buffer sizes to allocate for each Payload that comprises the DisjointedBuffer. |
Native |
payloadHandles | Optional list that receives the Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
AllocateDisjointedBuffer(ref FixedList64Bytes<ushort>, NativeList<PayloadHandle>)
Allocates a new Disjointed buffer, which includes allocating the individual Payloads that make up the entire buffer.
Declaration
public PayloadHandle AllocateDisjointedBuffer(ref FixedList64Bytes<ushort> payloadSizes, NativeList<PayloadHandle> payloadHandles = default)
Parameters
Type | Name | Description |
---|---|---|
Fixed |
payloadSizes | Set of buffer sizes to allocate for each Payload that comprises the DisjointedBuffer. |
Native |
payloadHandles | Optional list that receives the Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
Remarks
A 'Disjointed' buffer is a set of individual Payload buffers that are collectively treated as a single buffer; it's similar to a Jagged Array or can
be thought of as an "array of arrays". Internally, the Disjointed buffer is implemented by a "head" buffer that holds Payload
Disjointed buffers can either be allocated up front via this Method or created from existing Payloads via Create
When using this method, the individual Payload buffers are automatically allocated using the passed in size values. All Payload allocations sizes (including
the head buffer) must fall within the Minimum
IMPORTANT: If any of the allocations (including the head buffer) fail, the entire operation is aborted and any allocated memory is released. However that memory won't be available for new allocations until after it's been reclaimed by a call to Update(). This means, an attempt to allocate too much memory may result in a significant waste of available space causing other allocation requests to fail.
Disjointed buffers are intended for the following scenarios:
- Payload data exceeds the maximum Payload size and must be broken up into multiple pieces
- The entire Payload data size isn't known up front and must be allocated in different stages
- Additional data needs to be "appended" to an existing payload but without needing to completely reallocate a new buffer
In general, Disjointed buffers should be treated as a single allocation and the individual Payloads that make up the buffer should only be used for immediate reading/writing data. It's recommended to follow these guidelines:
- Do not store or pass the individual Payload handles; only the head handle (returned by this method) should be stored
- Do not release the individual payload allocations; all Disjointed memory is released through the head allocation
- Do not call Lock
Payload on individual payload handle; only the head buffer should be lockedBuffer(Payload Handle) - Do not use a given Payload allocation in multiple Disjointed buffers
- Do not use a Disjointed head handle within another Disjointed buffer (unsupported scenario)
NOTE: These rules are not generally not checked nor enforced, and any validation that is performed only occurs when ENABLE_UNITY_COLLECTIONS_CHECKS or UNITY_DOTS_DEBUG is enabled.
AllocateDisjointedBuffer(ref NativeList<ushort>, NativeList<PayloadHandle>)
Allocates a new Disjointed buffer, which includes allocating the individual Payloads that make up the entire buffer.
Declaration
public PayloadHandle AllocateDisjointedBuffer(ref NativeList<ushort> payloadSizes, NativeList<PayloadHandle> payloadHandles = default)
Parameters
Type | Name | Description |
---|---|---|
Native |
payloadSizes | Set of buffer sizes to allocate for each Payload that comprises the DisjointedBuffer. |
Native |
payloadHandles | Optional list that receives the Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
AllocatePayloadBuffer(uint)
Allocates a new Payload buffer from the default Payload container.
Declaration
public PayloadHandle AllocatePayloadBuffer(uint payloadSize)
Parameters
Type | Name | Description |
---|---|---|
uint | payloadSize | Number of bytes to allocate; must fall within the range of Minimum |
Returns
Type | Description |
---|---|
Payload |
A valid Payload |
AllocatePayloadBuffer(uint, out NativeArray<byte>)
Allocates a new Payload buffer from the default Payload container.
Declaration
public PayloadHandle AllocatePayloadBuffer(uint payloadSize, out NativeArray<byte> buffer)
Parameters
Type | Name | Description |
---|---|---|
uint | payloadSize | Number of bytes to allocate; must fall within the range of Minimum |
Native |
buffer | NativeArray that allows safe access to the allocated Payload buffer |
Returns
Type | Description |
---|---|
Payload |
A valid Payload |
Remarks
If successful a PayloadHandle referencing the allocated memory is returned, and a NativeArray with read/write access (as a view into the buffer) is passed out. If allocation fails an invalid handle and buffer are returned.
The PayloadHandle must be saved, as it's needed to retrieve the payload buffer again and also to release it. However, the passed out NativeArray is only intended for immediate reading/writing into the buffer; the variable must not be saved.
IMPORTANT: The Payload buffer must eventually be released by calling Release
NOTE: Do not call Dispose on the returned NativeArray; it's only a view into the Payload buffer.
CreateDisjointedPayloadBufferFromExistingPayloads(ref FixedList4096Bytes<PayloadHandle>)
Creates a new Disjointed buffer that's composed of preallocated Payloads, instead of allocating new ones.
Declaration
public PayloadHandle CreateDisjointedPayloadBufferFromExistingPayloads(ref FixedList4096Bytes<PayloadHandle> payloadHandles)
Parameters
Type | Name | Description |
---|---|---|
Fixed |
payloadHandles | Set a Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
Remarks
CreateDisjointedPayloadBufferFromExistingPayloads(ref FixedList512Bytes<PayloadHandle>)
Creates a new Disjointed buffer that's composed of preallocated Payloads, instead of allocating new ones.
Declaration
public PayloadHandle CreateDisjointedPayloadBufferFromExistingPayloads(ref FixedList512Bytes<PayloadHandle> payloadHandles)
Parameters
Type | Name | Description |
---|---|---|
Fixed |
payloadHandles | Set a Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
Remarks
See Allocate
Use this method to group a set of Payload buffers that have already been allocated into a single Disjointed buffer.
In this case, only the "head" payload needs to be allocated, which is then filled with the specified Payload
Disjointed buffers created this way should be treated exactly the same as those allocated up front; the individual Payloads
are now part of the whole buffer and should only be used for immediate reading/writing of data. Likewise, calling
Release
NOTE: The Payload
CreateDisjointedPayloadBufferFromExistingPayloads(ref NativeList<PayloadHandle>)
Creates a new Disjointed buffer that's composed of preallocated Payloads, instead of allocating new ones.
Declaration
public PayloadHandle CreateDisjointedPayloadBufferFromExistingPayloads(ref NativeList<PayloadHandle> payloadHandles)
Parameters
Type | Name | Description |
---|---|---|
Native |
payloadHandles | Set a Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
Remarks
DebugDetailsOfPayloadHandle(ref PayloadHandle)
Debug function that returns information about Payload
Declaration
public FixedString4096Bytes DebugDetailsOfPayloadHandle(ref PayloadHandle handle)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | PayloadHandle to analyze |
Returns
Type | Description |
---|---|
Fixed |
FixedString that contains debug information |
DebugStateString(FixedString128Bytes)
Gathers the internal statistics of this Log
Declaration
public FixedString4096Bytes DebugStateString(FixedString128Bytes name = default)
Parameters
Type | Name | Description |
---|---|---|
Fixed |
name | Optional name of the log memory manager |
Returns
Type | Description |
---|---|
Fixed |
FixedString4096Bytes that contains debug internal state of this manager |
FromPointer(IntPtr)
Converts pointer into ref LogMemoryManager
Declaration
public static ref LogMemoryManager FromPointer(IntPtr memoryManager)
Parameters
Type | Name | Description |
---|---|---|
Int |
memoryManager | IntPtr that should reference LogMemoryManager. Cannot be null |
Returns
Type | Description |
---|---|
Log |
LogMemoryManager converted from a pointer |
GetCurrentDefaultBufferCapacity()
Returns the Capacity of the current Payload container from which Payloads are allocated from.
Declaration
public uint GetCurrentDefaultBufferCapacity()
Returns
Type | Description |
---|---|
uint | Capacity of the current Payload container from which Payloads are allocated from. |
Remarks
During a Resize operation 2 containers are used: an "active" one which holds the new size and the "old" one which holds the previous allocations that haven't yet been released. Only the Capacity from the "active" container is returned; the Overflow buffer is never included.
GetCurrentDefaultBufferUsage()
Returns the Usage of the current Payload container from which Payloads are allocated from.
Declaration
public uint GetCurrentDefaultBufferUsage()
Returns
Type | Description |
---|---|
uint | Usage of the current Payload container from which Payloads are allocated from. |
Remarks
During a Resize operation 2 containers are used: an "active" one which holds the new size and the "old" one which holds the previous allocations that haven't yet been released. Only the Usage from the "active" container is returned; the Overflow buffer is never included.
Initialize()
Initializes MemoryManager using default parameters.
Declaration
public void Initialize()
Remarks
Initialize(LogMemoryManagerParameters)
Initializes MemoryManager with the specified set of parameters.
Declaration
public void Initialize(LogMemoryManagerParameters parameters)
Parameters
Type | Name | Description |
---|---|---|
Log |
parameters | Log |
Remarks
Parameter values must fall within the specified minimum/maximum ranges, and invalid parameters are replaced with their corresponding default value.
IsPayloadBufferLocked(PayloadHandle)
Tests if the specified Payload buffer is locked and returns the number of individual locks.
Declaration
public bool IsPayloadBufferLocked(PayloadHandle handle)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
Returns
Type | Description |
---|---|
bool | True if Payload buffer has at least 1 lock and false otherwise. |
Remarks
IsPayloadBufferLocked(PayloadHandle, out int)
Tests if the specified Payload buffer is locked and returns the number of individual locks.
Declaration
public bool IsPayloadBufferLocked(PayloadHandle handle, out int numLockContexts)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
int | numLockContexts | Number of active locks on this Payload buffer. |
Returns
Type | Description |
---|---|
bool | True if Payload buffer has at least 1 lock and false otherwise. |
See Also
IsPayloadHandleValid(PayloadHandle)
Tests if Payload
Declaration
public bool IsPayloadHandleValid(PayloadHandle handle)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | PayloadHandle value to test for validity. |
Returns
Type | Description |
---|---|
bool | True if handle references a valid Payload buffer and false if not. |
Remarks
Unlike Is
LockPayloadBuffer(PayloadHandle)
Adds a "Lock" on the specified Payload buffer, preventing it from being released while the lock is active.
Declaration
public PayloadLockContext LockPayloadBuffer(PayloadHandle handle)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
Returns
Type | Description |
---|---|
Payload |
If successful, a valid Payload |
Remarks
Only active Payload buffers can be locked; this method will fail if the buffer has already been released. Multiple locks can be applied to the same buffer simultaneously, (distinguished by a "context" value) but is limited to a max of 64.
Each successful "lock" operation generates a Payload
The purpose of Payload Locks is to coordinate multiple log Listeners sharing the same payload memory, so the buffer is only released once all Listeners are finished. Upon receiving a LogMessage, a Listener immediately calls this method to lock the buffer, then processes and outputs the log data, and finally releases the lock when finished. This ensures the buffer isn't released prematurely while a Listener is still accessing the memory.
See Also
ReleasePayloadBuffer(PayloadHandle, out PayloadReleaseResult, bool)
Releases the Payload memory allocated within the default Payload container.
Declaration
public bool ReleasePayloadBuffer(PayloadHandle handle, out PayloadReleaseResult result, bool force = false)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | The Payload |
Payload |
result | A detailed result code from Payload |
bool | force | Forces release of the Payload buffer even if it can't be performed "cleanly". |
Returns
Type | Description |
---|---|
bool | True if the payload buffer specifically referenced by the handle is released and false if not. For DisjointedBuffers, true is only returned if the "head" buffer is actually released. Valid Payloads referenced by a DisjointedBuffer are always released regardless of the return value. |
Remarks
This must be called when the Payload data is no longer needed, otherwise payload blocks will "leak" within the container. Once complete the handle becomes invalid and attempts to retrieve the buffer again will fail.
If the Payload buffer has been "locked", this operation will fail until all locks have been released. However, this behavior can be overridden using the "force" option; if set the buffer will be released irregardless of the number of locks on it.
If the handle is for a Disjointed buffer, then all individual Payload buffers will also be released. When working with DisjointedBuffers, this is the recommended way to handle individual payloads. In general, it's not recommended to manually release payloads referenced by a DisjointedBuffer.
Should a given Payload referenced by the DisjointedBuffer handle fail to release (for any reason) the call
will fail with the result: Disjointed
In general, it isn't necessary to call this directly because Log
ReleasePayloadBufferDeferred(PayloadHandle)
Releases the Payload memory allocated within the default Payload container after two (system is double buffered) Update()> calls
Declaration
public void ReleasePayloadBufferDeferred(PayloadHandle handle)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | The Payload |
Remarks
This call adds payload handle to 'deferred' list, so it can be released after everything that uses this payload was processed.
General use case is 'decoration' for logging messages. Some messages can be decorated with this payloads.
Then Decorator is released, ReleasePayloadBufferDeferred is called and that guarantees that this decoration won't be attached to any log from this point.
And then after two Update()> calls when all users of this Payload were processed - we should safely release it.
For more details see Release
RetrieveDisjointedPayloadBuffer(PayloadHandle, int, bool, out NativeArray<byte>)
Retrieves a NativeArray to safely access an individual Payload that's part of a Disjointed buffer.
Declaration
public bool RetrieveDisjointedPayloadBuffer(PayloadHandle handle, int payloadBufferIndex, bool readWriteAccess, out NativeArray<byte> payloadBuffer)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A Payload |
int | payloadBufferIndex | Index of the Payload, referenced by the Disjointed buffer, to retrieve. |
bool | readWriteAccess | True to allow write-access to the returned NativeArray, otherwise it's read-only. |
Native |
payloadBuffer | NativeArray that allows safe access to the allocated Payload buffer. |
Returns
Type | Description |
---|---|
bool | True if successfully accessed Payload buffer. |
Remarks
See Allocate
Use this method to safely retrieve one of the Payload buffers, that's referenced by a Disjointed buffer, for
reading or writing payload data, similar to Retrieve
The Payload buffer to retrieve is specified by an index of the Payload
As with Retrieve
RetrieveDisjointedPayloadBuffer(PayloadHandle, int, out NativeArray<byte>)
Retrieves a NativeArray to safely access an individual Payload that's part of a Disjointed buffer.
Declaration
public bool RetrieveDisjointedPayloadBuffer(PayloadHandle handle, int payloadBufferIndex, out NativeArray<byte> payloadBuffer)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A Payload |
int | payloadBufferIndex | Index of the Payload, referenced by the Disjointed buffer, to retrieve. |
Native |
payloadBuffer | NativeArray that allows safe access to the allocated Payload buffer. |
Returns
Type | Description |
---|---|
bool | True if successfully accessed Payload buffer. |
Remarks
RetrievePayloadBuffer(PayloadHandle, bool, out NativeArray<byte>)
Retrieves a NativeArray to safely access Payload memory.
Declaration
public bool RetrievePayloadBuffer(PayloadHandle handle, bool readWriteAccess, out NativeArray<byte> payloadBuffer)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
bool | readWriteAccess | True to allow write-access to the returned NativeArray, otherwise it's read-only |
Native |
payloadBuffer | NativeArray that allows safe access to the allocated Payload buffer. |
Returns
Type | Description |
---|---|
bool | True if successfully accessed Payload buffer. |
Remarks
Listeners must call this to read the log message data when processing a Log
By default the return NativeArray is read-only, since typically Listeners only need to de-serialize the buffer contents and don't need to write into the buffer.
RetrievePayloadBuffer(PayloadHandle, out NativeArray<byte>)
Retrieves a NativeArray to safely access Payload memory.
Declaration
public bool RetrievePayloadBuffer(PayloadHandle handle, out NativeArray<byte> payloadBuffer)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
Native |
payloadBuffer | NativeArray that allows safe access to the allocated Payload buffer. |
Returns
Type | Description |
---|---|
bool | True if successfully accessed Payload buffer. |
Remarks
Shutdown()
Releases all allocated memory and returns MemoryManager to an uninitialized state.
Declaration
public void Shutdown()
Remarks
Do not call this directly; shutdown is performed through Shutdown().
UnlockPayloadBuffer(PayloadHandle, PayloadLockContext)
Releases an existing Payload Lock on the specified buffer for a given context.
Declaration
public bool UnlockPayloadBuffer(PayloadHandle handle, PayloadLockContext context)
Parameters
Type | Name | Description |
---|---|---|
Payload |
handle | A valid Payload |
Payload |
context | Value returned by preceding call to Lock |
Returns
Type | Description |
---|---|
bool | True if unlock operation was successful or not. |
Remarks
Each call to Lock
If the specified buffer wasn't locked for this specific context, the unlock operation will fail.
See Also
Update()
Performs maintenance work on the allocated RingBuffers and should be called once per frame.
Enters exclusive lock, so make sure it is not called during Lock
Declaration
public void Update()
Remarks
Do not call this directly; updating is performed automatically by the Log