📄 circularbuf.h
字号:
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*******************************************************************************
* Filename:
* ---------
* CircularBuf.h
*
* Project:
* --------
* Catcher
*
* Description:
* ------------
* Template definition of circular buffer.
*
* Author:
* -------
* Angus Chen (mtk00306)
*
*==============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* $Revision: 1.0 $
* $Modtime: May 29 2003 14:48:32 $
* $Log: //mtkvs01/vmdata/PhoneSuiteApp/archives/comm/CircularBuf.h-arc $
*
* Rev 1.0 Feb 27 2004 18:28:10 admin
* Initial revision.
*
* Rev 1.0 Feb 27 2004 16:42:06 admin
* Initial revision.
*
* Rev 1.0 Aug 14 2003 21:27:04 admin
* Initial revision.
*
* Rev 1.0 Nov 19 2002 13:51:40 MTK00303
* Initial revision.
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*==============================================================================
*******************************************************************************/
#ifndef ANGUS_CIRCULARBUFFER_DEF_H
#define ANGUS_CIRCULARBUFFER_DEF_H
#include "Lock.h"
#ifndef AFX_INLINE
#define AFX_INLINE inline
#endif
template<class Type>
class ACircularBuf
{
public:
ACircularBuf();
~ACircularBuf();
bool StartBuffer(int size);
void StopBuffer();
void Clear();
bool IsFull();
bool IsEmpty();
bool CheckIn(Type &);
bool CheckOut(Type &);
bool GetWatch(Type &);
void AlignIn();
void AlignWatch();
bool ProceedWatch(int steps);
bool StepbackWatch(int steps);
protected:
bool started;
Type *m_Buffer;
int m_size;
int m_pIn;
int m_pOut;
int m_pWatch;
ACriticalSection m_CritSec;
HANDLE m_evIN[2];
HANDLE m_evOUT[2];
HANDLE m_evEXIT;
bool betweenInOut(int pwatch);
};
template<class Type>
AFX_INLINE ACircularBuf<Type>::ACircularBuf()
{
m_Buffer = NULL;
m_pIn = -1;
m_pOut = -1;
m_pWatch = -1;
m_size = 0;
m_evEXIT = NULL;
m_evIN[1] = NULL;
m_evOUT[1] = NULL;
started = false;
}
template<class Type>
AFX_INLINE ACircularBuf<Type>::~ACircularBuf()
{
Clear();
}
template<class Type>
AFX_INLINE void ACircularBuf<Type>::Clear()
{
// Clear buffer
if( m_Buffer!=NULL ) {
delete [] m_Buffer;
m_Buffer = NULL;
}
m_pIn = -1;
m_pOut = -1;
m_pWatch = -1;
m_size = 0;
// Close exit event
if( m_evEXIT!=NULL ) {
CloseHandle(m_evEXIT);
m_evEXIT = NULL;
}
// Close wait for space event
if( m_evIN[1]!=NULL ) {
CloseHandle(m_evIN[1]);
m_evIN[1] = NULL;
}
// Close wait for item event
if( m_evOUT[1]!=NULL) {
CloseHandle(m_evOUT[1]);
m_evOUT[1] = NULL;
}
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::StartBuffer(int size)
{
Clear();
m_size = size;
m_Buffer = new Type[size];
if( m_Buffer==NULL )
goto SetSizeFailed;
// Create exit event
m_evEXIT = ::CreateEvent(NULL, TRUE, FALSE, NULL);
if( m_evEXIT==NULL )
goto SetSizeFailed;
m_evIN[0] = m_evEXIT;
m_evOUT[0] = m_evEXIT;
// Create wait for space event
m_evIN[1] = ::CreateEvent(NULL, TRUE, TRUE, NULL);
if( m_evIN[1]==NULL )
goto SetSizeFailed;
// Create wait for item event
m_evOUT[1] = ::CreateEvent(NULL, TRUE, TRUE, NULL);
if( m_evOUT[1]==NULL )
goto SetSizeFailed;
// Initilize the three pointer
m_pIn = m_pOut = m_pWatch = 0;
started = true;
return true;
SetSizeFailed:
Clear();
return false;
}
template<class Type>
AFX_INLINE void ACircularBuf<Type>::StopBuffer()
{
if( started==false )
return;
HANDLE ev[2];
::SetEvent(m_evEXIT);
ev[0] = m_evIN[1];
ev[1] = m_evOUT[1];
::WaitForMultipleObjects(2, ev, TRUE, INFINITE);
Clear();
started = false;
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::IsFull()
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_pIn==-1 ) return true;
if( m_pOut==(m_pIn+1)%m_size )
return true;
else
return false;
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::IsEmpty()
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_pOut==-1 ) return true;
if( m_pIn==m_pOut )
return true;
else
return false;
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::CheckIn(Type &data)
{
bool ToWait = false;
{
ALock lock(&m_CritSec);
if( IsFull() ) {
::ResetEvent(m_evIN[1]);
ToWait = true;
}
}
if( ToWait==true ) {
DWORD rets = ::WaitForMultipleObjects(2, m_evIN, FALSE, INFINITE);
if( rets==WAIT_OBJECT_0 ) {
// exit event is signalled
// signale wait for space event to resume the blocked StopBuffer function.
::SetEvent(m_evIN[1]);
return false;
}
}
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_Buffer==NULL )
return false;
m_Buffer[m_pIn] = data;
m_pIn = (m_pIn+1)%m_size;
SetEvent(m_evOUT[1]);
return true;
}
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::CheckOut(Type &data)
{
bool ToWait = false;
{
ALock lock(&m_CritSec);
if( IsEmpty() ) {
::ResetEvent(m_evOUT[1]);
ToWait = true;
}
}
if( ToWait==true ) {
DWORD rets = ::WaitForMultipleObjects(2, m_evOUT, FALSE, INFINITE);
if( rets==WAIT_OBJECT_0 ) {
// exit event is signalled
// signale wait for item event to resume the blocked StopBuffer function.
::SetEvent(m_evOUT[1]);
return false;
}
}
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_Buffer==NULL )
return false;
data = m_Buffer[m_pOut];
if( m_pOut==m_pWatch ) {
m_pOut = (m_pOut+1)%m_size;
m_pWatch = m_pOut;
} else {
m_pOut = (m_pOut+1)%m_size;
}
SetEvent(m_evIN[1]);
return true;
}
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::GetWatch(Type &data)
{
bool ToWait = false;
{
ALock lock(&m_CritSec);
if( m_pWatch==m_pIn ) {
::ResetEvent(m_evOUT[1]);
ToWait = true;
}
}
if( ToWait==true ) {
DWORD rets = ::WaitForMultipleObjects(2, m_evOUT, FALSE, INFINITE);
if( rets==WAIT_OBJECT_0 ) {
// exit event is signalled
// signale wait for item event to resume the blocked StopBuffer function.
::SetEvent(m_evOUT[1]);
return false;
}
}
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_Buffer==NULL )
return false;
data = m_Buffer[m_pWatch];
m_pWatch = (m_pWatch+1)%m_size;
}
return true;
}
template<class Type>
AFX_INLINE void ACircularBuf<Type>::AlignIn()
{
ALock lock(&m_CritSec);
if( m_pOut==m_pWatch )
return;
m_pOut = m_pWatch;
SetEvent(m_evIN[1]);
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::ProceedWatch(int steps)
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_pWatch==-1 ) return false;
int newp = (m_pWatch + steps)%m_size;
if( betweenInOut(newp) ) {
m_pWatch = newp;
return true;
} else {
return false;
}
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::StepbackWatch(int steps)
{
ALock lock(&m_CritSec);
// DON'T delete this line
// This line is inteded to prevend the problem
// when we stop the consumer and producer of this buffer
if( m_pWatch==-1)
return false;
int newp = (m_pWatch - steps)%m_size;
if( betweenInOut(newp) ) {
m_pWatch = newp;
return true;
} else {
return false;
}
}
template<class Type>
AFX_INLINE void ACircularBuf<Type>::AlignWatch()
{
ALock lock(&m_CritSec);
m_pWatch = m_pOut;
}
template<class Type>
AFX_INLINE bool ACircularBuf<Type>::betweenInOut(int pwatch)
{
ALock lock(&m_CritSec);
// empty
if( m_pIn==m_pOut )
return false;
if( m_pOut>m_pIn) {
if( pwatch>=m_pIn && pwatch<m_pOut)
return false;
else
return true;
} else {
if( pwatch>=m_pOut && pwatch<m_pIn)
return true;
else
return false;
}
}
//template class ACircularBuf<int>;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -