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_LINKED_H_
00038 #include <ucommon/linked.h>
00039 #endif
00040
00041 NAMESPACE_UCOMMON
00042
00043 class PagerPool;
00044
00052 class __EXPORT memalloc
00053 {
00054 private:
00055 size_t pagesize, align;
00056 unsigned count;
00057
00058 typedef struct mempage {
00059 struct mempage *next;
00060 union {
00061 void *memalign;
00062 unsigned used;
00063 };
00064 } page_t;
00065
00066 page_t *page;
00067
00068 protected:
00069 unsigned limit;
00070
00075 page_t *pager(void);
00076
00077 public:
00082 memalloc(size_t page = 0);
00083
00087 virtual ~memalloc();
00088
00093 inline unsigned getPages(void)
00094 {return count;};
00095
00103 inline unsigned getLimit(void)
00104 {return limit;};
00105
00110 inline unsigned getAlloc(void)
00111 {return pagesize;};
00112
00123 unsigned utilization(void);
00124
00128 void purge(void);
00129
00136 virtual void *alloc(size_t size);
00137
00145 void *zalloc(size_t size);
00146
00152 char *dup(const char *string);
00153
00160 void *dup(void *memory, size_t size);
00161 };
00162
00183 class __EXPORT mempager : public memalloc
00184 {
00185 private:
00186 pthread_mutex_t mutex;
00187
00188 public:
00193 mempager(size_t page = 0);
00194
00198 virtual ~mempager();
00199
00206 inline void lock(void)
00207 {pthread_mutex_lock(&mutex);};
00208
00212 inline void unlock(void)
00213 {pthread_mutex_unlock(&mutex);};
00214
00225 unsigned utilization(void);
00226
00230 void purge(void);
00231
00239 virtual void dealloc(void *memory);
00240
00248 void *alloc(size_t size);
00249
00258 void *zalloc(size_t size);
00259
00266 char *dup(const char *string);
00267
00275 void *dup(void *memory, size_t size);
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
00353 class __EXPORT PagerPool
00354 {
00355 private:
00356 mempager *pager;
00357 LinkedObject *freelist;
00358 pthread_mutex_t mutex;
00359
00360 protected:
00361 PagerPool(mempager *pager);
00362 ~PagerPool();
00363
00364 PagerObject *get(size_t size);
00365
00366 public:
00371 void put(PagerObject *object);
00372 };
00373
00385 class __EXPORT keyassoc : protected mempager
00386 {
00387 private:
00391 class __LOCAL keydata : public NamedObject
00392 {
00393 public:
00394 void *data;
00395 char text[8];
00396
00397 keydata(keyassoc *assoc, char *id, unsigned max, unsigned bufsize);
00398 };
00399
00400 friend class keydata;
00401
00402 unsigned count;
00403 unsigned paths;
00404 size_t keysize;
00405 NamedObject **root;
00406 LinkedObject **list;
00407
00408 public:
00415 keyassoc(unsigned indexing = 177, size_t max = 0, size_t page = 0);
00416
00420 ~keyassoc();
00421
00426 inline unsigned getCount(void)
00427 {return count;};
00428
00434 inline void *operator()(const char *name)
00435 {return locate(name);};
00436
00440 void purge(void);
00441
00447 void *locate(const char *name);
00448
00456 bool assign(char *name, void *pointer);
00457
00464 bool create(char *name, void *pointer);
00465
00472 void *remove(const char *name);
00473 };
00474
00482 template <class T, unsigned I = 177, size_t M = 0, size_t P = 0>
00483 class assoc_pointer : private keyassoc
00484 {
00485 public:
00489 inline assoc_pointer() : keyassoc(I, M, P) {};
00490
00495 inline unsigned getCount(void)
00496 {return keyassoc::getCount();};
00497
00501 inline void purge(void)
00502 {keyassoc::purge();};
00503
00509 inline T *locate(const char *name)
00510 {return static_cast<T*>(keyassoc::locate(name));};
00511
00517 inline T *operator()(const char *name)
00518 {return locate(name);};
00519
00527 inline bool assign(char *name, T *pointer)
00528 {return keyassoc::assign(name, pointer);};
00529
00536 inline bool create(char *name, T *pointer)
00537 {return keyassoc::create(name, pointer);};
00538
00544 inline void remove(char *name)
00545 {keyassoc::remove(name);};
00546
00552 inline unsigned utilization(void)
00553 {return mempager::utilization();};
00554
00561 inline unsigned getPages(void)
00562 {return mempager::getPages();};
00563 };
00564
00571 template <class T>
00572 class pager : private PagerPool
00573 {
00574 public:
00579 inline pager(mempager *heap = NULL) : PagerPool(heap) {};
00580
00584 inline ~pager()
00585 {mempager::purge();};
00586
00591 inline T *operator()(void)
00592 {return new(get(sizeof(T))) T;};
00593
00598 inline T *operator*()
00599 {return new(get(sizeof(T))) T;};
00600 };
00601
00607 template <class T, unsigned M = 177>
00608 class keypager : public mempager
00609 {
00610 private:
00611 NamedObject *idx[M];
00612
00613 public:
00618 inline keypager(size_t size) : mempager(size) {};
00619
00623 inline ~keypager()
00624 {NamedObject::purge(idx, M); mempager::purge();};
00625
00632 inline T *get(const char *name) const {
00633 T *node = (static_cast<T*>(NamedObject::map(idx, name, M)));
00634 if(!node) {
00635 node = init<T>(static_cast<T*>(mempager::alloc(sizeof(T))));
00636 node->NamedObject::add(idx, name, M);
00637 }
00638 return node;
00639 }
00640
00646 bool test(const char *name) const
00647 {return NamedObject::map(idx, name, M) != NULL;};
00648
00655 inline T *operator[](const char *name) const
00656 {return get(name);};
00657
00662 inline T *begin(void) const
00663 {return static_cast<T*>(NamedObject::skip(idx, NULL, M));};
00664
00670 inline T *next(T *current) const
00671 {return static_cast<T*>(NamedObject::skip(idx, current, M));};
00672
00677 inline unsigned count(void) const
00678 {return NamedObject::count(idx, M);};
00679
00686 inline T **index(void) const
00687 {return NamedObject::index(idx, M);};
00688
00695 inline T **sort(void) const
00696 {return NamedObject::sort(NamedObject::index(idx, M));};
00697 };
00698
00699 END_NAMESPACE
00700
00701 #endif