F´ Flight Software - C/C++ Documentation  NASA-v2.0.1
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BufferManagerComponentImpl.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title BufferManagerComponentImpl.cpp
3 // \author tcanham
4 // \brief cpp file for BufferManager component implementation class
5 //
6 // \copyright
7 // Copyright 2009-2015, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 
15 #include <Fw/Types/BasicTypes.hpp>
16 #include <Fw/Types/Assert.hpp>
17 #include <Fw/Buffer/Buffer.hpp>
18 #include <new>
19 
20 namespace Svc {
21 
22  // ----------------------------------------------------------------------
23  // Construction, initialization, and destruction
24  // ----------------------------------------------------------------------
25 
28  const char *const compName
29  ) : BufferManagerComponentBase(compName)
30  ,m_setup(false)
31  ,m_cleaned(false)
32  ,m_mgrId(0)
33  ,m_buffers(0)
34  ,m_allocator(0)
35  ,m_memId(0)
36  ,m_numStructs(0)
37  ,m_highWater(0)
38  ,m_currBuffs(0)
39  ,m_noBuffs(0)
40  ,m_emptyBuffs(0)
41  {
42 
43  }
44 
47  const NATIVE_INT_TYPE instance
48  )
49  {
50  BufferManagerComponentBase::init(instance);
51  }
52 
55  {
56  this->cleanup();
57  }
58 
60  cleanup(void)
61  {
62  FW_ASSERT(this->m_buffers);
63  FW_ASSERT(this->m_allocator);
64 
65  if (not this->m_cleaned) {
66  // walk through Fw::Buffer instances and delete them
67  for (NATIVE_UINT_TYPE entry = 0; entry < this->m_numStructs; entry++) {
68  this->m_buffers[entry].buff.~Buffer();
69  }
70  this->m_cleaned = true;
71  // release memory
72  this->m_allocator->deallocate(this->m_memId,this->m_buffers);
73  this->m_setup = false;
74  }
75  }
76 
77 
78  // ----------------------------------------------------------------------
79  // Handler implementations for user-defined typed input ports
80  // ----------------------------------------------------------------------
81 
82  void BufferManagerComponentImpl ::
83  bufferSendIn_handler(
84  const NATIVE_INT_TYPE portNum,
85  Fw::Buffer &fwBuffer
86  )
87  {
88  // make sure component has been set up
89  FW_ASSERT(this->m_setup);
90  FW_ASSERT(m_buffers);
91  // check for empty buffers - this is just a warning since this component returns
92  // empty buffers if it can't allocate one.
93  if (fwBuffer.getSize() == 0) {
94  this->log_WARNING_HI_ZeroSizeBuffer();
95  this->m_emptyBuffs++;
96  return;
97  }
98  // use the bufferID member field to find the original slot
99  U32 context = fwBuffer.getContext();
100  U32 id = context & 0xFFFF;
101  U32 mgrId = context >> 16;
102  // check some things
103  FW_ASSERT(id < this->m_numStructs,id,this->m_numStructs);
104  FW_ASSERT(mgrId == this->m_mgrId,mgrId,id,this->m_mgrId);
105  FW_ASSERT(true == this->m_buffers[id].allocated,id,this->m_mgrId);
106  FW_ASSERT(reinterpret_cast<U8*>(fwBuffer.getData()) >= this->m_buffers[id].memory,id,this->m_mgrId);
107  FW_ASSERT(reinterpret_cast<U8*>(fwBuffer.getData()) < (this->m_buffers[id].memory + this->m_buffers[id].size),id,this->m_mgrId);
108  // user can make smaller for their own purposes, but it shouldn't be bigger
109  FW_ASSERT(fwBuffer.getSize() <= this->m_buffers[id].size,id,this->m_mgrId);
110  // clear the allocated flag
111  this->m_buffers[id].allocated = false;
112  this->m_currBuffs--;
113  }
114 
115  Fw::Buffer BufferManagerComponentImpl ::
116  bufferGetCallee_handler(
117  const NATIVE_INT_TYPE portNum,
118  U32 size
119  )
120  {
121  // make sure component has been set up
122  FW_ASSERT(this->m_setup);
123  FW_ASSERT(m_buffers);
124  // find smallest buffer based on size.
125  for (NATIVE_UINT_TYPE buff = 0; buff < this->m_numStructs; buff++) {
126  if ((not this->m_buffers[buff].allocated) and (size < this->m_buffers[buff].size)) {
127  this->m_buffers[buff].allocated = true;
128  this->m_currBuffs++;
129  if (this->m_currBuffs > this->m_highWater) {
130  this->m_highWater = this->m_currBuffs;
131  }
132  Fw::Buffer copy = this->m_buffers[buff].buff;
133  // change size to match request
134  copy.setSize(size);
135  return copy;
136  }
137  }
138 
139  // if no buffers found, return empty buffer
140  this->log_WARNING_HI_NoBuffsAvailable(size);
141  this->m_noBuffs++;
142  return Fw::Buffer();
143 
144  }
145 
147  NATIVE_UINT_TYPE mgrId,
148  NATIVE_UINT_TYPE memId,
149  Fw::MemAllocator& allocator,
150  const BufferBins& bins
151  ) {
152 
153  this->m_mgrId = mgrId;
154  this->m_memId = memId;
155  this->m_allocator = &allocator;
156  // clear bins
157  memset(&this->m_bufferBins,0,sizeof(this->m_bufferBins));
158 
159  this->m_bufferBins = bins;
160 
161  // compute the amount of memory needed
162  NATIVE_UINT_TYPE memorySize = 0; // track needed memory
163  this->m_numStructs = 0; // size the number of tracking structs
164  // walk through bins and add up the sizes
165  for (NATIVE_UINT_TYPE bin = 0; bin < BUFFERMGR_MAX_NUM_BINS; bin++) {
166  if (this->m_bufferBins.bins[bin].numBuffers) {
167  memorySize +=
168  (this->m_bufferBins.bins[bin].bufferSize * this->m_bufferBins.bins[bin].numBuffers) + // allocate each set of buffer memory
169  (static_cast<NATIVE_UINT_TYPE>(sizeof(AllocatedBuffer)) * this->m_bufferBins.bins[bin].numBuffers); // allocate the structs to track the buffers
170  this->m_numStructs += this->m_bufferBins.bins[bin].numBuffers;
171  }
172  }
173 
174  NATIVE_UINT_TYPE allocatedSize = memorySize;
175  bool recoverable = false;
176 
177  // allocate memory
178  void *memory = allocator.allocate(memId,allocatedSize,recoverable);
179  // make sure the memory returns was non-zero and the size requested
180  FW_ASSERT(memory);
181  FW_ASSERT(memorySize == allocatedSize,memorySize,allocatedSize);
182  // structs will be at beginning of memory
183  this->m_buffers = static_cast<AllocatedBuffer*>(memory);
184  // memory buffers will be at end of structs in memory, so compute that memory as the beginning of the
185  // struct past the number of structs
186  U8* bufferMem = reinterpret_cast<U8*>(&this->m_buffers[this->m_numStructs]);
187 
188  // walk through entries and initialize them
189  NATIVE_UINT_TYPE currStruct = 0;
190  for (NATIVE_UINT_TYPE bin = 0; bin < BUFFERMGR_MAX_NUM_BINS; bin++) {
191  if (this->m_bufferBins.bins[bin].numBuffers) {
192  for (NATIVE_UINT_TYPE binEntry = 0; binEntry < this->m_bufferBins.bins[bin].numBuffers; binEntry++) {
193  // placement new for Fw::Buffer instance. We don't need the new() return value,
194  // because we know where the Fw::Buffer instance is
195  U32 context = (this->m_mgrId << 16) | currStruct;
196  (void) new(&this->m_buffers[currStruct].buff) Fw::Buffer(bufferMem,this->m_bufferBins.bins[bin].bufferSize,context);
197  this->m_buffers[currStruct].allocated = false;
198  this->m_buffers[currStruct].memory = bufferMem;
199  this->m_buffers[currStruct].size = this->m_bufferBins.bins[bin].bufferSize;
200  bufferMem += this->m_bufferBins.bins[bin].bufferSize;
201  currStruct++;
202  }
203  }
204  }
205 
206  // check some assertions
207  FW_ASSERT(bufferMem == (static_cast<U8*>(memory) + memorySize));
208  FW_ASSERT(currStruct == this->m_numStructs,currStruct,this->m_numStructs);
209  // indicate setup is done
210  this->m_setup = true;
211  }
212 
213  void BufferManagerComponentImpl ::
214  schedIn_handler(
215  const NATIVE_INT_TYPE portNum,
216  NATIVE_UINT_TYPE context
217  )
218  {
219  // write telemetry values
220  this->tlmWrite_HiBuffs(this->m_highWater);
221  this->tlmWrite_CurrBuffs(this->m_currBuffs);
222  this->tlmWrite_TotalBuffs(this->m_numStructs);
223  this->tlmWrite_NoBuffs(this->m_noBuffs);
224  this->tlmWrite_EmptyBuffs(this->m_emptyBuffs);
225  }
226 
227 } // end namespace Svc
Svc::BufferManagerComponentImpl::setup
void setup(NATIVE_UINT_TYPE mgrID, NATIVE_UINT_TYPE memID, Fw::MemAllocator &allocator, const BufferBins &bins)
set up configuration
Definition: BufferManagerComponentImpl.cpp:146
Fw::Buffer::getData
U8 * getData() const
Definition: Buffer.cpp:56
Fw::MemAllocator::deallocate
virtual void deallocate(const NATIVE_UINT_TYPE identifier, void *ptr)=0
Deallocate memory.
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Svc::BufferManagerComponentImpl::BufferManagerComponentImpl
BufferManagerComponentImpl(const char *const compName)
Definition: BufferManagerComponentImpl.cpp:27
Buffer.hpp
Svc::BufferManagerComponentImpl::BufferBin::numBuffers
NATIVE_UINT_TYPE numBuffers
number of buffers in this bin. Set to zero for unused bins.
Definition: BufferManagerComponentImpl.hpp:81
Fw::Buffer::getContext
U32 getContext() const
Definition: Buffer.cpp:64
Fw::MemAllocator::allocate
virtual void * allocate(const NATIVE_UINT_TYPE identifier, NATIVE_UINT_TYPE &size, bool &recoverable)=0
Allocate memory.
Fw::Buffer
Definition: Buffer.hpp:43
Assert.hpp
Svc::BUFFERMGR_MAX_NUM_BINS
static const NATIVE_UINT_TYPE BUFFERMGR_MAX_NUM_BINS
Definition: BufferManagerComponentImplCfg.hpp:7
Svc::BufferManagerComponentImpl::BufferBins
Definition: BufferManagerComponentImpl.hpp:85
BufferManagerComponentImpl.hpp
Fw::Buffer::getSize
U32 getSize() const
Definition: Buffer.cpp:60
Svc::BufferManagerComponentImpl::BufferBins::bins
BufferBin bins[BUFFERMGR_MAX_NUM_BINS]
set of bins to define buffers
Definition: BufferManagerComponentImpl.hpp:87
Fw::Buffer::setSize
void setSize(U32 size)
Definition: Buffer.cpp:75
NATIVE_UINT_TYPE
unsigned int NATIVE_UINT_TYPE
native unsigned integer type declaration
Definition: BasicTypes.hpp:30
Svc::BufferManagerComponentImpl::BufferBin::bufferSize
NATIVE_UINT_TYPE bufferSize
size of the buffers in this bin. Set to zero for unused bins.
Definition: BufferManagerComponentImpl.hpp:80
Svc::BufferManagerComponentImpl::cleanup
void cleanup(void)
Definition: BufferManagerComponentImpl.cpp:60
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
Svc::BufferManagerComponentImpl::init
void init(const NATIVE_INT_TYPE instance=0)
Definition: BufferManagerComponentImpl.cpp:46
Fw::MemAllocator
Definition: MemAllocator.hpp:44
Svc::BufferManagerComponentImpl::~BufferManagerComponentImpl
~BufferManagerComponentImpl(void)
Definition: BufferManagerComponentImpl.cpp:54
Svc
Definition: ActiveRateGroupImplCfg.hpp:18
BasicTypes.hpp
Declares ISF basic types.
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29