Home | History | Annotate | Download | only in core
      1 /****************************************************************************
      2 * Copyright (C) 2016 Intel Corporation.   All Rights Reserved.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice (including the next
     12 * paragraph) shall be included in all copies or substantial portions of the
     13 * Software.
     14 *
     15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     21 * IN THE SOFTWARE.
     22 *
     23 * @file arena.h
     24 *
     25 * @brief RingBuffer
     26 *        The RingBuffer class manages all aspects of the ring buffer including
     27 *        the head/tail indices, etc.
     28 *
     29 ******************************************************************************/
     30 #pragma once
     31 
     32 template<typename T>
     33 class RingBuffer
     34 {
     35 public:
     36     RingBuffer()
     37         : mpRingBuffer(nullptr), mNumEntries(0), mRingHead(0), mRingTail(0)
     38     {
     39     }
     40 
     41     ~RingBuffer()
     42     {
     43         Destroy();
     44     }
     45 
     46     void Init(uint32_t numEntries)
     47     {
     48         SWR_ASSERT(numEntries > 0);
     49         SWR_ASSERT(((1ULL << 32) % numEntries) == 0, "%d is not evenly divisible into 2 ^ 32.  Wrap errors will occur!", numEntries);
     50         mNumEntries = numEntries;
     51         mpRingBuffer = (T*)AlignedMalloc(sizeof(T)*numEntries, 64);
     52         SWR_ASSERT(mpRingBuffer != nullptr);
     53         memset(mpRingBuffer, 0, sizeof(T)*numEntries);
     54     }
     55 
     56     void Destroy()
     57     {
     58         AlignedFree(mpRingBuffer);
     59         mpRingBuffer = nullptr;
     60     }
     61 
     62     T& operator[](const uint32_t index)
     63     {
     64         SWR_ASSERT(index < mNumEntries);
     65         return mpRingBuffer[index];
     66     }
     67 
     68     INLINE void Enqueue()
     69     {
     70         mRingHead++; // There's only one producer.
     71         // Assert to find wrap-around cases, NEVER ENABLE DURING CHECKIN!!
     72         // SWR_REL_ASSERT(mRingHead);
     73     }
     74 
     75     INLINE void Dequeue()
     76     {
     77         InterlockedIncrement(&mRingTail); // There are multiple consumers.
     78     }
     79 
     80     INLINE bool IsEmpty()
     81     {
     82         return (GetHead() == GetTail());
     83     }
     84 
     85     INLINE bool IsFull()
     86     {
     87         uint32_t numEnqueued = GetHead() - GetTail();
     88         SWR_ASSERT(numEnqueued <= mNumEntries);
     89 
     90         return (numEnqueued == mNumEntries);
     91     }
     92 
     93     INLINE uint32_t GetTail() volatile { return mRingTail; }
     94     INLINE uint32_t GetHead() volatile { return mRingHead; }
     95 
     96 protected:
     97     T* mpRingBuffer;
     98     uint32_t mNumEntries;
     99 
    100     OSALIGNLINE(volatile uint32_t) mRingHead;  // Consumer Counter
    101     OSALIGNLINE(volatile uint32_t) mRingTail;  // Producer Counter
    102 };
    103