jbuff.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef JBUFF_HPP
  14. #define JBUFF_HPP
  15. #include "jiface.hpp"
  16. #include "jmutex.hpp"
  17. #include "jmalloc.hpp"
  18. class StringAttr;
  19. class StringBuffer;
  20. class jlib_decl MemoryAttr
  21. {
  22. public:
  23. inline MemoryAttr() { len = 0; ptr = NULL; }
  24. MemoryAttr(size_t _len);
  25. MemoryAttr(size_t _len, const void * _ptr);
  26. MemoryAttr(const MemoryAttr & src);
  27. inline ~MemoryAttr() { free(ptr); }
  28. void * allocate(size_t _len);
  29. void clear();
  30. void * detach();
  31. void * ensure(size_t _len);
  32. void * reallocate(size_t _len);
  33. inline const void * get() const { return ptr; }
  34. inline size_t length() const { return len; }
  35. inline void * mem() const { return ptr; }
  36. void set(size_t _len, const void * _ptr);
  37. void setOwn(size_t _len, void * _ptr);
  38. static int compare(const MemoryAttr & m1, const MemoryAttr & m2);
  39. inline void * bufferBase() const { return ptr; } // like get except non-const
  40. private:
  41. void * ptr;
  42. size_t len;
  43. };
  44. //--------------------------------------------------------------------------------------------------------------------
  45. interface IMemoryBlock
  46. {
  47. public:
  48. virtual const byte * get() const = 0;
  49. virtual byte * getMem() const = 0;
  50. virtual byte * ensure(size32_t len) = 0;
  51. };
  52. class jlib_decl CMemoryBlock : public IMemoryBlock
  53. {
  54. public:
  55. virtual const byte * get() const
  56. {
  57. return reinterpret_cast<const byte *>(memory.get());
  58. }
  59. virtual byte * getMem() const
  60. {
  61. return reinterpret_cast<byte *>(memory.mem());
  62. }
  63. virtual byte * ensure(size32_t len)
  64. {
  65. return reinterpret_cast<byte *>(memory.ensure(len));
  66. }
  67. protected:
  68. MemoryAttr memory;
  69. };
  70. //--------------------------------------------------------------------------------------------------------------------
  71. template <class CLASS> class OwnedMalloc
  72. {
  73. public:
  74. inline OwnedMalloc() { ptr = NULL; }
  75. inline OwnedMalloc(CLASS * _ptr) { ptr = _ptr; }
  76. explicit inline OwnedMalloc(unsigned n, bool clearMemory = false) { doAllocate(n, clearMemory); }
  77. inline ~OwnedMalloc() { free(ptr); }
  78. inline CLASS * operator -> () const { return ptr; }
  79. inline operator CLASS *() const { return ptr; }
  80. inline void clear() { CLASS *temp=ptr; ptr=NULL; free(temp); }
  81. inline CLASS * get() const { return ptr; }
  82. inline CLASS * getClear() { CLASS * temp = ptr; ptr = NULL; return temp; }
  83. inline void setown(CLASS * _ptr) { CLASS * temp = ptr; ptr = _ptr; free(temp); }
  84. inline void allocate(bool clearMemory = false) { allocateN(1, clearMemory); }
  85. inline void allocateN(unsigned n, bool clearMemory = false)
  86. {
  87. clear();
  88. doAllocate(n, clearMemory);
  89. }
  90. private:
  91. inline OwnedMalloc(const OwnedMalloc<CLASS> & other);
  92. inline void doAllocate(unsigned n, bool clearMemory = false)
  93. {
  94. void * mem = clearMemory ? calloc(n, sizeof(CLASS)) : malloc(n * sizeof(CLASS));
  95. ptr = static_cast<CLASS *>(mem);
  96. }
  97. void allocate(unsigned n, bool clearMemory = false);
  98. void operator = (CLASS * _ptr);
  99. void operator = (const OwnedMalloc<CLASS> & other);
  100. void set(CLASS * _ptr);
  101. void set(const OwnedMalloc<CLASS> &other);
  102. void setown(const OwnedMalloc<CLASS> &other);
  103. private:
  104. CLASS * ptr;
  105. };
  106. #define MEMBUFFER_MAXLEN UINT_MAX // size32_t
  107. class jlib_decl MemoryBuffer
  108. {
  109. public:
  110. inline MemoryBuffer() { init(); }
  111. MemoryBuffer(size_t initial);
  112. MemoryBuffer(size_t len, const void * buffer);
  113. inline ~MemoryBuffer() { kill(); }
  114. MemoryBuffer & rewrite(size32_t pos = 0);
  115. MemoryBuffer & append(char value);
  116. MemoryBuffer & append(unsigned char value);
  117. MemoryBuffer & append(bool value);
  118. MemoryBuffer & append(const char * value);
  119. MemoryBuffer & append(const unsigned char * value);
  120. MemoryBuffer & append(size32_t len, const void * value);
  121. MemoryBuffer & append(double value);
  122. MemoryBuffer & append(float value);
  123. MemoryBuffer & append(short value);
  124. MemoryBuffer & append(unsigned short value);
  125. MemoryBuffer & append(int value);
  126. MemoryBuffer & append(unsigned value);
  127. MemoryBuffer & append(__int64 value);
  128. MemoryBuffer & append(unsigned __int64 value);
  129. MemoryBuffer & append(const MemoryBuffer & value);
  130. MemoryBuffer & appendBytes(unsigned char value, unsigned count);
  131. MemoryBuffer & appendEndian(size32_t len, const void * value);
  132. MemoryBuffer & appendFile(const char *fileName);
  133. MemoryBuffer & appendSwap(size32_t len, const void * value);
  134. MemoryBuffer & appendPacked(unsigned __int64 value); // compatible with any unsigned size
  135. inline MemoryBuffer & appendMemSize(memsize_t value) { __int64 val=(__int64)value; append(val); return *this; }
  136. MemoryBuffer & reset(size32_t pos = 0);
  137. MemoryBuffer & read(char & value);
  138. MemoryBuffer & read(unsigned char & value);
  139. MemoryBuffer & read(bool & value);
  140. MemoryBuffer & read(StringAttr & value);
  141. MemoryBuffer & read(StringBuffer & value);
  142. MemoryBuffer & read(const char * & value);
  143. MemoryBuffer & read(size32_t len, void * value);
  144. MemoryBuffer & read(double & value);
  145. MemoryBuffer & read(float & value);
  146. MemoryBuffer & read(short & value);
  147. MemoryBuffer & read(unsigned short & value);
  148. MemoryBuffer & read(int & value);
  149. MemoryBuffer & read(unsigned & value);
  150. MemoryBuffer & read(__int64 & value);
  151. MemoryBuffer & read(unsigned __int64 & value);
  152. MemoryBuffer & readEndian(size32_t len, void * value);
  153. MemoryBuffer & readFile(StringAttr &fileName);
  154. MemoryBuffer & readSwap(size32_t len, void * value);
  155. const byte * readDirect(size32_t len); // for efficiency
  156. MemoryBuffer & readPacked(unsigned & value);
  157. MemoryBuffer & readPacked(unsigned __int64 & value);
  158. inline MemoryBuffer & readMemSize(memsize_t & value) { __int64 val; read(val); value = (memsize_t)val; assertex(val == (__int64) value); return *this; }
  159. MemoryBuffer & skip(unsigned len);
  160. void writeDirect(size32_t pos,size32_t len,const void *buf); // NB does not extend buffer
  161. void writeEndianDirect(size32_t pos,size32_t len,const void *buf); // NB does not extend buffer
  162. inline size32_t getPos() { return readPos; }; // read ptr
  163. inline MemoryBuffer & clear() { curLen = 0; readPos = 0; return *this; }
  164. inline bool needSwapEndian() { return swapEndian; }
  165. int setEndian(int endian); // pass __[BIG|LITTLE]_ENDIAN
  166. bool setSwapEndian(bool swap);
  167. inline const char * toByteArray() const { return curLen ? buffer : NULL; }
  168. void swapWith(MemoryBuffer & other);
  169. inline size32_t capacity() { return (maxLen - curLen); }
  170. void * ensureCapacity (unsigned max);
  171. inline size32_t length() const { return curLen; }
  172. inline size32_t remaining() const { return curLen - readPos; }
  173. void resetBuffer();
  174. void setBuffer(size_t len, void * buffer, bool takeOwnership=false);
  175. void setLength(unsigned len);
  176. void setWritePos(unsigned len); // only use for back patching data
  177. void * detach();
  178. void * detachOwn(); // Never reallocates
  179. //Non-standard functions:
  180. void * reserve(unsigned size);
  181. void truncate(); // truncates (i.e. minimizes allocation) to current size
  182. void * reserveTruncate(unsigned size); // reserves and truncates to that size
  183. void * insertDirect(unsigned offset, size32_t len); // insert len bytes at offset returning address to area inserted
  184. inline void Release() const { delete this; } // for consistency even though not link counted
  185. inline void * bufferBase() const { return buffer; }
  186. protected:
  187. size32_t readPos;
  188. bool swapEndian;
  189. private:
  190. MemoryBuffer & read(unsigned long & value); // unimplemented
  191. MemoryBuffer & read(long & value); // unimplemented
  192. MemoryBuffer & append(long value); // unimplemented
  193. MemoryBuffer & append(unsigned long value); // unimplemented
  194. void _insert(unsigned offset, size32_t len);
  195. void init();
  196. void kill();
  197. unsigned __int64 readPacked();
  198. void _realloc(size32_t max);
  199. void _reallocExact(size32_t max);
  200. MemoryBuffer & _remove(unsigned start, unsigned len);
  201. MemoryBuffer & _reverse();
  202. const char* _str();
  203. mutable char * buffer;
  204. size32_t curLen;
  205. size32_t maxLen;
  206. bool ownBuffer;
  207. MemoryBuffer(MemoryBuffer & value);
  208. };
  209. // Utility class, to back patch a size into current position
  210. class jlib_decl DelayedSizeMarker
  211. {
  212. MemoryBuffer &mb;
  213. size32_t pos;
  214. public:
  215. DelayedSizeMarker(MemoryBuffer &_mb) : mb(_mb)
  216. {
  217. restart();
  218. }
  219. inline void write()
  220. {
  221. size32_t sz = size();
  222. mb.writeDirect(pos, sizeof(sz), &sz);
  223. }
  224. inline size32_t size() const
  225. {
  226. return (size32_t)(mb.length() - (pos + sizeof(size32_t)));
  227. }
  228. // resets position marker and writes another size to be filled subsequently by write()
  229. inline void restart()
  230. {
  231. pos = mb.length();
  232. mb.append((size32_t)0);
  233. }
  234. };
  235. interface jlib_decl serializable : extends IInterface
  236. {
  237. public:
  238. virtual void serialize(MemoryBuffer &tgt) = 0;
  239. virtual void deserialize(MemoryBuffer &src) = 0;
  240. };
  241. class jlib_decl MemoryBuffer2IDataVal : public CInterface, implements IDataVal
  242. {
  243. public:
  244. MemoryBuffer2IDataVal(MemoryBuffer & _buffer) : buffer(_buffer) {}
  245. IMPLEMENT_IINTERFACE;
  246. virtual const void * data() const { return buffer.toByteArray(); }
  247. virtual void clear() { } // clearing when appending does nothing
  248. virtual void setLen(const void * val, size_t length) { buffer.append((size32_t)length, val); }
  249. virtual size_t length() const { return buffer.length(); }
  250. virtual void * reserve(size_t length) { return buffer.reserveTruncate((size32_t)length); }
  251. private:
  252. MemoryBuffer & buffer;
  253. };
  254. class jlib_decl MemoryAttr2IStringVal : public CInterface, implements IStringVal
  255. {
  256. public:
  257. MemoryAttr2IStringVal(MemoryAttr & _attr) : attr(_attr) {}
  258. IMPLEMENT_IINTERFACE;
  259. virtual const char * str() const;
  260. virtual void set(const char *val) { attr.set(strlen(val), val); }
  261. virtual void clear() { attr.clear(); } // clearing when appending does nothing
  262. virtual void setLen(const char *val, unsigned length) { attr.set(length, val); }
  263. virtual unsigned length() const { return (size32_t)attr.length(); };
  264. protected:
  265. MemoryAttr & attr;
  266. };
  267. class jlib_decl Variable2IDataVal : public CInterface, implements IDataVal
  268. {
  269. public:
  270. Variable2IDataVal(unsigned * _pLen, void * * _pData) { pLen = _pLen; pData = _pData; }
  271. IMPLEMENT_IINTERFACE;
  272. virtual const void * data() const { return *pData; };
  273. virtual void clear() { free(*pData); *pData = NULL; *pLen = 0; };
  274. virtual void setLen(const void * val, size_t length) { free(*pData); *pData = malloc(length); memcpy(*pData, val, length); *pLen = (size32_t)length; }
  275. virtual size_t length() const { return *pLen; };
  276. virtual void * reserve(size_t length) { free(*pData); *pData = malloc(length); *pLen = (size32_t)length; return *pData; }
  277. private:
  278. unsigned * pLen; // Should really be a size_t
  279. void * * pData;
  280. };
  281. //Similar to above, but only used for fixed sized returns (or variable size rows with a known max length)
  282. class jlib_decl Fixed2IDataVal : public CInterface, implements IDataVal
  283. {
  284. public:
  285. Fixed2IDataVal(size_t _len, void * _ptr) { len = _len; ptr = _ptr; }
  286. IMPLEMENT_IINTERFACE;
  287. virtual const void * data() const { return ptr; };
  288. virtual void clear() { memset(ptr, 0, len); };
  289. virtual void setLen(const void * val, size_t length) { assertex(length <= len); memcpy(ptr, val, length); }
  290. virtual size_t length() const { return len; };
  291. virtual void * reserve(size_t length) { assertex(length <= len); return ptr; }
  292. private:
  293. size_t len;
  294. void * ptr;
  295. };
  296. #ifdef __GNUC__
  297. class jlib_decl GccMemoryBuffer2IDataVal
  298. {
  299. public:
  300. GccMemoryBuffer2IDataVal(MemoryBuffer & _buffer) : adaptor(_buffer) {}
  301. inline operator IDataVal & () { return adaptor; }
  302. private:
  303. MemoryBuffer2IDataVal adaptor;
  304. };
  305. class jlib_decl GccVariable2IDataVal
  306. {
  307. public:
  308. GccVariable2IDataVal(unsigned * _pLen, void * * _pData) : adaptor(_pLen, _pData) {}
  309. inline operator IDataVal & () { return adaptor; }
  310. private:
  311. Variable2IDataVal adaptor;
  312. };
  313. #define MemoryBuffer2IDataVal GccMemoryBuffer2IDataVal
  314. #define Variable2IDataVal GccVariable2IDataVal
  315. #endif
  316. extern jlib_decl MemoryBuffer & serialize(MemoryBuffer & buffer, const MemoryAttr & value);
  317. extern jlib_decl MemoryBuffer & deserialize(MemoryBuffer & buffer, MemoryAttr & value);
  318. extern jlib_decl MemoryBuffer & serialize(MemoryBuffer & buffer, const char * value);
  319. extern jlib_decl MemoryBuffer & deserialize(MemoryBuffer & buffer, StringAttr & value);
  320. class jlib_decl CContiguousLargeMemoryAllocator
  321. {
  322. // limited to 4GB for the moment
  323. protected:
  324. byte *base;
  325. size32_t totalmax;
  326. size32_t ofs;
  327. size32_t chunkmin; // only used for next and nextBuffer;
  328. size32_t mapped; // amount of 'real' memory
  329. bool throwexception;
  330. HANDLE hfile;
  331. #ifdef WIN32
  332. HANDLE hmap;
  333. #endif
  334. void outOfMem(size32_t sz);
  335. bool map(size32_t tot,size32_t sz);
  336. void unmap();
  337. public:
  338. CContiguousLargeMemoryAllocator(size32_t _totalmax,size32_t _chunkmin,bool _throwexception)
  339. {
  340. init(_totalmax,_chunkmin,_throwexception);
  341. }
  342. CContiguousLargeMemoryAllocator();
  343. void init(size32_t _totalmax,size32_t _chunkmin,bool _throwexception);
  344. virtual ~CContiguousLargeMemoryAllocator();
  345. inline void setTotalMax(size32_t total)
  346. {
  347. totalmax = total;
  348. }
  349. inline size32_t getTotalMax()
  350. {
  351. return totalmax;
  352. }
  353. inline bool checkAvail(size32_t sz, size32_t sza=0,size32_t extra=0)
  354. {
  355. if (sza>sz)
  356. sz = sza;
  357. if (ofs+sz+extra>mapped)
  358. if (!map(ofs+sz+extra,sz))
  359. return false;
  360. return true;
  361. }
  362. inline byte *alloc(size32_t sz,size32_t extra=0)
  363. {
  364. if (mapped<ofs+sz+extra)
  365. if (!map(ofs+sz+extra,sz))
  366. return NULL;
  367. byte *ret = base+ofs;
  368. ofs += sz;
  369. return ret;
  370. }
  371. inline size32_t allocated()
  372. {
  373. return ofs;
  374. }
  375. inline size32_t maxallocated()
  376. {
  377. return mapped;
  378. }
  379. void setChunkGranularity(size32_t sz)
  380. {
  381. if (sz&&(chunkmin>sz))
  382. chunkmin -= (chunkmin%sz);
  383. }
  384. void reset();
  385. void setSize(size32_t pos);
  386. void reduceSize(size32_t amount);
  387. byte *next(size32_t pos,size32_t &size);
  388. MemoryBuffer &serialize(MemoryBuffer &mb);
  389. MemoryBuffer &deserialize(MemoryBuffer &mb,size32_t sz, size32_t extra=0);
  390. void *nextBuffer(void *prev,size32_t &sz);
  391. void *getBase();
  392. };
  393. class jlib_decl CLargeMemoryAllocator
  394. {
  395. protected:
  396. struct Chunk
  397. {
  398. Chunk *prev;
  399. byte *base;
  400. size32_t max;
  401. size32_t size;
  402. } chunk;
  403. memsize_t totalmax;
  404. size32_t chunkmin;
  405. memsize_t amax; // total of max values
  406. memsize_t atot; // total allocated not including chunk.size
  407. bool throwexception;
  408. bool newchunk(size32_t sz,size32_t extra,bool exceptionwanted);
  409. virtual void allocchunkmem();
  410. virtual void disposechunkmem();
  411. public:
  412. CLargeMemoryAllocator(memsize_t _totalmax,size32_t _chunkmin,bool _throwexception)
  413. {
  414. init(_totalmax,_chunkmin,_throwexception);
  415. }
  416. CLargeMemoryAllocator();
  417. void init(memsize_t _totalmax,size32_t _chunkmin,bool _throwexception);
  418. virtual ~CLargeMemoryAllocator()
  419. {
  420. reset();
  421. }
  422. inline void setTotalMax(memsize_t total)
  423. {
  424. totalmax = total;
  425. }
  426. inline memsize_t getTotalMax()
  427. {
  428. return totalmax;
  429. }
  430. inline byte *alloc(size32_t sz,size32_t extra=0)
  431. {
  432. size32_t chsize = chunk.size;
  433. if (chsize+sz>chunk.max) {
  434. if (!newchunk(sz,extra,throwexception))
  435. return NULL;
  436. chsize = chunk.size;
  437. }
  438. byte *ret = chunk.base+chsize;
  439. chunk.size = chsize+sz;
  440. return ret;
  441. }
  442. inline bool checkAvail(size32_t sz, size32_t sza=0,size32_t extra=0)
  443. {
  444. if (chunk.size+sz>chunk.max) {
  445. if (sza<sz)
  446. sza = sz;
  447. if (!newchunk(sza,extra,false))
  448. return false;
  449. }
  450. return true;
  451. }
  452. inline memsize_t allocated()
  453. {
  454. return chunk.size+atot;
  455. }
  456. inline memsize_t maxallocated()
  457. {
  458. return amax;
  459. }
  460. void setChunkGranularity(size32_t sz)
  461. {
  462. if (sz&&(chunkmin>sz))
  463. chunkmin -= (chunkmin%sz);
  464. }
  465. void reset();
  466. void setSize(memsize_t pos);
  467. void reduceSize(memsize_t amount);
  468. byte *next(memsize_t pos,size32_t &size); // this should not be used for small jumps as it is slow
  469. MemoryBuffer &serialize(MemoryBuffer &mb);
  470. MemoryBuffer &deserialize(MemoryBuffer &mb,size32_t sz, size32_t extra=0);
  471. void *nextBuffer(void *prev,size32_t &sz); // to enumerate buffers (NULL returns first)
  472. };
  473. class jlib_decl CJMallocLargeMemoryAllocator: public CLargeMemoryAllocator
  474. {
  475. IAllocator *allocator;
  476. virtual void allocchunkmem();
  477. virtual void disposechunkmem();
  478. public:
  479. CJMallocLargeMemoryAllocator(IAllocator *_allocator,memsize_t _totalmax,size32_t _chunkmin,bool _throwexception)
  480. : allocator(_allocator)
  481. {
  482. allocator = _allocator;
  483. allocator->Link();
  484. CLargeMemoryAllocator::init(_totalmax,_chunkmin,_throwexception);
  485. }
  486. ~CJMallocLargeMemoryAllocator()
  487. {
  488. CLargeMemoryAllocator::reset();
  489. allocator->Release();
  490. }
  491. IAllocator *queryAllocator() { return allocator; }
  492. };
  493. class CLargeMemorySequentialReader
  494. {
  495. size32_t left;
  496. memsize_t pos;
  497. const void *ptr;
  498. CLargeMemoryAllocator &allocator;
  499. inline CLargeMemorySequentialReader(CLargeMemoryAllocator &_allocator)
  500. : allocator(_allocator)
  501. {
  502. left = 0;
  503. pos = 0;
  504. }
  505. inline const void *read(size32_t &max)
  506. {
  507. if (!left) {
  508. ptr = allocator.next(pos,left);
  509. if (!left)
  510. return NULL;
  511. }
  512. max = left;
  513. return ptr;
  514. }
  515. inline void skip(size32_t sz)
  516. {
  517. assertex(left>=sz);
  518. left -= sz;
  519. pos += sz;
  520. ptr = (const byte *)ptr+sz;
  521. }
  522. };
  523. interface IOutOfMemException;
  524. jlib_decl IOutOfMemException *createOutOfMemException(int errcode, size_t wanted, size_t got=0, bool expected=false, const char *errMsg=nullptr);
  525. jlib_decl void RaiseOutOfMemException(int errcode, size_t wanted, size_t got=0, bool expected=false, const char *errMsg=nullptr);
  526. interface ILargeMemLimitNotify: extends IInterface
  527. {
  528. virtual bool take(memsize_t tot)=0; // called when a memory request about to be satisfied will exceed limit
  529. // will raise oom exception if false returned
  530. virtual void give(memsize_t tot)=0; // called when the memory allocated falls back below the limit
  531. };
  532. extern jlib_decl void setLargeMemLimitNotify(memsize_t size,ILargeMemLimitNotify *notify);
  533. inline void *checked_malloc(size_t len,int errcode)
  534. {
  535. if (len==0)
  536. return NULL;
  537. void *ret = malloc(len);
  538. if (!ret)
  539. RaiseOutOfMemException(errcode, len);
  540. return ret;
  541. }
  542. jlib_decl void *checked_realloc(void *orig, size_t newlen, size_t origlen,int errcode);
  543. class NonReentrantSpinLock;
  544. class jlib_decl CFixedSizeAllocator
  545. {
  546. private:
  547. void *freelist;
  548. void *chunklist;
  549. NonReentrantSpinLock lock;
  550. unsigned numalloc;
  551. unsigned numfree;
  552. size32_t allocsize;
  553. size32_t chunksize;
  554. void *allocChunk();
  555. void freeChunk(void *);
  556. public:
  557. CFixedSizeAllocator();
  558. CFixedSizeAllocator(size32_t _allocsize,size32_t _chunksize=0x100000);
  559. virtual ~CFixedSizeAllocator();
  560. void init(size32_t _allocsize,size32_t _chunksize=0x100000);
  561. void kill();
  562. void *alloc();
  563. void dealloc(void *blk);
  564. void stats(size32_t &sizealloc, size32_t &sizeunused);
  565. };
  566. #endif