ReactOS  0.4.13-dev-551-gf37fb1f
_pthread_alloc.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 1994
4  * Hewlett-Packard Company
5  *
6  * Copyright (c) 1996,1997
7  * Silicon Graphics Computer Systems, Inc.
8  *
9  * Copyright (c) 1997
10  * Moscow Center for SPARC Technology
11  *
12  * Copyright (c) 1999
13  * Boris Fomitchev
14  *
15  * This material is provided "as is", with absolutely no warranty expressed
16  * or implied. Any use is at your own risk.
17  *
18  * Permission to use or copy this software for any purpose is hereby granted
19  * without fee, provided the above notices are retained on all copies.
20  * Permission to modify the code and to distribute modified code is granted,
21  * provided the above notices are retained, and a notice that the code was
22  * modified is included with the above copyright notice.
23  *
24  */
25 
26 #ifndef _STLP_PTHREAD_ALLOC_H
27 #define _STLP_PTHREAD_ALLOC_H
28 
29 /*
30  * Pthread-specific node allocator.
31  * This is similar to the default allocator, except that free-list
32  * information is kept separately for each thread, avoiding locking.
33  * This should be reasonably fast even in the presence of threads.
34  * The down side is that storage may not be well-utilized.
35  * It is not an error to allocate memory in thread A and deallocate
36  * it in thread B. But this effectively transfers ownership of the memory,
37  * so that it can only be reallocated by thread B. Thus this can effectively
38  * result in a storage leak if it's done on a regular basis.
39  * It can also result in frequent sharing of
40  * cache lines among processors, with potentially serious performance
41  * consequences.
42  */
43 
44 #if !defined (_STLP_PTHREADS)
45 # error POSIX specific allocator implementation. Your system do not seems to \
46 have this interface so please comment the _STLP_USE_PERTHREAD_ALLOC macro \
47 or report to the STLport forum.
48 #endif
49 
50 #if defined (_STLP_USE_NO_IOSTREAMS)
51 # error You cannot use per thread allocator implementation without building \
52 STLport libraries.
53 #endif
54 
55 #ifndef _STLP_INTERNAL_ALLOC_H
56 # include <stl/_alloc.h>
57 #endif
58 
60 
62 
63 struct _Pthread_alloc_per_thread_state;
64 
65 // Pthread-specific allocator.
67 public: // but only for internal use:
68  typedef _Pthread_alloc_per_thread_state __state_type;
69  typedef char value_type;
70 
71 public:
72  // Return a recycled or new per thread state.
73  static __state_type * _STLP_CALL _S_get_per_thread_state();
74 
75  /* n must be > 0 */
76  static void * _STLP_CALL allocate(size_t& __n);
77 
78  /* p may not be 0 */
79  static void _STLP_CALL deallocate(void *__p, size_t __n);
80 
81  // boris : versions for per_thread_allocator
82  /* n must be > 0 */
83  static void * _STLP_CALL allocate(size_t& __n, __state_type* __a);
84 
85  /* p may not be 0 */
86  static void _STLP_CALL deallocate(void *__p, size_t __n, __state_type* __a);
87 
88  static void * _STLP_CALL reallocate(void *__p, size_t __old_sz, size_t& __new_sz);
89 };
90 
92 
95 
96 template <class _Tp>
97 class pthread_allocator : public __stlport_class<pthread_allocator<_Tp> > {
98  typedef pthread_alloc _S_Alloc; // The underlying allocator.
99 public:
100  typedef size_t size_type;
102  typedef _Tp* pointer;
103  typedef const _Tp* const_pointer;
104  typedef _Tp& reference;
105  typedef const _Tp& const_reference;
106  typedef _Tp value_type;
107 
108 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
109  template <class _NewType> struct rebind {
111  };
112 #endif
113 
116 
117 #if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
118  template <class _OtherType> pthread_allocator(const pthread_allocator<_OtherType>&)
119  _STLP_NOTHROW {}
120 #endif
121 
123 
124  pointer address(reference __x) const { return &__x; }
125  const_pointer address(const_reference __x) const { return &__x; }
126 
127  // __n is permitted to be 0. The C++ standard says nothing about what
128  // the return value is when __n == 0.
129  _Tp* allocate(size_type __n, const void* = 0) {
130  if (__n > max_size()) {
132  }
133  if (__n != 0) {
134  size_type __buf_size = __n * sizeof(value_type);
135  _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
136 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
137  memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
138 #endif
139  return __ret;
140  }
141  else
142  return 0;
143  }
144 
146  _STLP_ASSERT( (__p == 0) == (__n == 0) )
147  if (__p != 0) {
148 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
149  memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
150 #endif
151  _S_Alloc::deallocate(__p, __n * sizeof(value_type));
152  }
153  }
154 
156  { return size_t(-1) / sizeof(_Tp); }
157 
158  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
159  void destroy(pointer _p) { _p->~_Tp(); }
160 
161 #if defined (_STLP_NO_EXTENSIONS)
162  /* STLport extension giving rounded size of an allocated memory buffer
163  * This method do not have to be part of a user defined allocator implementation
164  * and won't even be called if such a function was granted.
165  */
166 protected:
167 #endif
168  _Tp* allocate(size_type __n, size_type& __allocated_n) {
169  if (__n > max_size()) {
171  }
172  if (__n != 0) {
173  size_type __buf_size = __n * sizeof(value_type);
174  _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size));
175 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
176  memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
177 #endif
178  __allocated_n = __buf_size / sizeof(value_type);
179  return __ret;
180  }
181  else
182  return 0;
183  }
184 #if defined (_STLP_USE_PARTIAL_SPEC_WORKAROUND) && !defined (_STLP_FUNCTION_TMPL_PARTIAL_ORDER)
185  void _M_swap_workaround(pthread_allocator<_Tp>& __x) {}
186 #endif
187 };
188 
191 public:
192  typedef size_t size_type;
194  typedef void* pointer;
195  typedef const void* const_pointer;
196  typedef void value_type;
197 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
198  template <class _NewType> struct rebind {
200  };
201 #endif
202 };
203 
204 template <class _T1, class _T2>
206  const pthread_allocator<_T2>& a2)
207 { return true; }
208 
209 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
210 template <class _T1, class _T2>
211 inline bool operator!=(const pthread_allocator<_T1>&,
212  const pthread_allocator<_T2>&)
213 { return false; }
214 #endif
215 
216 
217 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
218 
219 template <class _Tp, class _Atype>
220 struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
222 
223 #endif
224 
225 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
226 
227 template <class _Tp1, class _Tp2>
230 { return (pthread_allocator<_Tp2>&)__x; }
231 
232 template <class _Tp1, class _Tp2>
235 { return pthread_allocator<_Tp2>(); }
236 
237 #endif
238 
240 
241 template <class _Tp>
244  //The default allocator implementation which is recognize thanks to the
245  //__stlport_class inheritance is a stateless object so:
251 };
252 
254 
255 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
256 template <class _Tp>
258 #else
261 # if defined (_STLP_HAS_WCHAR_T)
264 # endif
265 # if defined (_STLP_USE_PTR_SPECIALIZATIONS)
268 # endif
269 #endif
270 
271 //
272 // per_thread_allocator<> : this allocator always return memory to the same thread
273 // it was allocated from.
274 //
275 
276 template <class _Tp>
278  typedef pthread_alloc _S_Alloc; // The underlying allocator.
279  typedef pthread_alloc::__state_type __state_type;
280 public:
281  typedef size_t size_type;
283  typedef _Tp* pointer;
284  typedef const _Tp* const_pointer;
285  typedef _Tp& reference;
286  typedef const _Tp& const_reference;
287  typedef _Tp value_type;
288 
289 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
290  template <class _NewType> struct rebind {
292  };
293 #endif
294 
296  _M_state = _S_Alloc::_S_get_per_thread_state();
297  }
299 
300 #if defined (_STLP_MEMBER_TEMPLATES) /* && defined (_STLP_FUNCTION_PARTIAL_ORDER) */
301  template <class _OtherType> per_thread_allocator(const per_thread_allocator<_OtherType>& __a)
302  _STLP_NOTHROW : _M_state(__a._M_state) {}
303 #endif
304 
306 
307  pointer address(reference __x) const { return &__x; }
308  const_pointer address(const_reference __x) const { return &__x; }
309 
310  // __n is permitted to be 0. The C++ standard says nothing about what
311  // the return value is when __n == 0.
312  _Tp* allocate(size_type __n, const void* = 0) {
313  if (__n > max_size()) {
315  }
316  if (__n != 0) {
317  size_type __buf_size = __n * sizeof(value_type);
318  _Tp* __ret = __REINTERPRET_CAST(_Tp*, _S_Alloc::allocate(__buf_size, _M_state));
319 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
320  memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
321 #endif
322  return __ret;
323  }
324  else
325  return 0;
326  }
327 
329  _STLP_ASSERT( (__p == 0) == (__n == 0) )
330  if (__p != 0) {
331 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
332  memset((char*)__p, _STLP_SHRED_BYTE, __n * sizeof(value_type));
333 #endif
334  _S_Alloc::deallocate(__p, __n * sizeof(value_type), _M_state);
335  }
336  }
337 
339  { return size_t(-1) / sizeof(_Tp); }
340 
341  void construct(pointer __p, const _Tp& __val) { new(__p) _Tp(__val); }
342  void destroy(pointer _p) { _p->~_Tp(); }
343 
344  // state is being kept here
346 
347 #if defined (_STLP_NO_EXTENSIONS)
348  /* STLport extension giving rounded size of an allocated memory buffer
349  * This method do not have to be part of a user defined allocator implementation
350  * and won't even be called if such a function was granted.
351  */
352 protected:
353 #endif
354  _Tp* allocate(size_type __n, size_type& __allocated_n) {
355  if (__n > max_size()) {
357  }
358  if (__n != 0) {
359  size_type __buf_size = __n * sizeof(value_type);
360  _Tp* __ret = __REINTERPRET_CAST(value_type*, _S_Alloc::allocate(__buf_size, _M_state));
361 #if defined (_STLP_DEBUG_UNINITIALIZED) && !defined (_STLP_DEBUG_ALLOC)
362  memset((char*)__ret, _STLP_SHRED_BYTE, __buf_size);
363 #endif
364  __allocated_n = __buf_size / sizeof(value_type);
365  return __ret;
366  }
367  else
368  return 0;
369  }
370 };
371 
374 public:
375  typedef size_t size_type;
377  typedef void* pointer;
378  typedef const void* const_pointer;
379  typedef void value_type;
380 #ifdef _STLP_MEMBER_TEMPLATE_CLASSES
381  template <class _NewType> struct rebind {
383  };
384 #endif
385 };
386 
387 template <class _T1, class _T2>
388 inline bool operator==(const per_thread_allocator<_T1>& __a1,
389  const per_thread_allocator<_T2>& __a2)
390 { return __a1._M_state == __a2._M_state; }
391 
392 #ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
393 template <class _T1, class _T2>
394 inline bool operator!=(const per_thread_allocator<_T1>& __a1,
395  const per_thread_allocator<_T2>& __a2)
396 { return __a1._M_state != __a2._M_state; }
397 #endif
398 
399 
400 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
401 
402 template <class _Tp, class _Atype>
403 struct _Alloc_traits<_Tp, per_thread_allocator<_Atype> >
405 
406 #endif
407 
408 #if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
409 
410 template <class _Tp1, class _Tp2>
413 { return (per_thread_allocator<_Tp2>&)__x; }
414 
415 template <class _Tp1, class _Tp2>
418 { return per_thread_allocator<_Tp2>(); }
419 
420 #endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
421 
423 
424 template <class _Tp>
427  //The default allocator implementation which is recognize thanks to the
428  //__stlport_class inheritance is a stateless object so:
434 };
435 
437 
438 #if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
439 template <class _Tp>
441 #else
444 # if defined (_STLP_HAS_WCHAR_T)
447 # endif
448 # if defined (_STLP_USE_PTR_SPECIALIZATIONS)
451 # endif
452 #endif
453 
454 
456 
457 #endif /* _STLP_PTHREAD_ALLOC */
458 
459 // Local Variables:
460 // mode:C++
461 // End:
pointer address(reference __x) const
bool operator==(const pthread_allocator< _T1 > &, const pthread_allocator< _T2 > &a2)
bool _STLP_CALL operator!=(const allocator< _T1 > &, const allocator< _T2 > &) _STLP_NOTHROW
Definition: _alloc.h:384
const _Tp * const_pointer
allocator< _Tp2 > _STLP_CALL __stl_alloc_create(const allocator< _Tp1 > &, const _Tp2 *)
Definition: _alloc.h:465
return __n
Definition: _algo.h:75
const_pointer address(const_reference __x) const
per_thread_allocator() _STLP_NOTHROW
int other
Definition: msacm.c:1364
_STLportAlloc has_trivial_assignment_operator
_Tp * allocate(size_type __n, size_type &__allocated_n)
#define _STLP_MOVE_TO_PRIV_NAMESPACE
Definition: features.h:524
const _Tp & const_reference
_IsSTLportClass< pthread_allocator< _Tp > >::_Ret _STLportAlloc
pthread_alloc _S_Alloc
__state_type * _M_state
_Tp * allocate(size_type __n, const void *=0)
allocator< _Tp2 > &_STLP_CALL __stl_alloc_rebind(allocator< _Tp1 > &__a, const _Tp2 *)
Definition: _alloc.h:462
_STLportAlloc has_trivial_assignment_operator
void destroy(pointer _p)
_STLportAlloc has_trivial_default_constructor
unsigned char
Definition: typeof.h:29
~per_thread_allocator() _STLP_NOTHROW
void destroy(pointer _p)
pthread_alloc::__state_type __state_type
unsigned short wchar_t
Definition: crtdefs.h:324
_Tp * allocate(size_type __n, const void *=0)
__kernel_size_t size_t
Definition: linux.h:237
_Tp * allocate(size_type __n, size_type &__allocated_n)
#define _STLP_MOVE_TO_STD_NAMESPACE
Definition: features.h:525
_STLportAlloc has_trivial_copy_constructor
void construct(pointer __p, const _Tp &__val)
~pthread_allocator() _STLP_NOTHROW
_STLportAlloc has_trivial_copy_constructor
static const struct update_accum a2
Definition: msg.c:586
__pthread_alloc pthread_alloc
_STLP_INLINE_LOOP _InputIter const _Tp & __val
Definition: _algobase.h:656
ptrdiff_t difference_type
void construct(pointer __p, const _Tp &__val)
pthread_alloc _S_Alloc
#define _STLP_SHRED_BYTE
Definition: features.h:903
_Pthread_alloc_per_thread_state __state_type
#define _STLP_PRIV
Definition: _dm.h:70
_Rebind_type::other allocator_type
Definition: _alloc.h:201
#define _STLP_CLASS_DECLSPEC
Definition: features.h:983
#define __REINTERPRET_CAST(__x, __y)
Definition: features.h:586
#define _STLP_TEMPLATE_NULL
Definition: features.h:652
_IsSTLportClass< per_thread_allocator< _Tp > >::_Ret _STLportAlloc
const_pointer address(const_reference __x) const
per_thread_allocator(const per_thread_allocator< _Tp > &__a) _STLP_NOTHROW
const _Tp & const_reference
pthread_allocator(const pthread_allocator< _Tp > &a) _STLP_NOTHROW
const _Tp * const_pointer
#define _STLP_END_NAMESPACE
Definition: features.h:503
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define _STLP_ASSERT(expr)
Definition: _debug.h:165
_STLportAlloc has_trivial_destructor
#define const
Definition: zconf.h:230
pointer address(reference __x) const
pthread_allocator() _STLP_NOTHROW
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
size_type max_size() const _STLP_NOTHROW
#define _STLP_NOTHROW
Definition: _intel.h:35
__false_type has_trivial_default_constructor
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
size_type max_size() const _STLP_NOTHROW
#define memset(x, y, z)
Definition: compat.h:39
#define _STLP_CALL
Definition: _bc.h:131
#define _STLP_THROW_BAD_ALLOC
Definition: _new.h:116
void deallocate(pointer __p, size_type __n)
_STLP_MOVE_TO_STD_NAMESPACE typedef _STLP_PRIV _Pthread_alloc __pthread_alloc
void deallocate(pointer __p, size_type __n)