ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/include/common/memory.h
Revision: 1.2
Committed: Wed Aug 29 21:01:18 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +26 -0 lines
Log Message:
- reduced ifdefs by moving __GNUC__ and friends to svsconfig.h
- #define to enum { } in tools.h
- corrected log levels a bit
- made timersub an inline function instead of a macro
- added a simple garbage collection mechanism for postponed freeing of lost
  memory chunks
- enhanced type_traits
- merged inspircd1.2 support with upstream
- reformatting
- renamed TTP to a more "standard" PRItime and STP to PRIsize

File Contents

# User Rev Content
1 pippijn 1.1 /**
2     * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
3     * Rights to this code are documented in doc/pod/gplicense.pod.
4     *
5     * Memory templates.
6     */
7    
8     #ifndef ERMYTH_MEMORY_H
9     #define ERMYTH_MEMORY_H
10    
11 pippijn 1.2 #include <vector>
12    
13     #include <ermyth/type_traits.h>
14    
15 pippijn 1.1 namespace impl
16     {
17     inline void *
18     smalloc (unsigned n) throw (std::bad_alloc)
19     {
20     void *ptr = malloc (n);
21    
22     if (!ptr)
23     throw std::bad_alloc ();
24    
25     return ptr;
26     }
27    
28     inline void *
29     smalloc (unsigned n, void *src) throw (std::bad_alloc)
30     {
31     void *ptr = smalloc (n);
32    
33     if (src)
34     memcpy (ptr, src, n);
35     else
36     memset (ptr, 0, n);
37    
38     return ptr;
39     }
40    
41     // safe and slow version of above: never tries to copy more than len from src
42     inline void *
43     smalloc (unsigned n, void *src, size_t len) throw (std::bad_alloc)
44     {
45     size_t max = n >= len ? n : len;
46     void *ptr = smalloc (max);
47    
48     if (src)
49     {
50     memcpy (ptr, src, len);
51     memset (((char *)(ptr)) + len, 0, max - len); // XXX: hack to allow pointer arithmetic
52     }
53     else
54     memset (ptr, 0, max);
55    
56     return ptr;
57     }
58     }
59    
60     template<typename T>
61     inline T *
62     alloc (int n = 1) throw (std::bad_alloc)
63     {
64     return (T *) impl::smalloc (n * sizeof (T));
65     }
66    
67     template<typename T>
68     inline T *
69     alloc (unsigned n, T *src) throw (std::bad_alloc)
70     {
71     return (T *) impl::smalloc (n * sizeof (T), src);
72     }
73    
74     // template counterpart of the safe copying allocator
75     template<typename T>
76     inline T *
77     alloc (unsigned n, T *src, size_t len) throw (std::bad_alloc)
78     {
79     return (T *) impl::smalloc (n * sizeof (T), src, len);
80     }
81    
82     template<typename T>
83     inline T *
84     alloc (unsigned n, char c) throw (std::bad_alloc)
85     {
86     T *ptr = (T *) impl::smalloc (n * sizeof (T));
87     return memset (ptr, c, n * sizeof (T));
88     }
89    
90     template<typename T>
91     inline void
92     sfree (T *ptr) throw ()
93     {
94     free (ptr);
95     }
96    
97     // makes dynamically allocated objects zero-initialised
98     struct zero_initialised
99     {
100     void *operator new (size_t s)
101     {
102     void *p = impl::smalloc (s);
103     memset (p, 0, s);
104     return p;
105     }
106    
107     void *operator new[] (size_t s)
108     {
109     void *p = impl::smalloc (s);
110     memset (p, 0, s);
111     return p;
112     }
113    
114     void operator delete (void *p, size_t s)
115     {
116     free (p);
117     }
118    
119     void operator delete[] (void *p, size_t s)
120     {
121     free (p);
122     }
123     };
124    
125     E char *sstrdup (char const * const s);
126     E char *sstrndup (char const * const s, int len);
127    
128     template<size_t N>
129     inline char *
130     sstrndup (char const (&s)[N])
131     {
132     return sstrndup (s, N);
133     }
134    
135 pippijn 1.2 struct garbage_collector
136     {
137     void insert (void *p)
138     {
139     mortals.push_back (p);
140     }
141    
142     void collect ()
143     {
144     while (!mortals.empty ())
145     {
146     sfree (mortals.back ());
147     mortals.pop_back ();
148     }
149     }
150    
151     private:
152     std::vector<void *> mortals;
153     };
154    
155     E garbage_collector gc;
156    
157 pippijn 1.1 #endif