/******************************************************************************* * Copyright (C) ST-Ericsson SA 2011 * License terms: 3-clause BSD license ******************************************************************************/ #ifndef _LOCKLESSQUEUE_H_ #define _LOCKLESSQUEUE_H_ /// /// Class for store received data in Z-protocol in a lockless queue. /// class LockLessQueue { unsigned char *m_puchQueue; unsigned int m_uiHead; unsigned int m_uiTail; unsigned int m_uiSize; unsigned int m_uiMask; public: /// /// Constructor. /// /// Size of buffer = 2^uiSize. LockLessQueue(unsigned int uiSize): m_uiHead(0), m_uiTail(0) { m_uiSize = 1 << uiSize; m_uiMask = m_uiSize - 1; m_puchQueue = new unsigned char[m_uiSize]; } /// /// Constructor. Default buffer size to 2^20. /// LockLessQueue(): m_uiHead(0), m_uiTail(0) { m_uiSize = 1 << 20; m_uiMask = m_uiSize - 1; m_puchQueue = new unsigned char[m_uiSize]; } /// /// Destructor. /// ~LockLessQueue() { if (m_puchQueue != 0) { delete [] m_puchQueue; } } /// /// Store one byte in buffer queue. /// /// Data to store in buffer. /// Status of buffer, true = full buffer. void Push(unsigned char uchData, bool *pbFull) { unsigned int uiHead = m_uiHead; uiHead = uiHead & m_uiMask; //(Head++) & m_uiMask -> This does the required roll over to zero at the end of the array. uiHead++; if (uiHead == m_uiTail) { *pbFull = true; } else { m_puchQueue[uiHead] = uchData; m_uiHead = uiHead; *pbFull = false; } } /// /// Take out one byte from buffer queue. /// /// Status of buffer. pbEmpty = true -> buffer is empty. /// One byte data from buffer queue. unsigned char Pop(bool *pbEmpty) { unsigned char uchPopData = 0; unsigned int uiTail = m_uiTail; if (m_uiHead != uiTail) { uiTail = (uiTail + 1) & m_uiMask; //This does the required roll over to zero at the end of the array. m_uiTail = uiTail; uchPopData = m_puchQueue[uiTail]; *pbEmpty = false; } else { *pbEmpty = true; } return uchPopData; } /// /// Reset buffer queue. /// void Clear() { m_uiTail = m_uiHead; } }; #endif // _LOCKLESSQUEUE_H_