private void ReleaseMemorySegmentsAt(IntPtr memSegPtr) { // Проходим от указанного сегмента по связям с предыдущими. while (memSegPtr != IntPtr.Zero) { IntPtr releaseMemSegPtr = memSegPtr; memSegPtr = MemorySegment.GetPrev(releaseMemSegPtr); // Чистим связи с другими сегментами. MemorySegment.SetPrev(releaseMemSegPtr, IntPtr.Zero); MemorySegment.SetNext(releaseMemSegPtr, IntPtr.Zero); _allocator.Release(releaseMemSegPtr); } }
private void SwitchToPrev() { IntPtr prevMemSegPtr = MemorySegment.GetPrev(MemSegPtr); if (prevMemSegPtr != IntPtr.Zero) { SetCurrentMemSeg(prevMemSegPtr); // Сместиться могли более чем на 1 слот, поэтому прибавляем весь текущий сегмент. MemSegReadIndex += MemSegSize + 1; return; } throw new Exception(); }
public override void ReleaseReaded() { // Вычисляем, начиная с какого сегмента можно освободить прочитанную цепочку сегментов. // Тут возможны 2 варианта: // - Весь буфер уже прочитан, тогда можно освободить все. // - Буфер прочитан не полностью, тогда можно освободить все предыдущие, а текущий оставить. // Сценарий с освобождением всей цепочки требует более тщательной реализации и пока невозможен, // поэтому всегда будем освобождать только начиная с предыдущего. // Дело в том, что у буфера пока не может не быть какого-то сегмента, а при освобождении всех именно так // и получится, но сам буфер может использоваться для аккумуляции дальше. Будет реализовано потом, если // потребуется. IntPtr memSegPtr = MemorySegment.GetPrev(_memSegPtr); // Отвязываем от текущего. MemorySegment.SetPrev(_memSegPtr, IntPtr.Zero); ReleaseMemorySegmentsAt(memSegPtr); }