00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if !defined(_xyzzy_shmalloc_hxx_)
00023 # define _xyzzy_shmalloc_hxx_
00024
00025 #include <cstdlib>
00026 #include <string>
00027 #include "xyzzy/assert.hxx"
00028 #include "xyzzy/portable.hxx"
00029
00030 namespace xyzzy
00031 {
00032
00036 class TShmAlloc
00037 {
00038 public:
00039
00040 explicit TShmAlloc(const char *key, size_t size, bool create = true);
00041
00042
00043 explicit TShmAlloc(const char *keyAndSize, bool create = true);
00044
00045
00046 ptrdiff_t alloc(size_t);
00047
00048
00049 void* ptr(ptrdiff_t offset) const
00050 {
00051 return (TUint8*)m_shmBase + offset;
00052 }
00053
00054 void* base() const { return m_shmBase; }
00055
00056 static TShmAlloc* theOne() { return m_stTheOne; }
00057
00058 void destroy();
00059
00060 const char* getKey() const {return m_key.c_str();}
00061
00062 size_t getMaxSize() const {return m_maxSize;}
00063
00064 ~TShmAlloc() {destroy();}
00065
00066 private:
00067 int m_schmid;
00068 void *m_shmBase;
00069 size_t m_maxSize;
00070 size_t m_used;
00071
00072 std::string m_key;
00073
00074 static TShmAlloc *m_stTheOne;
00075
00076 void init(const char *key, size_t size, bool create);
00077 };
00078
00079 namespace shm
00080 {
00081 inline
00082 ptrdiff_t alloc(size_t sz)
00083 {
00084 return TShmAlloc::theOne()->alloc(sz);
00085 }
00086
00087 inline
00088 void* allocp(size_t sz)
00089 {
00090 return TShmAlloc::theOne()->ptr(alloc(sz));
00091 }
00092
00093 inline
00094 ptrdiff_t offset(void* p)
00095 {
00096 return reinterpret_cast<TUint8*>(p) -
00097 reinterpret_cast<TUint8*>(TShmAlloc::theOne()->base());
00098 }
00099
00100 inline
00101 void destroy()
00102 {
00103 TShmAlloc::theOne()->destroy();
00104 }
00105
00106 inline
00107 const char* getKey()
00108 {
00109 return TShmAlloc::theOne()->getKey();
00110 }
00111
00112 inline
00113 size_t getMaxSize()
00114 {
00115 return TShmAlloc::theOne()->getMaxSize();
00116 }
00117
00118 };
00119
00120 template<typename T, typename Alloc>
00121 T
00122 castTo(ptrdiff_t offset)
00123 {
00124 return reinterpret_cast<T>(Alloc::theOne()->ptr(offset));
00125 }
00126
00127 template<typename T, typename Alloc = TShmAlloc>
00128 class PTShmObj
00129 {
00130 public:
00131 explicit PTShmObj()
00132 : m_offset(0)
00133 {}
00134
00135 PTShmObj(T p)
00136 : m_offset(shm::offset(p))
00137 {}
00138
00139 PTShmObj(ptrdiff_t offset)
00140 : m_offset(offset)
00141 {}
00142
00143 const PTShmObj& operator=(ptrdiff_t offset)
00144 {
00145 const_cast<ptrdiff_t&>(m_offset) = offset;
00146 return *this;
00147 }
00148
00149 const PTShmObj& operator=(const PTShmObj &r)
00150 {
00151 const_cast<ptrdiff_t&>(m_offset) = r.m_offset;
00152 return *this;
00153 }
00154
00155 T operator()()
00156 {
00157 return castTo<T, Alloc>(m_offset);
00158 }
00159
00160 const T operator()() const
00161 {
00162 return castTo<T, Alloc>(m_offset);
00163 }
00164
00165 operator T() { return operator()(); }
00166
00167 operator const T() const { return operator()(); }
00168
00169 private:
00170 const ptrdiff_t m_offset;
00171 };
00172
00173 template<typename T, typename Alloc = TShmAlloc>
00174 class PTShmObjAr
00175 {
00176 public:
00177 explicit PTShmObjAr(TUint32 num = 0)
00178 : m_numObjs(0)
00179 {
00180 init(num);
00181 }
00182
00183 const PTShmObjAr& operator=(TUint32 num)
00184 {
00185 init(num);
00186 return *this;
00187 }
00188
00189 TUint32 length() const {return m_numObjs;}
00190
00191 T& operator[](TUint32 ix) {return at(ix);}
00192
00193
00194
00195 private:
00196 TUint32 m_numObjs;
00197 PTShmObj<T*> m_pobjsAr;
00198
00199 void init(TUint32 num)
00200 {
00201 ASSERT_TRUE(0 == m_numObjs);
00202 if (0 == num)
00203 return;
00204 m_numObjs = num;
00205 m_pobjsAr = shm::alloc(sizeof(T) * m_numObjs);
00206 }
00207
00208 T& at(TUint32 ix)
00209 {
00210 ASSERT_TRUE(m_numObjs > ix);
00211 T *arv = m_pobjsAr();
00212 return arv[ix];
00213 }
00214 };
00215
00216 };
00217
00218 #endif //_xyzzy_shmalloc_hxx_