00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00030 #ifndef _UCOMMON_MEMORY_H_
00031 #define _UCOMMON_MEMORY_H_
00032
00033 #ifndef _UCOMMON_CONFIG_H_
00034 #include <ucommon/platform.h>
00035 #endif
00036
00037 #ifndef _UCOMMON_PROTOCOLS_H_
00038 #include <ucommon/protocols.h>
00039 #endif
00040
00041 #ifndef _UCOMMON_LINKED_H_
00042 #include <ucommon/linked.h>
00043 #endif
00044
00045 NAMESPACE_UCOMMON
00046
00047 class PagerPool;
00048
00056 class __EXPORT memalloc : public MemoryProtocol, protected LockingProtocol
00057 {
00058 private:
00059 friend class bufpager;
00060
00061 size_t pagesize, align;
00062 unsigned count;
00063
00064 typedef struct mempage {
00065 struct mempage *next;
00066 union {
00067 void *memalign;
00068 unsigned used;
00069 };
00070 } page_t;
00071
00072 page_t *page;
00073
00074 protected:
00075 unsigned limit;
00076
00081 page_t *pager(void);
00082
00083 public:
00088 memalloc(size_t page = 0);
00089
00093 virtual ~memalloc();
00094
00099 inline unsigned getPages(void)
00100 {return count;};
00101
00109 inline unsigned getLimit(void)
00110 {return limit;};
00111
00116 inline unsigned getAlloc(void)
00117 {return pagesize;};
00118
00129 unsigned utilization(void);
00130
00134 void purge(void);
00135
00143 virtual void *_alloc(size_t size);
00144 };
00145
00166 class __EXPORT mempager : public memalloc
00167 {
00168 private:
00169 pthread_mutex_t mutex;
00170
00171 protected:
00178 virtual void _lock(void);
00179
00183 virtual void _unlock(void);
00184
00185 public:
00190 mempager(size_t page = 0);
00191
00195 virtual ~mempager();
00196
00207 unsigned utilization(void);
00208
00212 void purge(void);
00213
00221 virtual void dealloc(void *memory);
00222
00231 virtual void *_alloc(size_t size);
00232 };
00233
00238 class __EXPORT bufpager : public memalloc, public CharacterProtocol
00239 {
00240 private:
00241 typedef struct cpage {
00242 struct cpage *next;
00243 char *text;
00244 unsigned size, used;
00245 } cpage_t;
00246
00247 cpage_t *first, *last, *current, *freelist;
00248 unsigned cpos;
00249 unsigned long ccount;
00250
00251 virtual int _getch(void);
00252 virtual int _putch(int code);
00253
00254 protected:
00255 virtual void *_alloc(size_t size);
00256
00257 public:
00261 void reset(void);
00262
00266 void rewind(void);
00267
00272 inline unsigned long getUsed(void)
00273 {return ccount;};
00274
00275 bufpager(size_t page = 0);
00276 };
00277
00285 class __EXPORT autorelease
00286 {
00287 private:
00288 LinkedObject *pool;
00289
00290 public:
00294 autorelease();
00295
00299 ~autorelease();
00300
00306 void release(void);
00307
00312 void operator+=(LinkedObject *object);
00313 };
00314
00325 class __EXPORT PagerObject : public LinkedObject, public CountedObject
00326 {
00327 protected:
00328 friend class PagerPool;
00329
00330 PagerPool *pager;
00331
00335 PagerObject();
00336
00340 void release(void);
00341
00345 void dealloc(void);
00346 };
00347
00356 class __EXPORT PagerPool : public MemoryProtocol
00357 {
00358 private:
00359 LinkedObject *freelist;
00360 pthread_mutex_t mutex;
00361
00362 protected:
00363 PagerPool();
00364 ~PagerPool();
00365
00366 PagerObject *get(size_t size);
00367
00368 public:
00373 void put(PagerObject *object);
00374 };
00375
00376 class __EXPORT charmem : public CharacterProtocol
00377 {
00378 protected:
00379 char *buffer;
00380 size_t inp, out, size;
00381 bool dynamic;
00382
00383 int _getch(void);
00384 int _putch(int code);
00385
00386 public:
00387 charmem(char *mem, size_t size);
00388 charmem(size_t size);
00389 charmem();
00390 ~charmem();
00391
00392 void release(void);
00393
00394 void set(char *mem, size_t size);
00395
00396 void set(size_t size);
00397
00398 inline void reset(void)
00399 {inp = out = 0;}
00400
00401 inline void rewind(void)
00402 {inp = 0;}
00403 };
00404
00405 class __EXPORT chartext : public CharacterProtocol
00406 {
00407 private:
00408 char *pos;
00409 size_t max;
00410
00411 int _putch(int code);
00412 int _getch(void);
00413
00414 public:
00415 chartext();
00416 chartext(char *buf);
00417 chartext(char *buf, size_t size);
00418 };
00419
00431 class __EXPORT keyassoc : protected mempager
00432 {
00433 private:
00437 class __LOCAL keydata : public NamedObject
00438 {
00439 public:
00440 void *data;
00441 char text[8];
00442
00443 keydata(keyassoc *assoc, char *id, unsigned max, unsigned bufsize);
00444 };
00445
00446 friend class keydata;
00447
00448 unsigned count;
00449 unsigned paths;
00450 size_t keysize;
00451 NamedObject **root;
00452 LinkedObject **list;
00453
00454 public:
00461 keyassoc(unsigned indexing = 177, size_t max = 0, size_t page = 0);
00462
00466 ~keyassoc();
00467
00472 inline unsigned getCount(void)
00473 {return count;};
00474
00480 inline void *operator()(const char *name)
00481 {return locate(name);};
00482
00486 void purge(void);
00487
00493 void *locate(const char *name);
00494
00502 bool assign(char *name, void *pointer);
00503
00510 bool create(char *name, void *pointer);
00511
00518 void *remove(const char *name);
00519 };
00520
00528 template <class T, unsigned I = 177, size_t M = 0, size_t P = 0>
00529 class assoc_pointer : private keyassoc
00530 {
00531 public:
00535 inline assoc_pointer() : keyassoc(I, M, P) {};
00536
00541 inline unsigned getCount(void)
00542 {return keyassoc::getCount();};
00543
00547 inline void purge(void)
00548 {keyassoc::purge();};
00549
00555 inline T *locate(const char *name)
00556 {return static_cast<T*>(keyassoc::locate(name));};
00557
00563 inline T *operator()(const char *name)
00564 {return locate(name);};
00565
00573 inline bool assign(char *name, T *pointer)
00574 {return keyassoc::assign(name, pointer);};
00575
00582 inline bool create(char *name, T *pointer)
00583 {return keyassoc::create(name, pointer);};
00584
00590 inline void remove(char *name)
00591 {keyassoc::remove(name);};
00592
00598 inline unsigned utilization(void)
00599 {return mempager::utilization();};
00600
00607 inline unsigned getPages(void)
00608 {return mempager::getPages();};
00609 };
00610
00617 template <typename T>
00618 class pager : private MemoryRedirect, private PagerPool
00619 {
00620 public:
00625 inline pager(mempager *heap = NULL) : MemoryRedirect(heap), PagerPool() {};
00626
00630 inline ~pager()
00631 {mempager::purge();};
00632
00637 inline T *operator()(void)
00638 {return new(get(sizeof(T))) T;};
00639
00644 inline T *operator*()
00645 {return new(get(sizeof(T))) T;};
00646 };
00647
00653 template <class T, unsigned M = 177>
00654 class keypager : public mempager
00655 {
00656 private:
00657 NamedObject *idx[M];
00658
00659 public:
00664 inline keypager(size_t size) : mempager(size) {};
00665
00669 inline ~keypager()
00670 {NamedObject::purge(idx, M); mempager::purge();};
00671
00678 inline T *get(const char *name) const {
00679 T *node = (static_cast<T*>(NamedObject::map(idx, name, M)));
00680 if(!node) {
00681 node = init<T>(static_cast<T*>(mempager::_alloc(sizeof(T))));
00682 node->NamedObject::add(idx, name, M);
00683 }
00684 return node;
00685 }
00686
00692 bool test(const char *name) const
00693 {return NamedObject::map(idx, name, M) != NULL;};
00694
00701 inline T *operator[](const char *name) const
00702 {return get(name);};
00703
00708 inline T *begin(void) const
00709 {return static_cast<T*>(NamedObject::skip(idx, NULL, M));};
00710
00716 inline T *next(T *current) const
00717 {return static_cast<T*>(NamedObject::skip(idx, current, M));};
00718
00723 inline unsigned count(void) const
00724 {return NamedObject::count(idx, M);};
00725
00732 inline T **index(void) const
00733 {return NamedObject::index(idx, M);};
00734
00741 inline T **sort(void) const
00742 {return NamedObject::sort(NamedObject::index(idx, M));};
00743 };
00744
00745 END_NAMESPACE
00746
00747 #endif