UCommon
memory.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
31 #ifndef _UCOMMON_MEMORY_H_
32 #define _UCOMMON_MEMORY_H_
33 
34 #ifndef _UCOMMON_CONFIG_H_
35 #include <ucommon/platform.h>
36 #endif
37 
38 #ifndef _UCOMMON_PROTOCOLS_H_
39 #include <ucommon/protocols.h>
40 #endif
41 
42 #ifndef _UCOMMON_LINKED_H_
43 #include <ucommon/linked.h>
44 #endif
45 
46 #ifndef _UCOMMON_STRING_H_
47 #include <ucommon/string.h>
48 #endif
49 
50 namespace ucommon {
51 
52 class PagerPool;
53 
61 class __EXPORT memalloc : public __PROTOCOL MemoryProtocol
62 {
63 private:
64  friend class bufpager;
65 
66  size_t pagesize, align;
67  unsigned count;
68 
69  typedef struct mempage {
70  struct mempage *next;
71  union {
72  void *memalign;
73  unsigned used;
74  };
75  } page_t;
76 
77  page_t *page;
78 
79 protected:
80  unsigned limit;
81 
86  page_t *pager(void);
87 
88 public:
93  memalloc(size_t page = 0);
94 
95  memalloc(const memalloc& copy);
96 
100  virtual ~memalloc();
101 
106  inline unsigned pages(void) const {
107  return count;
108  }
109 
117  inline unsigned max(void) const {
118  return limit;
119  }
120 
125  inline size_t size(void) const {
126  return pagesize;
127  }
128 
139  unsigned utilization(void) const;
140 
144  void purge(void);
145 
146 protected:
154  virtual void *_alloc(size_t size) __OVERRIDE;
155 
156 public:
161  void assign(memalloc& source);
162 };
163 
184 class __EXPORT mempager : public memalloc, public __PROTOCOL LockingProtocol
185 {
186 private:
187  mutable pthread_mutex_t mutex;
188 
189 protected:
196  virtual void _lock(void) __OVERRIDE;
197 
201  virtual void _unlock(void) __OVERRIDE;
202 
203 public:
208  mempager(size_t page = 0);
209 
210  mempager(const mempager& copy);
211 
215  virtual ~mempager();
216 
227  unsigned utilization(void);
228 
232  void purge(void);
233 
241  virtual void dealloc(void *memory);
242 
243 protected:
252  virtual void *_alloc(size_t size) __OVERRIDE;
253 
254 public:
259  void assign(mempager& source);
260 };
261 
262 class __EXPORT ObjectPager : protected memalloc
263 {
264 public:
265  class __EXPORT member : public LinkedObject
266  {
267  private:
268  void *mem;
269 
270  protected:
271  friend class ObjectPager;
272 
273  inline void set(member *node) {
274  Next = node;
275  }
276 
277  inline void *get(void) const {
278  return mem;
279  }
280 
281  member(LinkedObject **root);
282  member();
283 
284  public:
285  inline void *operator*() const {
286  return mem;
287  }
288  };
289 
290 private:
291  unsigned members;
292  LinkedObject *root;
293  size_t typesize;
294  member *last;
295  void **index;
296 
297  __DELETE_COPY(ObjectPager);
298 
299 protected:
300  ObjectPager(size_t objsize, size_t pagesize = 256);
301 
308  void *get(unsigned item) const;
309 
314  void *add(void);
315 
316  void *push(void);
317 
322  void *pull(void);
323 
328  void *pop(void);
329 
334  void *invalid(void) const;
335 
336 public:
341  void clear(void);
342 
348  inline ObjectPager::member *begin(void) {
349  return static_cast<ObjectPager::member *>(root);
350  }
351 
352  inline operator bool() const {
353  return members > 0;
354  }
355 
356  inline bool operator!() const {
357  return !members;
358  }
359 
364  inline unsigned count(void) const {
365  return members;
366  }
367 
371  typedef linked_pointer<ObjectPager::member> iterator;
372 
373  inline size_t size(void) {
374  return memalloc::size();
375  }
376 
377  inline unsigned pages(void) {
378  return memalloc::pages();
379  }
380 
381 protected:
386  void **list(void);
387 
388 public:
393  void assign(ObjectPager& source);
394 };
395 
401 class __EXPORT StringPager : protected memalloc
402 {
403 private:
404  unsigned members;
405  LinkedObject *root;
406 
407 public:
415  virtual bool filter(char *text, size_t size);
416 
423  class __EXPORT member : public LinkedObject
424  {
425  private:
426  const char *text;
427 
428  protected:
429  friend class StringPager;
430 
431  inline void set(member *node)
432  {Next = node;}
433 
434  member(LinkedObject **root, const char *data);
435  member(const char *data);
436 
437  public:
438  inline const char *operator*() const {
439  return text;
440  }
441 
442  inline const char *get(void) const {
443  return text;
444  }
445  };
446 
451  StringPager(size_t pagesize = 256);
452 
453  StringPager(char **list, size_t pagesize = 256);
454 
459  inline unsigned count(void) const {
460  return members;
461  }
462 
469  const char *get(unsigned item) const;
470 
476  void set(unsigned item, const char *string);
477 
482  void add(const char *text);
483 
488  void push(const char *text);
489 
494  void push(char **text);
495 
500  const char *pull(void);
501 
506  const char *pop(void);
507 
513  void add(char **list);
514 
520  void set(char **list);
521 
526  void clear(void);
527 
534  inline const char *operator[](unsigned item) const {
535  return get(item);
536  }
537 
538  inline const char *at(unsigned item) const {
539  return get(item);
540  }
541 
547  inline StringPager::member *begin(void) const {
548  return static_cast<StringPager::member *>(root);
549  }
550 
555  inline void operator+=(const char *text) {
556  add(text);
557  }
558 
563  inline StringPager& operator<<(const char *text) {
564  add(text);
565  return *this;
566  }
567 
568  inline StringPager& operator>>(const char *text) {
569  push(text);
570  return *this;
571  }
572 
576  void sort(void);
577 
582  char **list(void);
583 
592  unsigned token(const char *text, const char *list, const char *quote = NULL, const char *end = NULL);
593 
594  unsigned split(const char *text, const char *string, unsigned flags = 0);
595 
596  unsigned split(stringex_t& expr, const char *string, unsigned flags = 0);
597 
598  String join(const char *prefix = NULL, const char *middle = NULL, const char *suffix = NULL);
599 
600  inline operator bool() const {
601  return members > 0;
602  }
603 
604  inline bool operator!() const {
605  return !members;
606  }
607 
608  inline StringPager& operator=(char **list) {
609  set(list);
610  return *this;
611  }
612 
613  inline const char *operator*() {
614  return pull();
615  }
616 
617  inline operator char **() {
618  return list();
619  }
620 
625 
626  inline size_t size(void) const {
627  return memalloc::size();
628  }
629 
630  inline unsigned pages(void) const {
631  return memalloc::pages();
632  }
633 
634 private:
635  member *last;
636  char **index;
637 
638 public:
643  void assign(StringPager& source);
644 };
645 
653 class __EXPORT DirPager : protected StringPager
654 {
655 private:
656  __DELETE_COPY(DirPager);
657 
658 protected:
659  const char *dir;
660 
668  virtual bool filter(char *filename, size_t size) __OVERRIDE;
669 
675  bool load(const char *path);
676 
677 public:
678  DirPager();
679 
680  DirPager(const char *path);
681 
682  void operator=(const char *path);
683 
684  inline const char *operator*() const {
685  return dir;
686  }
687 
688  inline operator bool() const {
689  return dir != NULL;
690  }
691 
692  inline bool operator!() const {
693  return dir == NULL;
694  }
695 
696  inline unsigned count(void) const {
697  return StringPager::count();
698  }
699 
706  inline const char *operator[](unsigned item) const {
707  return StringPager::get(item);
708  }
709 
710  inline const char *get(unsigned item) const {
711  return StringPager::get(item);
712  }
713 
714  inline const char *at(unsigned item) const {
715  return StringPager::get(item);
716  }
717 
718  inline size_t size(void) const {
719  return memalloc::size();
720  }
721 
722  inline unsigned pages(void) const {
723  return memalloc::pages();
724  }
725 
726 public:
731  void assign(DirPager& source);
732 };
733 
741 class __EXPORT autorelease
742 {
743 private:
744  LinkedObject *pool;
745 
746  __DELETE_COPY(autorelease);
747 
748 public:
752  autorelease();
753 
757  ~autorelease();
758 
764  void release(void);
765 
770  void operator+=(LinkedObject *object);
771 };
772 
783 class __EXPORT PagerObject : public LinkedObject, public CountedObject
784 {
785 private:
786  __DELETE_COPY(PagerObject);
787 
788 protected:
789  friend class PagerPool;
790 
791  PagerPool *pager;
792 
796  PagerObject();
797 
801  void reset(void);
802 
803  void retain(void) __OVERRIDE;
804 
808  void release(void) __OVERRIDE;
809 
813  void dealloc(void) __OVERRIDE;
814 };
815 
824 class __EXPORT PagerPool : public __PROTOCOL MemoryProtocol
825 {
826 private:
827  LinkedObject *freelist;
828  mutable pthread_mutex_t mutex;
829 
830  __DELETE_COPY(PagerPool);
831 
832 protected:
833  PagerPool();
834  virtual ~PagerPool();
835 
836  PagerObject *get(size_t size);
837 
838 public:
843  void put(PagerObject *object);
844 };
845 
852 template <typename T>
853 class pager : private MemoryRedirect, private PagerPool
854 {
855 private:
856  __DELETE_COPY(pager);
857 
858 public:
863  inline pager(mempager *heap = NULL) : MemoryRedirect(heap), PagerPool() {}
864 
869  inline T *operator()(void) {
870  return new(get(sizeof(T))) T;
871  }
872 
877  inline T *operator*() {
878  return new(get(sizeof(T))) T;
879  }
880 };
881 
886 
891 
896 
897 inline String str(StringPager& list, const char *prefix = NULL, const char *middle = NULL, const char *suffix = NULL) {
898  return list.join(prefix, middle, suffix);
899 }
900 
901 } // namespace ucommon
902 
903 #endif
Linked objects, lists, templates, and containers.
const char * operator[](unsigned item) const
Return specified member from pager list.
Definition: memory.h:534
Mempager managed type factory for pager pool objects.
Definition: memory.h:853
pager(mempager *heap=NULL)
Construct a pager and optionally assign a private pager heap.
Definition: memory.h:863
Create a linked list of auto-releasable objects.
Definition: memory.h:741
String pager for storing lists of NULL terminated strings.
Definition: memory.h:401
linked_pointer< StringPager::member > iterator
Convenience typedef for iterative pointer.
Definition: memory.h:624
Pager pool base class for managed memory pools.
Definition: memory.h:824
A copy-on-write string class that operates by reference count.
Definition: string.h:78
DirPager dirlist_t
A convenience type for using DirPager directly.
Definition: memory.h:895
unsigned count(void) const
Get the number of items in the pager string list.
Definition: memory.h:459
StringPager & operator<<(const char *text)
Convenience operator to add to pager.
Definition: memory.h:563
A common string class and character string support functions.
unsigned pages(void) const
Get the number of pages that have been allocated from the real heap.
Definition: memory.h:106
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:468
Common locking protocol.
Definition: protocols.h:118
StringPager::member * begin(void) const
Get root of pager list.
Definition: memory.h:547
Convenience class for directories.
Definition: fsys.h:743
size_t size(void) const
Get the size of a memory page.
Definition: memory.h:125
T * operator *()
Create a managed object by pointer reference.
Definition: memory.h:877
A managed private heap for small allocations.
Definition: memory.h:184
A memory protocol pager for private heap manager.
Definition: memory.h:61
Various miscellaneous platform specific headers and defines.
Common namespace for all ucommon objects.
Definition: access.h:47
Directory pager is a paged string list for directory file names.
Definition: memory.h:653
unsigned max(void) const
Get the maximum number of pages that are permitted.
Definition: memory.h:117
T copy(const T &src)
Convenience function to copy objects.
Definition: generics.h:395
Abstract interfaces and support.
StringPager stringlist_t
A convenience type for paged string lists.
Definition: memory.h:885
T * operator()(void)
Create a managed object by casting reference.
Definition: memory.h:869
const char * get(unsigned item) const
Get string item from list.
A redirection base class for the memory protocol.
Definition: protocols.h:100
This is a base class for objects that may be created in pager pools.
Definition: memory.h:783
A smart pointer template for iterating linked lists.
Definition: linked.h:991
void operator+=(const char *text)
Convenience operator to add to pager and auto-sort.
Definition: memory.h:555
StringPager::member stringlistitem_t
A convenience type for paged string list items.
Definition: memory.h:890
Common base class for all objects that can be formed into a linked list.
Definition: linked.h:55
A base class for reference counted objects.
Definition: object.h:56
const char * operator[](unsigned item) const
Return specified filename from directory list.
Definition: memory.h:706
Member of string list.
Definition: memory.h:423