shmalloc.hxx

Go to the documentation of this file.
00001 /*
00002  *   xyzzy
00003  *   Copyright (C) 2007    Karl W. Pfalzer
00004  *
00005  *   This program is free software; you can redistribute it and/or
00006  *   modify it under the terms of the GNU General Public License
00007  *   as published by the Free Software Foundation; either version 2
00008  *   of the License, or (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the
00017  *   Free Software Foundation, Inc.
00018  *   51 Franklin Street, Fifth Floor
00019  *   Boston, MA  02110-1301, USA.
00020  */
00021 
00022 #if !defined(_xyzzy_shmalloc_hxx_)
00023 #    define  _xyzzy_shmalloc_hxx_
00024 
00025 #include <cstdlib>  //ptrdiff_t
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     // key is form "/name" (as in shm_open)
00040     explicit TShmAlloc(const char *key, size_t size, bool create = true);
00041 
00042     // keyAndSize is string: "key,size"
00043     explicit TShmAlloc(const char *keyAndSize, bool create = true);
00044 
00045     // Return pointer (offset) to alloc requested chunk.
00046     ptrdiff_t alloc(size_t);
00047 
00048     // Return pointer: base + offset
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     //const T& operator[](TUint32 ix) const {return at(ix);}
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);    //can't reallocate
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_

Generated on Thu Mar 22 13:51:08 2007 for anvil by  doxygen 1.5.1