public void AllocateFree(int offset, GATManagedData inext) { next = inext; _offset = offset; allocatedSize = 0; _retainCount = 0; }
/// <summary> /// Finds and virtually allocates a GATManagedData instance before /// returning it as a GATData reference. /// First, the algorithm looks at the free chunks bin of appropriate size. /// If the bin doesn't hold any chunk, it will check if there is enough /// unfragmented space. If there isn't, it will look at bins holding larger chunks /// and fragment one if found. Finally, it will attempt defragmenting and run again, /// before logging an out of memory error. /// </summary> /// <returns> /// A GATData reference to a GATManagedData instance. /// </returns> /// <param name='size'> /// Size of the chunk to virtually allocate. /// </param> public GATData GetDataContainer(int size) { GATManagedData chunk = null; int binIndex; int binSize; binIndex = GetBinIndexForSize(size); binSize = _binWidth + binIndex * _binWidth; if (_freeChunksBins[binIndex].Count != 0) { chunk = _freeChunksBins[binIndex].Pop(); } else { if (_unallocatedCursor.MaxSize >= binSize) { chunk = _unallocatedCursor; chunk.allocatedSize = size; _unallocatedCursor = GetOrMakeChunk(); _unallocatedCursor.AllocateFree(chunk.MemOffset + binSize, _endCursor); chunk.next = _unallocatedCursor; } else { if (TryFragmentBins(binIndex + 1, binSize, ref chunk) == false) { Defragment(); if (_freeChunksBins[binIndex].Count != 0) { chunk = _freeChunksBins[binIndex].Pop(); } else { if (_unallocatedCursor.MaxSize >= binSize) { chunk = _unallocatedCursor; chunk.allocatedSize = size; _unallocatedCursor = GetOrMakeChunk(); _unallocatedCursor.AllocateFree(chunk.MemOffset + binSize, _endCursor); chunk.next = _unallocatedCursor; } else if (TryFragmentBins(binIndex + 1, binSize, ref chunk) == false) { throw new GATException("Out of memory!"); } } } } } chunk.allocatedSize = size; return(chunk); }
private void AddToFreeChunksBins(GATManagedData chunk) { int binIndex; int size; size = chunk.MaxSize; binIndex = (size - _binWidth) / _binWidth; _freeChunksBins[binIndex].Push(chunk); }
private void InitCursors() { _endCursor = new GATFixedData(this, ""); _endCursor.AllocateFree(_mainBuffer.Length, null); _unallocatedCursor = new GATManagedData(this); _unallocatedCursor.AllocateFree(0, _endCursor); _firstCursor = new GATManagedData(this); _firstCursor.AllocateFree(0, _unallocatedCursor); }
private GATManagedData GetOrMakeChunk() { if (_pool.Count != 0) { return(_pool.Pop()); } else { GATManagedData data = new GATManagedData(this); return(data); } }
bool TryFragmentBins(int fromBinIndex, int binSize, ref GATManagedData chunk) { for (int i = fromBinIndex; i < _nbOfBins; i++) { if (_freeChunksBins[i].Count != 0) { chunk = _freeChunksBins[i].Pop(); GATManagedData subChunk = GetOrMakeChunk(); subChunk.AllocateFree(chunk.MemOffset + binSize, chunk.next); chunk.next = subChunk; AddToFreeChunksBins(subChunk); return(true); } } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="GATDataAllocator"/> class. /// In most cases, only the default allocator initialized by GATManager is /// required. /// </summary> public GATDataAllocator( InitializationSettings initSettings ) { int i; _totalSize = ( int )( initSettings.preAllocatedAudioDuration * GATInfo.OutputSampleRate ); _mainBuffer = new float[ _totalSize ]; _pool = new Stack< GATManagedData >( initSettings.maxConcurrentSamples ); _binWidth = initSettings.binWidth; _nbOfBins = initSettings.nbOfBins; for( i = 0; i < initSettings.maxConcurrentSamples; i++ ) { GATManagedData data = new GATManagedData( this ); _pool.Push( data ); } _freeChunksBins = new Stack< GATManagedData >[ _nbOfBins ]; for( i = 0; i < _nbOfBins; i++ ) { _freeChunksBins[i] = new Stack< GATManagedData >(20); } InitCursors(); _maxBinSize = _nbOfBins * _binWidth; #if !UNITY_WEBPLAYER _mainBufferHandle = GCHandle.Alloc( _mainBuffer, GCHandleType.Pinned ); _mainBufferPointer = _mainBufferHandle.AddrOfPinnedObject(); #endif #if GAT_DEBUG Debug.Log( "GATDataAllocator initialized, total size: " + _totalSize + " largest allocatable chunk: " + _maxBinSize ); #endif }
/// <summary> /// Initializes a new instance of the <see cref="GATDataAllocator"/> class. /// In most cases, only the default allocator initialized by GATManager is /// required. /// </summary> public GATDataAllocator(InitializationSettings initSettings) { int i; _totalSize = ( int )(initSettings.preAllocatedAudioDuration * GATInfo.OutputSampleRate); _mainBuffer = new float[_totalSize]; _pool = new Stack <GATManagedData>(initSettings.maxConcurrentSamples); _binWidth = initSettings.binWidth; _nbOfBins = initSettings.nbOfBins; for (i = 0; i < initSettings.maxConcurrentSamples; i++) { GATManagedData data = new GATManagedData(this); _pool.Push(data); } _freeChunksBins = new Stack <GATManagedData> [_nbOfBins]; for (i = 0; i < _nbOfBins; i++) { _freeChunksBins[i] = new Stack <GATManagedData>(20); } InitCursors(); _maxBinSize = _nbOfBins * _binWidth; #if !UNITY_WEBPLAYER _mainBufferHandle = GCHandle.Alloc(_mainBuffer, GCHandleType.Pinned); _mainBufferPointer = _mainBufferHandle.AddrOfPinnedObject(); #endif #if GAT_DEBUG Debug.Log("GATDataAllocator initialized, total size: " + _totalSize + " largest allocatable chunk: " + _maxBinSize); #endif }
public void AllocateFree( int offset, GATManagedData inext ) { next = inext; _offset = offset; allocatedSize = 0; _retainCount = 0; }
bool TryFragmentBins( int fromBinIndex, int binSize, ref GATManagedData chunk ) { for( int i = fromBinIndex; i < _nbOfBins; i++ ) { if( _freeChunksBins[ i ].Count != 0 ) { chunk = _freeChunksBins[ i ].Pop (); GATManagedData subChunk = GetOrMakeChunk(); subChunk.AllocateFree( chunk.MemOffset + binSize, chunk.next ); chunk.next = subChunk; AddToFreeChunksBins( subChunk ); return true; } } return false; }
private void InitCursors() { _endCursor = new GATFixedData( this, "" ); _endCursor.AllocateFree( _mainBuffer.Length, null ); _unallocatedCursor = new GATManagedData( this ); _unallocatedCursor.AllocateFree( 0, _endCursor ); _firstCursor = new GATManagedData( this ); _firstCursor.AllocateFree( 0, _unallocatedCursor ); }
private GATManagedData GetOrMakeChunk() { if( _pool.Count != 0 ) { return _pool.Pop(); } else { GATManagedData data = new GATManagedData( this ); return data; } }
private void AddToFreeChunksBins( GATManagedData chunk ) { int binIndex; int size; size = chunk.MaxSize; binIndex = ( size - _binWidth ) / _binWidth; _freeChunksBins[ binIndex ].Push( chunk ); }