QXRD  0.11.16
qcepallocator.cpp
Go to the documentation of this file.
1 #include "qcepdebug.h"
2 #include "qcepallocator.h"
3 #include "qcepmutexlocker.h"
4 #include "qcepapplication.h"
5 #include <stdio.h>
6 #include "qcepimagedata.h"
7 #include "qcepmaskdata.h"
8 #include "qcepintegrateddata.h"
9 #include "qcepthread.h"
10 
11 static QcepAllocator *g_Allocator = NULL;
12 static quint64 g_AllocatedMemory = 0;
13 
16  : QcepObject("allocator", NULL),
17  m_Mutex(QMutex::Recursive),
19  m_Max(saver, this, "max", 800, "Maximum Image Memory (MB)"),
20  m_TotalBufferSizeMB32(saver, this,"totalBufferSizeMB32", 800, "Maximum Image Memory in 32 bit system (MB)"),
21  m_TotalBufferSizeMB64(saver, this,"totalBufferSizeMB64", 2000,"Maximum Image Memory in 64 bit system (MB)"),
22  m_Reserve(saver, this,"reserve",100, "Extra Reserved Memory (MB)"),
23  m_Allocated(QcepSettingsSaverPtr(), this, "allocated", 0, "Allocated Memory (MB)")
24 {
25  if (g_Allocator) {
26  printf("Only one allocator can be created\n");
27  } else {
28  g_Allocator = this;
29  }
30 
32  printf("QcepAllocator::QcepAllocator(%p)\n", this);
33  }
34 
36  g_Application->printMessage(tr("allocator %1 constructed").HEXARG(this));
37  };
38 
39  connect(&m_Timer, SIGNAL(timeout()), this, SLOT(allocatorHeartbeat()));
40 
41  m_Timer.start(100);
42 
44 }
45 
47 {
48 #ifndef QT_NO_DEBUG
49  printf("Deleting allocator\n");
50 #endif
51 
52  g_Allocator = NULL;
53 
55  printf("QcepAllocator::~QcepAllocator(%p)\n", this);
56  }
57 
59  g_Application->printMessage(tr("allocator %1 deleted").HEXARG(this));
60  };
61 }
62 
63 void QcepAllocator::writeSettings(QSettings *settings, QString section)
64 {
65  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
66 
67  QcepObject::writeSettings(settings, section);
68 }
69 
70 void QcepAllocator::readSettings(QSettings *settings, QString section)
71 {
72  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
73 
74  QcepObject::readSettings(settings, section);
75 
76  if (get_TotalBufferSizeMB32() > 100000000) {
77  set_TotalBufferSizeMB32(get_TotalBufferSizeMB32()/MegaBytes);
78  }
79 
80  if (get_TotalBufferSizeMB64() > 100000000) {
81  set_TotalBufferSizeMB64(get_TotalBufferSizeMB64()/MegaBytes);
82  }
83 }
84 
86 {
87  return &m_Mutex;
88 }
89 
91 {
92  if (strat == QcepAllocator::WaitTillAvailable) {
93  while((m_AllocatedMemoryMB.fetchAndAddOrdered(0) + sizeMB) > get_Max()) {
94  m_Mutex.unlock();
95 
97  if (g_Application) {
98  g_Application->printMessage("QcepAllocator::waitTillAvailable() sleeping 100msec");
99  }
100  }
101 
102  QcepThread::msleep(100);
103 
104  m_Mutex.lock();
105  }
106 
107  return true;
108  } else if (strat == QcepAllocator::NullIfNotAvailable) {
109  return ((m_AllocatedMemoryMB.fetchAndAddOrdered(0) + sizeMB) < get_Max());
110  } else if (strat == QcepAllocator::AllocateFromReserve) {
111  return ((m_AllocatedMemoryMB.fetchAndAddOrdered(0) + sizeMB) < (get_Max() + get_Reserve()));
112  } else if (strat == QcepAllocator::AlwaysAllocate) {
113  return true;
114  } else {
115  return false;
116  }
117 }
118 
120 {
121  if (g_Allocator) {
122  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
123 
124  if (g_Allocator->waitTillAvailable(strat, g_Allocator->int16SizeMB(width, height))) {
125  QcepInt16ImageDataPtr res(new QcepInt16ImageData(QcepSettingsSaverPtr(), width, height, 0, parent));
126 
127  res->moveToThread(NULL);
128 
130  g_Application->printMessage(tr("QcepAllocator::newInt16Image() succeeded [%1] [%2]").HEXARG(res.data()).arg(g_Allocator->allocatedMemoryMB()));
131  }
132 
133  return res;
134  }
135  }
136 
138  g_Application->printMessage("QcepAllocator::newInt16Image() returned NULL");
139  }
140 
141  return QcepInt16ImageDataPtr(NULL);
142 }
143 
145 {
146  if (g_Allocator) {
147  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
148 
149  if (g_Allocator->waitTillAvailable(strat, g_Allocator->int32SizeMB(width, height))) {
150  QcepInt32ImageDataPtr res(new QcepInt32ImageData(QcepSettingsSaverPtr(), width, height, 0, parent));
151 
152  res->moveToThread(NULL);
153 
155  g_Application->printMessage(tr("QcepAllocator::newInt32Image() succeeded [%1] [%2]").HEXARG(res.data()).arg(g_Allocator->allocatedMemoryMB()));
156  }
157 
158  return res;
159  }
160  }
161 
163  g_Application->printMessage("QcepAllocator::newInt32Image() returned NULL");
164  }
165 
166  return QcepInt32ImageDataPtr(NULL);
167 }
168 
170 {
171  if (g_Allocator) {
172  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
173 
174  if (g_Allocator->waitTillAvailable(strat, g_Allocator->doubleSizeMB(width, height))) {
175  QcepDoubleImageDataPtr res(new QcepDoubleImageData(QcepSettingsSaverPtr(), width, height, 0, parent));
176 
177  res -> moveToThread(NULL);
178 
180  g_Application->printMessage(tr("QcepAllocator::newDoubleImage() succeeded [%1] [%2]").HEXARG(res.data()).arg(g_Allocator->allocatedMemoryMB()));
181  }
182 
183  return res;
184  }
185  }
186 
188  g_Application->printMessage("QcepAllocator::newDoubleImage() returned NULL");
189  }
190 
191  return QcepDoubleImageDataPtr(NULL);
192 }
193 
194 QcepDoubleImageDataPtr QcepAllocator::newDoubleImage(QString name, int width, int height, QcepObject *parent)
195 {
197 
198  if (g_Application) {
199  img = newDoubleImage(QcepAllocator::NullIfNotAvailable, width, height, parent);
200 
201  if (img) {
202  img->set_Name(name);
203  img->moveToThread(NULL);
204  }
205  }
206 
207  return img;
208 }
209 
210 QcepMaskDataPtr QcepAllocator::newMask(AllocationStrategy strat, int width, int height, int def, QcepObject *parent)
211 {
212  if (g_Allocator) {
213  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
214 
215  if (g_Allocator->waitTillAvailable(strat, g_Allocator->maskSizeMB(width, height))) {
216  QcepMaskDataPtr res(new QcepMaskData(QcepSettingsSaverPtr(), width, height, def, parent));
217 
218  res->moveToThread(NULL);
219 
221  g_Application->printMessage(tr("QcepAllocator::newMask() succeeded [%1] [%2]").HEXARG(res.data()).arg(g_Allocator->allocatedMemoryMB()));
222  }
223 
224  return res;
225  }
226  }
227 
229  g_Application->printMessage("QcepAllocator::newMask() returned NULL");
230  }
231 
232  return QcepMaskDataPtr(NULL);
233 }
234 
236 {
237  if (g_Allocator) {
238  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
239 
240  if (g_Allocator->waitTillAvailable(strat, g_Allocator->integratedSizeMB(10000))) {
242  "",
243  data,
244  10000,
245  parent));
246 
247  res->moveToThread(NULL);
248 
250  g_Application->printMessage(tr("QcepAllocator::newIntegratedData() succeeded [%1] [%2]").HEXARG(res.data()).arg(g_Allocator->allocatedMemoryMB()));
251  }
252 
253  return res;
254  }
255  }
256 
258  g_Application->printMessage("QcepAllocator::newIntegratedData() returned NULL");
259  }
260 
261  return QcepIntegratedDataPtr(NULL);
262 }
263 
265 {
266  QcepIntegratedDataPtr integ;
267 
268  if (g_Application) {
270 
271  if (integ) {
272  integ->set_Name(name);
273  integ->moveToThread(NULL);
274  integ->resize(size);
275  }
276  }
277 
278  return integ;
279 }
280 
282  int height, QcepObject *parent,
284 {
285  if (g_Allocator) {
286  QcepMutexLocker lock(__FILE__, __LINE__, g_Allocator->mutex());
287 
288  if (g_Allocator->waitTillAvailable(strat, g_Allocator->doubleSizeMB(width, height) + g_Allocator->integratedSizeMB(10000))) {
289  img = QcepDoubleImageDataPtr(new QcepDoubleImageData(QcepSettingsSaverPtr(), width, height, 0, parent));
290  integ = QcepIntegratedDataPtr(new QcepIntegratedData(QcepSettingsSaverPtr(), "", img, 10000, parent));
291 
292  img->moveToThread(NULL);
293  integ->moveToThread(NULL);
294 
296  g_Application->printMessage(tr("QcepAllocator::newDoubleImageAndIntegratedData() succeeded [%1] [%2] [%3]")
297  .HEXARG(img.data()).HEXARG(integ.data()).arg(g_Allocator->allocatedMemoryMB()));
298  }
299  }
300  }
301 
303  g_Application->printMessage("QcepAllocator::newDoubleImageAndIntegratedData() returned NULL");
304  }
305 }
306 
307 /* static */
308 void QcepAllocator::allocate(int sz, int width, int height)
309 {
310  if (g_Allocator) {
311  g_Allocator -> allocate((quint64) sz*width*height);
312  }
313 }
314 
315 /* static */
316 void QcepAllocator::allocate(quint64 amt)
317 {
318  if (g_Allocator) {
319  g_Allocator -> allocateBytes(amt);
320  }
321 }
322 
324 {
325  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
326 
327  g_AllocatedMemory += amt;
328 
329  m_AllocatedMemoryMB.fetchAndStoreOrdered(g_AllocatedMemory/MegaBytes);
330 }
331 
332 /* static */
333 void QcepAllocator::deallocate(int sz, int width, int height)
334 {
335  if (g_Allocator) {
336  g_Allocator -> deallocate((quint64) sz*width*height);
337  }
338 }
339 
340 /* static */
341 void QcepAllocator::deallocate(quint64 amt)
342 {
343  if (g_Allocator) {
344  g_Allocator -> deallocateBytes(amt);
345  }
346 }
347 
349 {
350  QcepMutexLocker lock(__FILE__, __LINE__, &m_Mutex);
351 
352  g_AllocatedMemory -= amt;
353 
354  m_AllocatedMemoryMB.fetchAndStoreOrdered(g_AllocatedMemory/MegaBytes);
355 }
356 
357 int QcepAllocator::int16SizeMB(int width, int height)
358 {
359  return sizeof(quint16)*width*height/MegaBytes;
360 }
361 
362 int QcepAllocator::int32SizeMB(int width, int height)
363 {
364  return sizeof(quint32)*width*height/MegaBytes;
365 }
366 
367 int QcepAllocator::doubleSizeMB(int width, int height)
368 {
369  return sizeof(double)*width*height/MegaBytes;
370 }
371 
372 int QcepAllocator::maskSizeMB(int width, int height)
373 {
374  return sizeof(quint16)*width*height/MegaBytes;
375 }
376 
378 {
379  return (sizeof(double)*4*nrows)/MegaBytes;
380 }
381 
383 {
384  set_Allocated(m_AllocatedMemoryMB.fetchAndAddOrdered(0));
385 }
386 
388 {
389  return m_AllocatedMemoryMB.fetchAndAddOrdered(0);
390 }
391 
393 {
394  return g_AllocatedMemory;
395 }
396 
398 {
399  return get_Max();
400 }
401 
403 {
404  return get_Max()*MegaBytes;
405 }
406 
408 {
409  set_Max(newMB);
410 }
QcepImageData< double > QcepDoubleImageData
static void deallocate(int sz, int width, int height)
QcepImageData< quint16 > QcepInt16ImageData
static QcepIntegratedDataPtr newIntegratedData(AllocationStrategy strat, QcepDoubleImageDataPtr image, QcepObject *parent)
void readSettings(QSettings *settings, QString section)
qint64 qcepDebug(int cond)
Definition: qcepdebug.cpp:26
int int16SizeMB(int width, int height)
virtual void readSettings(QSettings *set, QString section)
Definition: qcepobject.cpp:119
double maximumMemory()
QcepAllocator(QcepSettingsSaverPtr saver)
void changedSizeMB(int newMB)
static void newDoubleImageAndIntegratedData(AllocationStrategy strat, int width, int height, QcepObject *parent, QcepDoubleImageDataPtr &img, QcepIntegratedDataPtr &integ)
QSharedPointer< QcepIntegratedData > QcepIntegratedDataPtr
static quint64 allocatedMemory()
static void msleep(long unsigned int)
Definition: qcepthread.cpp:10
int int32SizeMB(int width, int height)
void writeSettings(QSettings *settings, QString section)
static QcepDoubleImageDataPtr newDoubleImage(AllocationStrategy strat, int width, int height, QcepObject *parent)
QcepImageData< quint32 > QcepInt32ImageData
static QcepAllocator * g_Allocator
int doubleSizeMB(int width, int height)
int maskSizeMB(int width, int height)
double maximumMemoryMB()
QMutex * mutex()
double allocatedMemoryMB()
QSharedPointer< QcepSettingsSaver > QcepSettingsSaverPtr
QcepObject(QString name, QcepObject *parent)
Definition: qcepobject.cpp:16
virtual ~QcepAllocator()
#define HEXARG(a)
Definition: qcepdebug.h:50
int waitTillAvailable(AllocationStrategy strat, int sizeMB)
QAtomicInt m_AllocatedMemoryMB
Definition: qcepallocator.h:86
void allocatorHeartbeat()
static void allocate(int sz, int width, int height)
virtual void writeSettings(QSettings *set, QString section)
Definition: qcepobject.cpp:114
static QcepInt16ImageDataPtr newInt16Image(AllocationStrategy strat, int width, int height, QcepObject *parent)
virtual void printMessage(QString msg, QDateTime ts=QDateTime::currentDateTime())=0
QSharedPointer< QcepInt32ImageData > QcepInt32ImageDataPtr
QcepApplication * g_Application
int integratedSizeMB(int nrows)
QString name
Definition: qcepobject.h:49
static quint64 g_AllocatedMemory
static QcepMaskDataPtr newMask(AllocationStrategy strat, int width, int height, int def, QcepObject *parent)
void allocateBytes(quint64 amt)
QSharedPointer< QcepInt16ImageData > QcepInt16ImageDataPtr
QSharedPointer< QcepMaskData > QcepMaskDataPtr
static QcepInt32ImageDataPtr newInt32Image(AllocationStrategy strat, int width, int height, QcepObject *parent)
void deallocateBytes(quint64 amt)
QSharedPointer< QcepDoubleImageData > QcepDoubleImageDataPtr