ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

_pthread_alloc.h
Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (c) 1994
00004  * Hewlett-Packard Company
00005  *
00006  * Copyright (c) 1996,1997
00007  * Silicon Graphics Computer Systems, Inc.
00008  *
00009  * Copyright (c) 1997
00010  * Moscow Center for SPARC Technology
00011  *
00012  * Copyright (c) 1999
00013  * Boris Fomitchev
00014  *
00015  * This material is provided "as is", with absolutely no warranty expressed
00016  * or implied. Any use is at your own risk.
00017  *
00018  * Permission to use or copy this software for any purpose is hereby granted
00019  * without fee, provided the above notices are retained on all copies.
00020  * Permission to modify the code and to distribute modified code is granted,
00021  * provided the above notices are retained, and a notice that the code was
00022  * modified is included with the above copyright notice.
00023  *
00024  */
00025 
00026 #ifndef _STLP_PTHREAD_ALLOC_H
00027 #define _STLP_PTHREAD_ALLOC_H
00028 
00029 /*
00030  * Pthread-specific node allocator.
00031  * This is similar to the default allocator, except that free-list
00032  * information is kept separately for each thread, avoiding locking.
00033  * This should be reasonably fast even in the presence of threads.
00034  * The down side is that storage may not be well-utilized.
00035  * It is not an error to allocate memory in thread A and deallocate
00036  * it in thread B.  But this effectively transfers ownership of the memory,
00037  * so that it can only be reallocated by thread B.  Thus this can effectively
00038  * result in a storage leak if it's done on a regular basis.
00039  * It can also result in frequent sharing of
00040  * cache lines among processors, with potentially serious performance
00041  * consequences.
00042  */
00043 
00044 #if !defined (_STLP_PTHREADS)
00045 #  error POSIX specific allocator implementation. Your system do not seems to \
00046 have this interface so please comment the _STLP_USE_PERTHREAD_ALLOC macro \
00047 or report to the STLport forum.
00048 #endif
00049 
00050 #if defined (_STLP_USE_NO_IOSTREAMS)
00051 #  error You cannot use per thread allocator implementation without building \
00052 STLport libraries.
00053 #endif
00054 
00055 #ifndef _STLP_INTERNAL_ALLOC_H
00056 #  include <stl/_alloc.h>
00057 #endif
00058 
00059 _STLP_BEGIN_NAMESPACE
00060 
00061 _STLP_MOVE_TO_PRIV_NAMESPACE
00062 
00063 struct _Pthread_alloc_per_thread_state;
00064 
00065 // Pthread-specific allocator.
00066 class _STLP_CLASS_DECLSPEC _Pthread_alloc {
00067 public: // but only for internal use:
00068   typedef _Pthread_alloc_per_thread_state __state_type;
00069   typedef char value_type;
00070 
00071 public:
00072   // Return a recycled or new per thread state.
00073   static __state_type * _STLP_CALL _S_get_per_thread_state();
00074 
00075   /* n must be > 0      */
00076   static void * _STLP_CALL allocate(size_t& __n);
00077 
00078   /* p may not be 0 */
00079   static void _STLP_CALL deallocate(void *__p, size_t __n);
00080 
00081   // boris : versions for per_thread_allocator
00082   /* n must be > 0      */
00083   static void * _STLP_CALL allocate(size_t& __n, __state_type* __a);
00084 
00085   /* p may not be 0 */
00086   static void _STLP_CALL deallocate(void *__p, size_t __n, __state_type* __a);
00087 
00088   static void * _STLP_CALL reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
00089 };
00090 
00091 _STLP_MOVE_TO_STD_NAMESPACE
00092 
00093 typedef _STLP_PRIV _Pthread_alloc __pthread_alloc;
00094 typedef __pthread_alloc pthread_alloc;
00095 
00096 template <class _Tp>
00097 class pthread_allocator : public __stlport_class<pthread_allocator<_Tp> > {
00098   typedef pthread_alloc _S_Alloc;          // The underlying allocator.
00099 public:
00100   typedef size_t     size_type;
00101   typedef ptrdiff_t  difference_type;
00102   typedef _Tp*       pointer;
00103   typedef const _Tp* const_pointer;
00104   typedef _Tp&       reference;
00105   typedef const _Tp& const_reference;
00106   typedef _Tp        value_type;
00107 
00108 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00109   template <class _NewType> struct rebind {
00110     typedef pthread_allocator<_NewType> other;
00111   };
00112 #endif
00113 
00114   pthread_allocator() _STLP_NOTHROW {}
00115   pthread_allocator(const pthread_allocator<_Tp>& a) _STLP_NOTHROW {}
00116 
00117 #if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
00118   template <class _OtherType> pthread_allocator(const pthread_allocator<_OtherType>&)
00119     _STLP_NOTHROW {}
00120 #endif
00121 
00122   ~pthread_allocator() _STLP_NOTHROW {}
00123 
00124   pointer address(reference __x) const { return &__x; }
00125   const_pointer address(const_reference __x) const { return &__x; }
00126 
00127   // __n is permitted to be 0.  The C++ standard says nothing about what
00128   // the return value is when __n == 0.
00129   _Tp* allocate(size_type __n, const void* = 0) {
00130     if (__n > max_size()) {
00131       _STLP_THROW_BAD_ALLOC;
00132     }
00133     if (__n != 0) {
00134       size_type __buf_size = __n * sizeof(value_type);
00135       _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
00136 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00137       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00138 #endif
00139       return __ret;
00140     }
00141     else
00142       return 0;
00143   }
00144 
00145   void deallocate(pointer __p, size_type __n) {
00146     _STLP_ASSERT( (__p == 0) == (__n == 0) )
00147     if (__p != 0) {
00148 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00149       memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
00150 #endif
00151       _S_Alloc::deallocate(__p, __n * sizeof(value_type));
00152     }
00153   }
00154 
00155   size_type max_size() const _STLP_NOTHROW
00156   { return size_t(-1) / sizeof(_Tp); }
00157 
00158   void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
00159   void destroy(pointer _p) { _p->~_Tp(); }
00160 
00161 #if defined (_STLP_NO_EXTENSIONS)
00162   /* STLport extension giving rounded size of an allocated memory buffer
00163    * This method do not have to be part of a user defined allocator implementation
00164    * and won't even be called if such a function was granted.
00165    */
00166 protected:
00167 #endif
00168   _Tp* allocate(size_type __n, size_type& __allocated_n) {
00169     if (__n > max_size()) {
00170       _STLP_THROW_BAD_ALLOC;
00171     }
00172     if (__n != 0) {
00173       size_type __buf_size = __n * sizeof(value_type);
00174       _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
00175 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00176       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00177 #endif
00178       __allocated_n = __buf_size / sizeof(value_type);
00179       return __ret;
00180     }
00181     else
00182       return 0;
00183   }
00184 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
00185   void _M_swap_workaround(pthread_allocator<_Tp>& __x) {}
00186 #endif
00187 };
00188 
00189 _STLP_TEMPLATE_NULL
00190 class _STLP_CLASS_DECLSPEC pthread_allocator<void> {
00191 public:
00192   typedef size_t      size_type;
00193   typedef ptrdiff_t   difference_type;
00194   typedef void*       pointer;
00195   typedef const void* const_pointer;
00196   typedef void        value_type;
00197 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00198   template <class _NewType> struct rebind {
00199     typedef pthread_allocator<_NewType> other;
00200   };
00201 #endif
00202 };
00203 
00204 template <class _T1, class _T2>
00205 inline bool operator==(const pthread_allocator<_T1>&,
00206                        const pthread_allocator<_T2>& a2)
00207 { return true; }
00208 
00209 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
00210 template <class _T1, class _T2>
00211 inline bool operator!=(const pthread_allocator<_T1>&,
00212                        const pthread_allocator<_T2>&)
00213 { return false; }
00214 #endif
00215 
00216 
00217 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00218 
00219 template <class _Tp, class _Atype>
00220 struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
00221 { typedef pthread_allocator<_Tp> allocator_type; };
00222 
00223 #endif
00224 
00225 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
00226 
00227 template <class _Tp1, class _Tp2>
00228 inline pthread_allocator<_Tp2>&
00229 __stl_alloc_rebind(pthread_allocator<_Tp1>& __x, const _Tp2*)
00230 { return (pthread_allocator<_Tp2>&)__x; }
00231 
00232 template <class _Tp1, class _Tp2>
00233 inline pthread_allocator<_Tp2>
00234 __stl_alloc_create(pthread_allocator<_Tp1>&, const _Tp2*)
00235 { return pthread_allocator<_Tp2>(); }
00236 
00237 #endif
00238 
00239 _STLP_MOVE_TO_PRIV_NAMESPACE
00240 
00241 template <class _Tp>
00242 struct __pthread_alloc_type_traits {
00243   typedef typename _IsSTLportClass<pthread_allocator<_Tp> >::_Ret _STLportAlloc;
00244   //The default allocator implementation which is recognize thanks to the
00245   //__stlport_class inheritance is a stateless object so:
00246   typedef _STLportAlloc has_trivial_default_constructor;
00247   typedef _STLportAlloc has_trivial_copy_constructor;
00248   typedef _STLportAlloc has_trivial_assignment_operator;
00249   typedef _STLportAlloc has_trivial_destructor;
00250   typedef _STLportAlloc is_POD_type;
00251 };
00252 
00253 _STLP_MOVE_TO_STD_NAMESPACE
00254 
00255 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00256 template <class _Tp>
00257 struct __type_traits<pthread_allocator<_Tp> > : _STLP_PRIV __pthread_alloc_type_traits<_Tp> {};
00258 #else
00259 _STLP_TEMPLATE_NULL
00260 struct __type_traits<pthread_allocator<char> > : _STLP_PRIV __pthread_alloc_type_traits<char> {};
00261 #  if defined (_STLP_HAS_WCHAR_T)
00262 _STLP_TEMPLATE_NULL
00263 struct __type_traits<pthread_allocator<wchar_t> > : _STLP_PRIV __pthread_alloc_type_traits<wchar_t> {};
00264 #  endif
00265 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00266 _STLP_TEMPLATE_NULL
00267 struct __type_traits<pthread_allocator<void*> > : _STLP_PRIV __pthread_alloc_type_traits<void*> {};
00268 #  endif
00269 #endif
00270 
00271 //
00272 // per_thread_allocator<> : this allocator always return memory to the same thread
00273 // it was allocated from.
00274 //
00275 
00276 template <class _Tp>
00277 class per_thread_allocator {
00278   typedef pthread_alloc _S_Alloc;          // The underlying allocator.
00279   typedef pthread_alloc::__state_type __state_type;
00280 public:
00281   typedef size_t     size_type;
00282   typedef ptrdiff_t  difference_type;
00283   typedef _Tp*       pointer;
00284   typedef const _Tp* const_pointer;
00285   typedef _Tp&       reference;
00286   typedef const _Tp& const_reference;
00287   typedef _Tp        value_type;
00288 
00289 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00290   template <class _NewType> struct rebind {
00291     typedef per_thread_allocator<_NewType> other;
00292   };
00293 #endif
00294 
00295   per_thread_allocator() _STLP_NOTHROW {
00296     _M_state = _S_Alloc::_S_get_per_thread_state();
00297   }
00298   per_thread_allocator(const per_thread_allocator<_Tp>& __a) _STLP_NOTHROW : _M_state(__a._M_state){}
00299 
00300 #if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
00301   template <class _OtherType> per_thread_allocator(const per_thread_allocator<_OtherType>& __a)
00302     _STLP_NOTHROW : _M_state(__a._M_state) {}
00303 #endif
00304 
00305   ~per_thread_allocator() _STLP_NOTHROW {}
00306 
00307   pointer address(reference __x) const { return &__x; }
00308   const_pointer address(const_reference __x) const { return &__x; }
00309 
00310   // __n is permitted to be 0.  The C++ standard says nothing about what
00311   // the return value is when __n == 0.
00312   _Tp* allocate(size_type __n, const void* = 0) {
00313     if (__n > max_size()) {
00314       _STLP_THROW_BAD_ALLOC;
00315     }
00316     if (__n != 0) {
00317       size_type __buf_size = __n * sizeof(value_type);
00318       _Tp* __ret = __REINTERPRET_CAST(_Tp*, _S_Alloc::allocate(__buf_size, _M_state));
00319 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00320       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00321 #endif
00322       return __ret;
00323     }
00324     else
00325       return 0;
00326   }
00327 
00328   void deallocate(pointer __p, size_type __n) {
00329     _STLP_ASSERT( (__p == 0) == (__n == 0) )
00330     if (__p != 0) {
00331 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00332       memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
00333 #endif
00334       _S_Alloc::deallocate(__p, __n * sizeof(value_type), _M_state);
00335     }
00336   }
00337 
00338   size_type max_size() const _STLP_NOTHROW
00339   { return size_t(-1) / sizeof(_Tp); }
00340 
00341   void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
00342   void destroy(pointer _p) { _p->~_Tp(); }
00343 
00344   // state is being kept here
00345   __state_type* _M_state;
00346 
00347 #if defined (_STLP_NO_EXTENSIONS)
00348   /* STLport extension giving rounded size of an allocated memory buffer
00349    * This method do not have to be part of a user defined allocator implementation
00350    * and won't even be called if such a function was granted.
00351    */
00352 protected:
00353 #endif
00354   _Tp* allocate(size_type __n, size_type& __allocated_n) {
00355     if (__n > max_size()) {
00356       _STLP_THROW_BAD_ALLOC;
00357     }
00358     if (__n != 0) {
00359       size_type __buf_size = __n * sizeof(value_type);
00360       _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size, _M_state));
00361 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
00362       memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
00363 #endif
00364       __allocated_n = __buf_size / sizeof(value_type);
00365       return __ret;
00366     }
00367     else
00368       return 0;
00369   }
00370 };
00371 
00372 _STLP_TEMPLATE_NULL
00373 class _STLP_CLASS_DECLSPEC per_thread_allocator<void> {
00374 public:
00375   typedef size_t      size_type;
00376   typedef ptrdiff_t   difference_type;
00377   typedef void*       pointer;
00378   typedef const void* const_pointer;
00379   typedef void        value_type;
00380 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
00381   template <class _NewType> struct rebind {
00382     typedef per_thread_allocator<_NewType> other;
00383   };
00384 #endif
00385 };
00386 
00387 template <class _T1, class _T2>
00388 inline bool operator==(const per_thread_allocator<_T1>& __a1,
00389                        const per_thread_allocator<_T2>& __a2)
00390 { return __a1._M_state == __a2._M_state; }
00391 
00392 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
00393 template <class _T1, class _T2>
00394 inline bool operator!=(const per_thread_allocator<_T1>& __a1,
00395                        const per_thread_allocator<_T2>& __a2)
00396 { return __a1._M_state != __a2._M_state; }
00397 #endif
00398 
00399 
00400 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00401 
00402 template <class _Tp, class _Atype>
00403 struct _Alloc_traits<_Tp, per_thread_allocator<_Atype> >
00404 { typedef per_thread_allocator<_Tp> allocator_type; };
00405 
00406 #endif
00407 
00408 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
00409 
00410 template <class _Tp1, class _Tp2>
00411 inline per_thread_allocator<_Tp2>&
00412 __stl_alloc_rebind(per_thread_allocator<_Tp1>& __x, const _Tp2*)
00413 { return (per_thread_allocator<_Tp2>&)__x; }
00414 
00415 template <class _Tp1, class _Tp2>
00416 inline per_thread_allocator<_Tp2>
00417 __stl_alloc_create(per_thread_allocator<_Tp1>&, const _Tp2*)
00418 { return per_thread_allocator<_Tp2>(); }
00419 
00420 #endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
00421 
00422 _STLP_MOVE_TO_PRIV_NAMESPACE
00423 
00424 template <class _Tp>
00425 struct __perthread_alloc_type_traits {
00426   typedef typename _IsSTLportClass<per_thread_allocator<_Tp> >::_Ret _STLportAlloc;
00427   //The default allocator implementation which is recognize thanks to the
00428   //__stlport_class inheritance is a stateless object so:
00429   typedef __false_type has_trivial_default_constructor;
00430   typedef _STLportAlloc has_trivial_copy_constructor;
00431   typedef _STLportAlloc has_trivial_assignment_operator;
00432   typedef _STLportAlloc has_trivial_destructor;
00433   typedef __false_type is_POD_type;
00434 };
00435 
00436 _STLP_MOVE_TO_STD_NAMESPACE
00437 
00438 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
00439 template <class _Tp>
00440 struct __type_traits<per_thread_allocator<_Tp> > : _STLP_PRIV __perthread_alloc_type_traits<_Tp> {};
00441 #else
00442 _STLP_TEMPLATE_NULL
00443 struct __type_traits<per_thread_allocator<char> > : _STLP_PRIV __perthread_alloc_type_traits<char> {};
00444 #  if defined (_STLP_HAS_WCHAR_T)
00445 _STLP_TEMPLATE_NULL
00446 struct __type_traits<per_thread_allocator<wchar_t> > : _STLP_PRIV __perthread_alloc_type_traits<wchar_t> {};
00447 #  endif
00448 #  if defined (_STLP_USE_PTR_SPECIALIZATIONS)
00449 _STLP_TEMPLATE_NULL
00450 struct __type_traits<per_thread_allocator<void*> > : _STLP_PRIV __perthread_alloc_type_traits<void*> {};
00451 #  endif
00452 #endif
00453 
00454 
00455 _STLP_END_NAMESPACE
00456 
00457 #endif /* _STLP_PTHREAD_ALLOC */
00458 
00459 // Local Variables:
00460 // mode:C++
00461 // End:

Generated on Fri May 25 2012 04:27:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.