F´ Flight Software - C/C++ Documentation  NASA-v1.5.0
A framework for building embedded system applications to NASA flight quality standards.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BufferManager.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title BufferManager.hpp
3 // \author bocchino
4 // \brief BufferManager component interface
5 //
6 // \copyright
7 // Copyright (C) 2015-2017, by the California Institute of Technology.
8 // ALL RIGHTS RESERVED. United States Government Sponsorship
9 // acknowledged.
10 //
11 // ======================================================================
12 
13 #include "Fw/Types/Assert.hpp"
14 #include "Fw/Types/BasicTypes.hpp"
16 
17 namespace Svc {
18 
19  // ----------------------------------------------------------------------
20  // Warnings::State
21  // ----------------------------------------------------------------------
22 
23  BufferManager::Warnings::State ::
24  State(void) :
25  storeSizeExceeded(false),
26  tooManyBuffers(false)
27  {
28 
29  }
30 
31  // ----------------------------------------------------------------------
32  // Warnings
33  // ----------------------------------------------------------------------
34 
35  BufferManager::Warnings ::
36  Warnings(BufferManager& bufferManager) :
37  bufferManager(bufferManager)
38  {
39 
40  }
41 
42  void BufferManager::Warnings ::
43  update(const Status::t status)
44  {
45  switch (status) {
46  case Status::SUCCESS:
47  if (this->state.storeSizeExceeded || this->state.tooManyBuffers) {
48  this->bufferManager.log_ACTIVITY_HI_ClearedErrorState();
49  }
50  this->state.storeSizeExceeded = false;
51  this->state.tooManyBuffers = false;
52  break;
53  case Status::STORE_SIZE_EXCEEDED:
54  if (!this->state.storeSizeExceeded) {
55  this->bufferManager.log_WARNING_HI_StoreSizeExceeded();
56  this->state.storeSizeExceeded = true;
57  }
58  break;
59  case Status::TOO_MANY_BUFFERS:
60  if (!this->state.tooManyBuffers) {
61  this->bufferManager.log_WARNING_HI_TooManyBuffers();
62  this->state.tooManyBuffers = true;
63  }
64  break;
65  default:
66  FW_ASSERT(0);
67  break;
68  }
69  }
70 
71  // ----------------------------------------------------------------------
72  // The store
73  // ----------------------------------------------------------------------
74 
75  BufferManager::Store ::
76  Store(const U32 size) :
77  totalSize(size),
78  memoryBase(new U8[size]),
79  freeIndex(0),
80  padSize(0),
81  allocatedSize(0)
82  {
83 
84  }
85 
86  BufferManager::Store ::
87  ~Store(void)
88  {
89  delete[] this->memoryBase;
90  }
91 
92  U32 BufferManager::Store ::
93  getAllocatedSize(void) const
94  {
95  return this->freeIndex;
96  }
97 
98  BufferManager::Store::Status BufferManager::Store ::
99  allocate(
100  const U32 s,
101  U8* &result
102  )
103  {
104  Status status = SUCCESS;
105  U32 newPadSize = 0;
106  FW_ASSERT(this->allocatedSize <= this->totalSize);
107  FW_ASSERT(this->freeIndex <= this->totalSize);
108  if (this->freeIndex + s > this->totalSize) {
109  // Pad size for wraparound allocation
110  newPadSize = this->totalSize - this->freeIndex;
111  }
112  if (this->allocatedSize + s + newPadSize > this->totalSize) {
113  // Allocation too large
114  status = FAILURE;
115  result = 0;
116  }
117  else {
118  if (this->freeIndex + s > this->totalSize) {
119  // Wraparound allocation
120  FW_ASSERT(this->padSize == 0, this->padSize);
121  this->padSize = newPadSize;
122  this->allocatedSize += newPadSize;
123  this->freeIndex = 0;
124  }
125  result = &this->memoryBase[this->freeIndex];
126  this->allocatedSize += s;
127  this->freeIndex += s;
128  FW_ASSERT(this->allocatedSize <= this->totalSize);
129  FW_ASSERT(this->freeIndex <= this->totalSize);
130  }
131  return status;
132  }
133 
134  void BufferManager::Store ::
135  free(
136  const U32 size,
137  U8 *const address
138  )
139  {
140  FW_ASSERT(this->allocatedSize >= size, this->allocatedSize, size);
141  this->allocatedSize -= size;
142  if (address == this->memoryBase) {
143  // Wraparound allocation
144  FW_ASSERT(this->allocatedSize >= padSize, this->allocatedSize, padSize);
145  this->allocatedSize -= this->padSize;
146  this->padSize = 0;
147  }
148  }
149 
150  // ----------------------------------------------------------------------
151  // The allocation queue
152  // ----------------------------------------------------------------------
153 
154  BufferManager::AllocationQueue ::
155  AllocationQueue(const U32 size) :
156  totalSize(size),
157  data(new Entry[size]),
158  nextId(0),
159  allocateIndex(0),
160  freeIndex(0),
161  allocationSize(0)
162  {
163 
164  }
165 
166  BufferManager::AllocationQueue ::
167  ~AllocationQueue(void)
168  {
169  delete[] this->data;
170  }
171 
172  U32 BufferManager::AllocationQueue ::
173  getNextId(void)
174  {
175  const U32 id = this->nextId;
176  ++this->nextId;
177  FW_ASSERT(this->nextId != 0);
178  return id;
179  }
180 
181  U32 BufferManager::AllocationQueue ::
182  getNextIndex(const U32 index)
183  {
184  FW_ASSERT(index < this->totalSize);
185  const U32 result = index + 1;
186  return result == this->totalSize ? 0 : result;
187  }
188 
189  U32 BufferManager::AllocationQueue ::
190  getAllocationSize(void) const
191  {
192  return this->allocationSize;
193  }
194 
196  BufferManager::AllocationQueue ::
197  allocate(
198  const U32 size,
199  U32& id
200  )
201  {
202  FW_ASSERT(this->allocationSize <= this->totalSize);
203  if (this->allocationSize == this->totalSize) {
204  id = 0;
205  return Allocate::FULL;
206  }
207  FW_ASSERT(this->allocateIndex < this->totalSize);
208  Entry& e = this->data[allocateIndex];
209  id = this->getNextId();
210  e.id = id;
211  e.size = size;
212  this->allocateIndex = this->getNextIndex(this->allocateIndex);
213  ++this->allocationSize;
214  return Allocate::SUCCESS;
215  }
216 
218  BufferManager::AllocationQueue ::
219  free(
220  const U32 expectedId,
221  U32& sawId,
222  U32& size
223  )
224  {
225  sawId = 0;
226  size = 0;
227  if (this->allocationSize == 0) {
228  FW_ASSERT(this->freeIndex == this->allocateIndex);
229  return Free::EMPTY;
230  }
231  FW_ASSERT(this->freeIndex < this->totalSize);
232  Entry& e = this->data[this->freeIndex];
233  sawId = e.id;
234  size = e.size;
235  if (expectedId != sawId) {
236  return Free::ID_MISMATCH;
237  }
238  this->freeIndex = this->getNextIndex(this->freeIndex);
239  --this->allocationSize;
240  return Free::SUCCESS;
241  }
242 
243  // ----------------------------------------------------------------------
244  // Construction, initialization, and destruction
245  // ----------------------------------------------------------------------
246 
249  const char *const compName,
250  const U32 storeSize,
251  const U32 maxNumBuffers
252  ) :
253  BufferManagerComponentBase(compName),
254  warnings(*this),
255  store(storeSize),
256  allocationQueue(maxNumBuffers)
257  {
258 
259  }
260 
262  init(const NATIVE_INT_TYPE instance)
263  {
265  }
266 
268  ~BufferManager(void)
269  {
270 
271  }
272 
273  // ----------------------------------------------------------------------
274  // Handler implementations for user-defined typed input ports
275  // ----------------------------------------------------------------------
276 
279  NATIVE_INT_TYPE portNum,
280  U32 size
281  )
282  {
283  U8 *address;
284  U32 id;
285  Fw::Buffer buffer;
286  buffer.set(this->getInstance(), 0, 0, size);
287 
288  Warnings::Status::t warningStatus = Warnings::Status::SUCCESS;
289 
290  {
291  const Store::Status status =
292  this->store.allocate(size, address);
293  if (status == BufferManager::Store::FAILURE) {
294  warningStatus = Warnings::Status::STORE_SIZE_EXCEEDED;
295  }
296  }
297 
298  if (warningStatus == Warnings::Status::SUCCESS) {
299  const AllocationQueue::Allocate::Status status =
300  this->allocationQueue.allocate(size, id);
301  if (status == AllocationQueue::Allocate::FULL) {
302  this->store.free(size, address);
303  warningStatus = Warnings::Status::TOO_MANY_BUFFERS;
304  }
305  }
306 
307  if (warningStatus == Warnings::Status::SUCCESS) {
308  buffer.setbufferID(id);
309  buffer.setdata(reinterpret_cast<U64>(address));
310  }
311 
312  this->warnings.update(warningStatus);
313  return buffer;
314  }
315 
318  const NATIVE_INT_TYPE portNum,
319  Fw::Buffer &buffer
320  )
321  {
322 
323  const U32 instance = static_cast<U32>(this->getInstance());
324  FW_ASSERT(buffer.getmanagerID() == instance);
325 
326  const U32 expectedId = buffer.getbufferID();
327  U8 *const address = reinterpret_cast<U8*>(buffer.getdata());
328  U32 sawId = 0;
329  U32 size = 0;
330 
331  {
332  const AllocationQueue::Free::Status status =
333  this->allocationQueue.free(expectedId, sawId, size);
334  FW_ASSERT(
335  status == AllocationQueue::Free::SUCCESS,
336  status, expectedId, sawId, size
337  );
338  }
339 
340  {
341  this->store.free(size, address);
342  }
343 
344  }
345 
346 }
Svc::BufferManager::BufferManager
BufferManager(const char *const compName, const U32 storeSize, const U32 maxNumBuffers)
Definition: BufferManager.cpp:248
Svc::BufferManagerComponentBase::bufferGetCallee_handler
virtual Fw::Buffer bufferGetCallee_handler(NATIVE_INT_TYPE portNum, U32 size)=0
Handler for input port bufferGetCallee.
Os::FileSystem::Status
Status
Definition: FileSystem.hpp:15
Fw::Buffer::setdata
void setdata(U64 val)
set member data
Definition: BufferSerializableAc.cpp:71
Fw::PassiveComponentBase::getInstance
NATIVE_INT_TYPE getInstance(void) const
Definition: PassiveComponentBase.cpp:29
U8
uint8_t U8
8-bit unsigned integer
Definition: BasicTypes.hpp:76
Svc::BufferManagerComponentBase
Auto-generated base for BufferManager component.
Definition: BufferManagerComponentAc.hpp:44
Svc::BufferManager::bufferSendIn_handler
void bufferSendIn_handler(const NATIVE_INT_TYPE portNum, Fw::Buffer &buffer)
Definition: BufferManager.cpp:317
Fw::Buffer
Definition: BufferSerializableAc.hpp:24
Fw::Buffer::set
void set(U32 managerID, U32 bufferID, U64 data, U32 size)
set values
Definition: BufferSerializableAc.cpp:42
Assert.hpp
U64
#define U64(C)
Definition: sha.h:176
Fw::Buffer::getdata
U64 getdata(void)
get member data
Definition: BufferSerializableAc.cpp:57
Svc::BufferManager::store
Store store
The store.
Definition: BufferManager.hpp:339
Svc::BufferManager::~BufferManager
~BufferManager(void)
Definition: BufferManager.cpp:268
Fw::ObjBase::init
void init(void)
Object initializer.
Definition: ObjBase.cpp:26
FW_ASSERT
#define FW_ASSERT(...)
Definition: Assert.hpp:9
BufferManager.hpp
Fw::Buffer::setbufferID
void setbufferID(U32 val)
set member bufferID
Definition: BufferSerializableAc.cpp:68
Svc::BufferManager::allocationQueue
AllocationQueue allocationQueue
The allocation queue.
Definition: BufferManager.hpp:342
Svc::BufferManager::size
PRIVATE U32 size
Definition: BufferManager.hpp:320
Svc
Definition: ActiveLoggerComponentAc.cpp:22
Fw::Buffer::getmanagerID
U32 getmanagerID(void)
get member managerID
Definition: BufferSerializableAc.cpp:49
BasicTypes.hpp
Declares ISF basic types.
NATIVE_INT_TYPE
int NATIVE_INT_TYPE
native integer type declaration
Definition: BasicTypes.hpp:29
Fw::Buffer::getbufferID
U32 getbufferID(void)
get member bufferID
Definition: BufferSerializableAc.cpp:53