jbuff.hpp 20 KB

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