ReactOS 0.4.15-dev-8131-g4988de4
_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 \
46have this interface so please comment the _STLP_USE_PERTHREAD_ALLOC macro \
47or 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 \
52STLport libraries.
53#endif
54
55#ifndef _STLP_INTERNAL_ALLOC_H
56# include <stl/_alloc.h>
57#endif
58
60
62
63struct _Pthread_alloc_per_thread_state;
64
65// Pthread-specific allocator.
67public: // but only for internal use:
68 typedef _Pthread_alloc_per_thread_state __state_type;
69 typedef char value_type;
70
71public:
72 // Return a recycled or new 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
96template <class _Tp>
97class pthread_allocator : public __stlport_class<pthread_allocator<_Tp> > {
98 typedef pthread_alloc _S_Alloc; // The underlying allocator.
99public:
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>&)
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 */
166protected:
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
191public:
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
204template <class _T1, class _T2>
207{ return true; }
208
209#ifdef _STLP_FUNCTION_TMPL_PARTIAL_ORDER
210template <class _T1, class _T2>
211inline bool operator!=(const pthread_allocator<_T1>&,
213{ return false; }
214#endif
215
216
217#if defined (_STLP_CLASS_PARTIAL_SPECIALIZATION)
218
219template <class _Tp, class _Atype>
220struct _Alloc_traits<_Tp, pthread_allocator<_Atype> >
222
223#endif
224
225#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
226
227template <class _Tp1, class _Tp2>
230{ return (pthread_allocator<_Tp2>&)__x; }
231
232template <class _Tp1, class _Tp2>
235{ return pthread_allocator<_Tp2>(); }
236
237#endif
238
240
241template <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)
256template <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
276template <class _Tp>
278 typedef pthread_alloc _S_Alloc; // The underlying allocator.
279 typedef pthread_alloc::__state_type __state_type;
280public:
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 */
352protected:
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
374public:
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
387template <class _T1, class _T2>
388inline 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
393template <class _T1, class _T2>
394inline 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
402template <class _Tp, class _Atype>
403struct _Alloc_traits<_Tp, per_thread_allocator<_Atype> >
405
406#endif
407
408#if defined (_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE)
409
410template <class _Tp1, class _Tp2>
413{ return (per_thread_allocator<_Tp2>&)__x; }
414
415template <class _Tp1, class _Tp2>
418{ return per_thread_allocator<_Tp2>(); }
419
420#endif /* _STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE */
421
423
424template <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)
439template <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:
return __n
Definition: _algo.h:75
_STLP_INLINE_LOOP _InputIter const _Tp & __val
Definition: _algobase.h:656
allocator< _Tp2 > &_STLP_CALL __stl_alloc_rebind(allocator< _Tp1 > &__a, const _Tp2 *)
Definition: _alloc.h:462
bool _STLP_CALL operator!=(const allocator< _T1 > &, const allocator< _T2 > &) _STLP_NOTHROW
Definition: _alloc.h:384
allocator< _Tp2 > _STLP_CALL __stl_alloc_create(const allocator< _Tp1 > &, const _Tp2 *)
Definition: _alloc.h:465
#define _STLP_CALL
Definition: _bc.h:131
#define _STLP_ASSERT(expr)
Definition: _debug.h:165
#define _STLP_PRIV
Definition: _dm.h:70
#define _STLP_NOTHROW
Definition: _intel.h:35
#define _STLP_THROW_BAD_ALLOC
Definition: _new.h:116
__pthread_alloc pthread_alloc
bool operator==(const pthread_allocator< _T1 > &, const pthread_allocator< _T2 > &a2)
_STLP_MOVE_TO_STD_NAMESPACE typedef _STLP_PRIV _Pthread_alloc __pthread_alloc
static void *_STLP_CALL reallocate(void *__p, size_t __old_sz, size_t &__new_sz)
static __state_type *_STLP_CALL _S_get_per_thread_state()
static void _STLP_CALL deallocate(void *__p, size_t __n)
static void _STLP_CALL deallocate(void *__p, size_t __n, __state_type *__a)
_Pthread_alloc_per_thread_state __state_type
static void *_STLP_CALL allocate(size_t &__n, __state_type *__a)
static void *_STLP_CALL allocate(size_t &__n)
per_thread_allocator(const per_thread_allocator< _Tp > &__a) _STLP_NOTHROW
_Tp * allocate(size_type __n, const void *=0)
size_type max_size() const _STLP_NOTHROW
const _Tp & const_reference
void destroy(pointer _p)
pointer address(reference __x) const
~per_thread_allocator() _STLP_NOTHROW
void construct(pointer __p, const _Tp &__val)
const_pointer address(const_reference __x) const
const _Tp * const_pointer
per_thread_allocator() _STLP_NOTHROW
__state_type * _M_state
_Tp * allocate(size_type __n, size_type &__allocated_n)
pthread_alloc _S_Alloc
pthread_alloc::__state_type __state_type
void deallocate(pointer __p, size_type __n)
const _Tp * const_pointer
void construct(pointer __p, const _Tp &__val)
_Tp * allocate(size_type __n, const void *=0)
void deallocate(pointer __p, size_type __n)
const _Tp & const_reference
pthread_alloc _S_Alloc
const_pointer address(const_reference __x) const
pthread_allocator() _STLP_NOTHROW
~pthread_allocator() _STLP_NOTHROW
_Tp * allocate(size_type __n, size_type &__allocated_n)
pointer address(reference __x) const
pthread_allocator(const pthread_allocator< _Tp > &a) _STLP_NOTHROW
void destroy(pointer _p)
ptrdiff_t difference_type
size_type max_size() const _STLP_NOTHROW
unsigned short wchar_t
Definition: crtdefs.h:345
unsigned char
Definition: typeof.h:29
__kernel_size_t size_t
Definition: linux.h:237
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
#define _STLP_TEMPLATE_NULL
Definition: features.h:652
#define __REINTERPRET_CAST(__x, __y)
Definition: features.h:586
#define _STLP_SHRED_BYTE
Definition: features.h:903
#define _STLP_MOVE_TO_STD_NAMESPACE
Definition: features.h:525
#define _STLP_CLASS_DECLSPEC
Definition: features.h:983
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
#define _STLP_END_NAMESPACE
Definition: features.h:503
#define _STLP_MOVE_TO_PRIV_NAMESPACE
Definition: features.h:524
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
static const struct update_accum a2
Definition: msg.c:586
int other
Definition: msacm.c:1376
#define memset(x, y, z)
Definition: compat.h:39
_Rebind_type::other allocator_type
Definition: _alloc.h:201
_IsSTLportClass< per_thread_allocator< _Tp > >::_Ret _STLportAlloc
_STLportAlloc has_trivial_assignment_operator
_STLportAlloc has_trivial_copy_constructor
__false_type has_trivial_default_constructor
_STLportAlloc has_trivial_default_constructor
_STLportAlloc has_trivial_copy_constructor
_STLportAlloc has_trivial_assignment_operator
_IsSTLportClass< pthread_allocator< _Tp > >::_Ret _STLportAlloc
_STLportAlloc has_trivial_destructor
#define const
Definition: zconf.h:233