CPN
Computational Process Networks
ThresholdQueueBase.h
Go to the documentation of this file.
1 //=============================================================================
2 // $Id: ThresholdQueueBase.h,v 1.1 2006/06/12 20:30:13 gallen Exp $
3 //-----------------------------------------------------------------------------
4 // A queue class that is optimized for DSP applications.
5 // Specifically, reading and writing is done directly from queue memory,
6 // and data is guaranteed to be contiguous in memory.
7 //-----------------------------------------------------------------------------
8 // The following _must_ hold: 1 <= qMaxThreshold < qLength
9 //=============================================================================
10 
11 
12 #ifndef ThresholdQueueBase_h
13 #define ThresholdQueueBase_h
14 #pragma once
15 #include "common_priv.h"
16 
17 //-----------------------------------------------------------------------------
18 // Implementation notes:
19 //
20 // +-------------------------+--------------+------
21 // | queueLength | mirrorLength | ...
22 // +-------------------------+--------------+------
23 //
24 // This works like a normal queue, but is intended to make up for the lack
25 // of circular address buffers on a general purpose processor.
26 // Where supported, MirrorBufferSet will be used, providing the mirroring in
27 // hardware with the virtual memory manager.
28 // Without MirrorBufferSet, there is a memory vs. performance tradeoff.
29 // When queueLength>>mirrorLength, data copying is seldom necessary.
30 // When queueLength==mirrorLength, copying must happen very frequently.
31 //-----------------------------------------------------------------------------
32 // This class follows the Computational Process Network calling conventions:
33 // - GetDequeuePtr(<thresh>) returns a pointer to <thresh> contiguous elements
34 // which are the next elements to be dequeued. That is, <thresh> elements
35 // must be in the queue before the consumer can fire. This threshold is
36 // equivalent to the [CG] parameter 'T'.
37 // - Dequeue(<count>) releases <count> elements from the queue. This <count>
38 // is equivalent to the [CG] parameter 'W'. Clearly, T >= W.
39 // - GetEnqueuePtr(<thresh>) returns a pointer to space in the queue for
40 // <thresh> contiguous elements, which are the next elements to be
41 // enqueued. That is, space for <thresh> elements must be in the queue
42 // before the producer can fire. (There is no equivalent in [CG].)
43 // - Enqueue(<count>) inserts <count> elements into the queue. This <count>
44 // is equivalent to the [CG] parameter 'U'. Clearly, enqueueThresh >= U.
45 //-----------------------------------------------------------------------------
46 // [CG] is Karp and Miller's Computation Graphs
47 //-----------------------------------------------------------------------------
48 // queueLength - The max number of elements in the queue
49 // dequeueThresh - The number of elements guaranteed contiguous beyond
50 // a pointer returned by GetDequeuePtr()
51 // enqueueThresh - The number of elements which may be written contiguously
52 // beyond a pointer returned by GetEnqueuePtr()
53 // maxThreshold - The max allowable value for dequeueThresh or
54 // enqueueThresh. Also, mirrorLength = maxThreshold-1
55 //-----------------------------------------------------------------------------
56 // To dequeue data:
57 // int count = <dequeueChunkSize>;
58 // T* ptr = theQueue.GetDequeuePtr(count);
59 // if (ptr) {
60 // for (int i=0; i<count; i++)
61 // <outgoingData> = ptr[i];
62 // Dequeue(count);
63 // }
64 // To enqueue data:
65 // int count = <enqueueChunkSize>;
66 // T* ptr = theQueue.GetEnqueuePtr(count);
67 // if (ptr) {
68 // for (int i=0; i<count; i++)
69 // ptr[i] = <incomingData>;
70 // Enqueue(count);
71 // }
72 //-----------------------------------------------------------------------------
73 // Other constructor parameters:
74 // useMBS - use MirrorBufferSet to get mirroring with virtual memory
75 // chanOffset - additional channel-to-channel offset to reduce cache thrashing
76 // baseOffset - additional base offset to reduce cache thrashing
77 // These offsets are in bytes, and do not apply unless useVMM=1
78 // These are performance tuning parameters. They should be a multiple of
79 // the number of bytes in a cache line, and a multiple of sizeof(T)
80 //-----------------------------------------------------------------------------
81 
82 #include "ThresholdQueueAttr.h"
83 
84 class MirrorBufferSet;
85 
87  // C++ templates are compile-time static, so we must be able to
88  // do everything in ThresholdQueueBase
89  public:
90  typedef unsigned long ulong;
91 
92  ThresholdQueueBase(ulong elemSize, ulong queueLen, ulong maxThresh, ulong numChans=1);
93  ThresholdQueueBase(ulong elemSize, const ThresholdQueueAttr& attr);
94  ~ThresholdQueueBase(void);
95 
96  void Reset(void);
97 
98  void* GetRawEnqueuePtr(ulong enqueueThresh, ulong chan=0) const;
99  void Enqueue(ulong count); // insert count after writing to enqueue ptr
100 
101  const void* GetRawDequeuePtr(ulong dequeueThresh, ulong chan=0) const;
102  void Dequeue(ulong count); // release count after reading from dequeue ptr
103 
104  ulong Count(void) const; // elements in the queue
105  ulong Freespace(void) const; // elements the queue can still hold
106 
107  bool Empty(void) const { return !Count(); }
108  bool Full(void) const { return !Freespace(); }
109 
110  ulong QueueLength(void) const { return queueLength; }
111  ulong MaxThreshold(void) const { return maxThreshold; }
112 
113  ulong NumChannels(void) const { return numChannels; }
114  ulong ChannelStride(void) const { return channelStride; }
115 
116  // just for fun
117  ulong ElementsEnqueued(void) const { return elementsEnqueued; }
118  ulong ElementsDequeued(void) const { return elementsDequeued; }
119 
120  void Grow(ulong queueLen, ulong maxThresh);
121 
122  protected:
123  ulong elementSize; // size of a single element
124  ulong head, tail; // dequeue & enqueue index
129  void* base;
131 
132  void AllocateBuf(ulong queueLen, ulong maxThresh, ulong numChans, bool useMBS);
133 };
134 
135 
136 #endif
void Dequeue(ulong count)
ulong MaxThreshold(void) const
ulong Count(void) const
const void * GetRawDequeuePtr(ulong dequeueThresh, ulong chan=0) const
ulong NumChannels(void) const
void AllocateBuf(ulong queueLen, ulong maxThresh, ulong numChans, bool useMBS)
ulong QueueLength(void) const
ulong ElementsDequeued(void) const
ulong Freespace(void) const
ulong ChannelStride(void) const
void Enqueue(ulong count)
void Grow(ulong queueLen, ulong maxThresh)
ulong ElementsEnqueued(void) const
bool Full(void) const
bool Empty(void) const
void * GetRawEnqueuePtr(ulong enqueueThresh, ulong chan=0) const
MirrorBufferSet * mbs
ThresholdQueueBase(ulong elemSize, ulong queueLen, ulong maxThresh, ulong numChans=1)