diff options
Diffstat (limited to '7zip/Compress/LZ/MT/MT.cpp')
-rwxr-xr-x | 7zip/Compress/LZ/MT/MT.cpp | 295 |
1 files changed, 0 insertions, 295 deletions
diff --git a/7zip/Compress/LZ/MT/MT.cpp b/7zip/Compress/LZ/MT/MT.cpp deleted file mode 100755 index b0ac456d..00000000 --- a/7zip/Compress/LZ/MT/MT.cpp +++ /dev/null @@ -1,295 +0,0 @@ -// MT.cpp - -#include "StdAfx.h" - -#include "../../../../Common/Alloc.h" - -#include "MT.h" - -static const UInt32 kBlockSize = (1 << 14); - -static DWORD WINAPI MFThread(void *threadCoderInfo) -{ - return ((CMatchFinderMT *)threadCoderInfo)->ThreadFunc(); -} - -CMatchFinderMT::CMatchFinderMT(): - m_Buffer(0), - m_NeedStart(true) -{ - m_BlockIndex = kNumMTBlocks - 1; - m_CS[m_BlockIndex].Enter(); - if (!m_Thread.Create(MFThread, this)) - throw 271826; -} - -CMatchFinderMT::~CMatchFinderMT() -{ - m_Exit = true; - m_CS[m_BlockIndex].Leave(); - m_CanChangeBufferPos.Set(); - if (m_NeedStart) - m_MtCanStart.Set(); - m_Thread.Wait(); - FreeMem(); -} - -void CMatchFinderMT::FreeMem() -{ - ::MyFree(m_Buffer); - m_Buffer = 0; -} - -STDMETHODIMP CMatchFinderMT::Create(UInt32 sizeHistory, UInt32 keepAddBufferBefore, - UInt32 matchMaxLen, UInt32 keepAddBufferAfter) -{ - FreeMem(); - m_MatchMaxLen = matchMaxLen; - if (kBlockSize <= matchMaxLen * 4) - return E_INVALIDARG; - UInt32 bufferSize = kBlockSize * kNumMTBlocks; - m_Buffer = (UInt32 *)::MyAlloc(bufferSize * sizeof(UInt32)); - if (m_Buffer == 0) - return E_OUTOFMEMORY; - keepAddBufferBefore += bufferSize; - keepAddBufferAfter += (kBlockSize + 1); - return m_MatchFinder->Create(sizeHistory, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter); -} - -// UInt32 blockSizeMult = 800 -HRESULT CMatchFinderMT::SetMatchFinder(IMatchFinder *matchFinder) -{ - m_MatchFinder = matchFinder; - return S_OK; -} - -STDMETHODIMP CMatchFinderMT::SetStream(ISequentialInStream *s) -{ - return m_MatchFinder->SetStream(s); -} - -// Call it after ReleaseStream / SetStream -STDMETHODIMP CMatchFinderMT::Init() -{ - m_NeedStart = true; - m_Pos = 0; - m_PosLimit = 0; - - HRESULT result = m_MatchFinder->Init(); - if (result == S_OK) - m_DataCurrentPos = m_MatchFinder->GetPointerToCurrentPos(); - m_NumAvailableBytes = m_MatchFinder->GetNumAvailableBytes(); - return result; -} - -// ReleaseStream is required to finish multithreading -STDMETHODIMP_(void) CMatchFinderMT::ReleaseStream() -{ - m_StopWriting = true; - m_CS[m_BlockIndex].Leave(); - if (!m_NeedStart) - { - m_CanChangeBufferPos.Set(); - m_MtWasStopped.Lock(); - m_NeedStart = true; - } - m_MatchFinder->ReleaseStream(); - m_BlockIndex = kNumMTBlocks - 1; - m_CS[m_BlockIndex].Enter(); -} - -STDMETHODIMP_(Byte) CMatchFinderMT::GetIndexByte(Int32 index) -{ - return m_DataCurrentPos[index]; -} - -STDMETHODIMP_(UInt32) CMatchFinderMT::GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) -{ - if ((Int32)(index + limit) > m_NumAvailableBytes) - limit = m_NumAvailableBytes - (index); - distance++; - const Byte *pby = m_DataCurrentPos + index; - UInt32 i; - for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++); - return i; -} - -STDMETHODIMP_(const Byte *) CMatchFinderMT::GetPointerToCurrentPos() -{ - return m_DataCurrentPos; -} - -STDMETHODIMP_(UInt32) CMatchFinderMT::GetNumAvailableBytes() -{ - return m_NumAvailableBytes; -} - -void CMatchFinderMT::GetNextBlock() -{ - if (m_NeedStart) - { - m_NeedStart = false; - for (UInt32 i = 0; i < kNumMTBlocks; i++) - m_StopReading[i] = false; - m_StopWriting = false; - m_Exit = false; - m_MtWasStarted.Reset(); - m_MtWasStopped.Reset(); - m_CanChangeBufferPos.Reset(); - m_BufferPosWasChanged.Reset(); - m_MtCanStart.Set(); - m_MtWasStarted.Lock(); - m_Result = S_OK; - } - for (;;) - { - UInt32 nextIndex = (m_BlockIndex == kNumMTBlocks - 1) ? 0 : m_BlockIndex + 1; - m_CS[nextIndex].Enter(); - if (!m_StopReading[nextIndex]) - { - m_CS[m_BlockIndex].Leave(); - m_BlockIndex = nextIndex; - break; - } - m_StopReading[nextIndex] = false; - m_CS[nextIndex].Leave(); - m_CanChangeBufferPos.Set(); - m_BufferPosWasChanged.Lock(); - m_CS[nextIndex].Enter(); - m_CS[m_BlockIndex].Leave(); - m_BlockIndex = nextIndex; - } - m_Pos = m_BlockIndex * kBlockSize; - m_PosLimit = m_Buffer[m_Pos++]; - m_NumAvailableBytes = m_Buffer[m_Pos++]; - m_Result = m_Results[m_BlockIndex]; -} - -STDMETHODIMP CMatchFinderMT::GetMatches(UInt32 *distances) -{ - if (m_Pos == m_PosLimit) - GetNextBlock(); - - if (m_Result != S_OK) - return m_Result; - m_NumAvailableBytes--; - m_DataCurrentPos++; - - const UInt32 *buffer = m_Buffer + m_Pos; - UInt32 len = *buffer++; - *distances++ = len; - m_Pos += 1 + len; - for (UInt32 i = 0; i != len; i += 2) - { - distances[i] = buffer[i]; - distances[i + 1] = buffer[i + 1]; - } - return S_OK; -} - -STDMETHODIMP CMatchFinderMT::Skip(UInt32 num) -{ - do - { - if (m_Pos == m_PosLimit) - GetNextBlock(); - - if (m_Result != S_OK) - return m_Result; - m_NumAvailableBytes--; - m_DataCurrentPos++; - - UInt32 len = m_Buffer[m_Pos++]; - m_Pos += len; - } - while(--num != 0); - return S_OK; -} - -STDMETHODIMP_(Int32) CMatchFinderMT::NeedChangeBufferPos(UInt32 /* numCheckBytes */) -{ - throw 1; -} - -STDMETHODIMP_(void) CMatchFinderMT::ChangeBufferPos() -{ - throw 1; -} - - -DWORD CMatchFinderMT::ThreadFunc() -{ - for (;;) - { - bool needStartEvent = true; - m_MtCanStart.Lock(); - HRESULT result = S_OK; - UInt32 blockIndex = 0; - for (;;) - { - m_CS[blockIndex].Enter(); - if (needStartEvent) - { - m_MtWasStarted.Set(); - needStartEvent = false; - } - else - m_CS[(blockIndex == 0) ? kNumMTBlocks - 1 : blockIndex - 1].Leave(); - if (m_Exit) - return 0; - if (m_StopWriting) - { - m_MtWasStopped.Set(); - m_CS[blockIndex].Leave(); - break; - } - if (result == S_OK) - { - IMatchFinder *mf = m_MatchFinder; - if (mf->NeedChangeBufferPos(kBlockSize) != 0) - { - // m_AskChangeBufferPos.Set(); - m_StopReading[blockIndex] = true; - m_CS[blockIndex].Leave(); - m_CanChangeBufferPos.Lock(); - m_CS[blockIndex].Enter(); - const Byte *bufferPosBefore = mf->GetPointerToCurrentPos(); - mf->ChangeBufferPos(); - m_DataCurrentPos += mf->GetPointerToCurrentPos() - bufferPosBefore; - m_BufferPosWasChanged.Set(); - } - else - { - UInt32 curPos = blockIndex * kBlockSize; - UInt32 limit = curPos + kBlockSize - m_MatchMaxLen - m_MatchMaxLen - 1; - UInt32 *buffer = m_Buffer; - m_Results[blockIndex] = S_OK; - curPos++; - UInt32 numAvailableBytes = mf->GetNumAvailableBytes(); - buffer[curPos++] = numAvailableBytes; - - while (numAvailableBytes-- != 0 && curPos < limit) - { - result = mf->GetMatches(buffer + curPos); - if (result != S_OK) - { - m_Results[blockIndex] = result; - break; - } - curPos += buffer[curPos] + 1; - } - buffer[blockIndex * kBlockSize] = curPos; - } - } - else - { - UInt32 curPos = blockIndex * kBlockSize; - m_Buffer[curPos] = curPos + 2; // size of buffer - m_Buffer[curPos + 1] = 0; // NumAvailableBytes - m_Results[blockIndex] = result; // error - } - if (++blockIndex == kNumMTBlocks) - blockIndex = 0; - } - } -} |