OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libstdc++-v3/] [include/] [ext/] [mt_allocator.h] - Blame information for rev 17

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 jlechner
// MT-optimized allocator -*- C++ -*-
2
 
3
// Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 2, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// You should have received a copy of the GNU General Public License along
17
// with this library; see the file COPYING.  If not, write to the Free
18
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19
// USA.
20
 
21
// As a special exception, you may use this file as part of a free software
22
// library without restriction.  Specifically, if other files instantiate
23
// templates or use macros or inline functions from this file, or you compile
24
// this file and link it with other files to produce an executable, this
25
// file does not by itself cause the resulting executable to be covered by
26
// the GNU General Public License.  This exception does not however
27
// invalidate any other reasons why the executable file might be covered by
28
// the GNU General Public License.
29
 
30
/** @file ext/mt_allocator.h
31
 *  This file is a GNU extension to the Standard C++ Library.
32
 */
33
 
34
#ifndef _MT_ALLOCATOR_H
35
#define _MT_ALLOCATOR_H 1
36
 
37
#include <new>
38
#include <cstdlib>
39
#include <bits/functexcept.h>
40
#include <bits/gthr.h>
41
#include <bits/atomicity.h>
42
 
43
namespace __gnu_cxx
44
{
45
  typedef void (*__destroy_handler)(void*);
46
 
47
  /// @brief  Base class for pool object.
48
  struct __pool_base
49
  {
50
    // Using short int as type for the binmap implies we are never
51
    // caching blocks larger than 65535 with this allocator.
52
    typedef unsigned short int _Binmap_type;
53
 
54
    // Variables used to configure the behavior of the allocator,
55
    // assigned and explained in detail below.
56
    struct _Tune
57
     {
58
      // Compile time constants for the default _Tune values.
59
      enum { _S_align = 8 };
60
      enum { _S_max_bytes = 128 };
61
      enum { _S_min_bin = 8 };
62
      enum { _S_chunk_size = 4096 - 4 * sizeof(void*) };
63
      enum { _S_max_threads = 4096 };
64
      enum { _S_freelist_headroom = 10 };
65
 
66
      // Alignment needed.
67
      // NB: In any case must be >= sizeof(_Block_record), that
68
      // is 4 on 32 bit machines and 8 on 64 bit machines.
69
      size_t    _M_align;
70
 
71
      // Allocation requests (after round-up to power of 2) below
72
      // this value will be handled by the allocator. A raw new/
73
      // call will be used for requests larger than this value.
74
      size_t    _M_max_bytes;
75
 
76
      // Size in bytes of the smallest bin.
77
      // NB: Must be a power of 2 and >= _M_align.
78
      size_t    _M_min_bin;
79
 
80
      // In order to avoid fragmenting and minimize the number of
81
      // new() calls we always request new memory using this
82
      // value. Based on previous discussions on the libstdc++
83
      // mailing list we have choosen the value below.
84
      // See http://gcc.gnu.org/ml/libstdc++/2001-07/msg00077.html
85
      size_t    _M_chunk_size;
86
 
87
      // The maximum number of supported threads. For
88
      // single-threaded operation, use one. Maximum values will
89
      // vary depending on details of the underlying system. (For
90
      // instance, Linux 2.4.18 reports 4070 in
91
      // /proc/sys/kernel/threads-max, while Linux 2.6.6 reports
92
      // 65534)
93
      size_t    _M_max_threads;
94
 
95
      // Each time a deallocation occurs in a threaded application
96
      // we make sure that there are no more than
97
      // _M_freelist_headroom % of used memory on the freelist. If
98
      // the number of additional records is more than
99
      // _M_freelist_headroom % of the freelist, we move these
100
      // records back to the global pool.
101
      size_t    _M_freelist_headroom;
102
 
103
      // Set to true forces all allocations to use new().
104
      bool      _M_force_new;
105
 
106
      explicit
107
      _Tune()
108
      : _M_align(_S_align), _M_max_bytes(_S_max_bytes), _M_min_bin(_S_min_bin),
109
      _M_chunk_size(_S_chunk_size), _M_max_threads(_S_max_threads),
110
      _M_freelist_headroom(_S_freelist_headroom),
111
      _M_force_new(getenv("GLIBCXX_FORCE_NEW") ? true : false)
112
      { }
113
 
114
      explicit
115
      _Tune(size_t __align, size_t __maxb, size_t __minbin, size_t __chunk,
116
            size_t __maxthreads, size_t __headroom, bool __force)
117
      : _M_align(__align), _M_max_bytes(__maxb), _M_min_bin(__minbin),
118
      _M_chunk_size(__chunk), _M_max_threads(__maxthreads),
119
      _M_freelist_headroom(__headroom), _M_force_new(__force)
120
      { }
121
    };
122
 
123
    struct _Block_address
124
    {
125
      void*                     _M_initial;
126
      _Block_address*           _M_next;
127
    };
128
 
129
    const _Tune&
130
    _M_get_options() const
131
    { return _M_options; }
132
 
133
    void
134
    _M_set_options(_Tune __t)
135
    {
136
      if (!_M_init)
137
        _M_options = __t;
138
    }
139
 
140
    bool
141
    _M_check_threshold(size_t __bytes)
142
    { return __bytes > _M_options._M_max_bytes || _M_options._M_force_new; }
143
 
144
    size_t
145
    _M_get_binmap(size_t __bytes)
146
    { return _M_binmap[__bytes]; }
147
 
148
    const size_t
149
    _M_get_align()
150
    { return _M_options._M_align; }
151
 
152
    explicit
153
    __pool_base()
154
    : _M_options(_Tune()), _M_binmap(NULL), _M_init(false) { }
155
 
156
    explicit
157
    __pool_base(const _Tune& __options)
158
    : _M_options(__options), _M_binmap(NULL), _M_init(false) { }
159
 
160
  private:
161
    explicit
162
    __pool_base(const __pool_base&);
163
 
164
    __pool_base&
165
    operator=(const __pool_base&);
166
 
167
  protected:
168
    // Configuration options.
169
    _Tune                       _M_options;
170
 
171
    _Binmap_type*               _M_binmap;
172
 
173
    // Configuration of the pool object via _M_options can happen
174
    // after construction but before initialization. After
175
    // initialization is complete, this variable is set to true.
176
    bool                        _M_init;
177
  };
178
 
179
 
180
  /**
181
   *  @brief  Data describing the underlying memory pool, parameterized on
182
   *  threading support.
183
   */
184
  template<bool _Thread>
185
    class __pool;
186
 
187
  /// Specialization for single thread.
188
  template<>
189
    class __pool<false> : public __pool_base
190
    {
191
    public:
192
      union _Block_record
193
      {
194
        // Points to the block_record of the next free block.
195
        _Block_record* volatile         _M_next;
196
      };
197
 
198
      struct _Bin_record
199
      {
200
        // An "array" of pointers to the first free block.
201
        _Block_record** volatile        _M_first;
202
 
203
        // A list of the initial addresses of all allocated blocks.
204
        _Block_address*                 _M_address;
205
      };
206
 
207
      void
208
      _M_initialize_once()
209
      {
210
        if (__builtin_expect(_M_init == false, false))
211
          _M_initialize();
212
      }
213
 
214
      void
215
      _M_destroy() throw();
216
 
217
      char*
218
      _M_reserve_block(size_t __bytes, const size_t __thread_id);
219
 
220
      void
221
      _M_reclaim_block(char* __p, size_t __bytes);
222
 
223
      size_t
224
      _M_get_thread_id() { return 0; }
225
 
226
      const _Bin_record&
227
      _M_get_bin(size_t __which)
228
      { return _M_bin[__which]; }
229
 
230
      void
231
      _M_adjust_freelist(const _Bin_record&, _Block_record*, size_t)
232
      { }
233
 
234
      explicit __pool()
235
      : _M_bin(NULL), _M_bin_size(1) { }
236
 
237
      explicit __pool(const __pool_base::_Tune& __tune)
238
      : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1) { }
239
 
240
    private:
241
      // An "array" of bin_records each of which represents a specific
242
      // power of 2 size. Memory to this "array" is allocated in
243
      // _M_initialize().
244
      _Bin_record* volatile     _M_bin;
245
 
246
      // Actual value calculated in _M_initialize().
247
      size_t                    _M_bin_size;
248
 
249
      void
250
      _M_initialize();
251
  };
252
 
253
#ifdef __GTHREADS
254
  /// Specialization for thread enabled, via gthreads.h.
255
  template<>
256
    class __pool<true> : public __pool_base
257
    {
258
    public:
259
      // Each requesting thread is assigned an id ranging from 1 to
260
      // _S_max_threads. Thread id 0 is used as a global memory pool.
261
      // In order to get constant performance on the thread assignment
262
      // routine, we keep a list of free ids. When a thread first
263
      // requests memory we remove the first record in this list and
264
      // stores the address in a __gthread_key. When initializing the
265
      // __gthread_key we specify a destructor. When this destructor
266
      // (i.e. the thread dies) is called, we return the thread id to
267
      // the front of this list.
268
      struct _Thread_record
269
      {
270
        // Points to next free thread id record. NULL if last record in list.
271
        _Thread_record* volatile        _M_next;
272
 
273
        // Thread id ranging from 1 to _S_max_threads.
274
        size_t                          _M_id;
275
      };
276
 
277
      union _Block_record
278
      {
279
        // Points to the block_record of the next free block.
280
        _Block_record* volatile         _M_next;
281
 
282
        // The thread id of the thread which has requested this block.
283
        size_t                          _M_thread_id;
284
      };
285
 
286
      struct _Bin_record
287
      {
288
        // An "array" of pointers to the first free block for each
289
        // thread id. Memory to this "array" is allocated in
290
        // _S_initialize() for _S_max_threads + global pool 0.
291
        _Block_record** volatile        _M_first;
292
 
293
        // A list of the initial addresses of all allocated blocks.
294
        _Block_address*                 _M_address;
295
 
296
        // An "array" of counters used to keep track of the amount of
297
        // blocks that are on the freelist/used for each thread id.
298
        // Memory to these "arrays" is allocated in _S_initialize() for
299
        // _S_max_threads + global pool 0.
300
        size_t* volatile                _M_free;
301
        size_t* volatile                _M_used;
302
 
303
        // Each bin has its own mutex which is used to ensure data
304
        // integrity while changing "ownership" on a block.  The mutex
305
        // is initialized in _S_initialize().
306
        __gthread_mutex_t*              _M_mutex;
307
      };
308
 
309
      // XXX GLIBCXX_ABI Deprecated
310
      void
311
      _M_initialize(__destroy_handler);
312
 
313
      void
314
      _M_initialize_once()
315
      {
316
        if (__builtin_expect(_M_init == false, false))
317
          _M_initialize();
318
      }
319
 
320
      void
321
      _M_destroy() throw();
322
 
323
      char*
324
      _M_reserve_block(size_t __bytes, const size_t __thread_id);
325
 
326
      void
327
      _M_reclaim_block(char* __p, size_t __bytes);
328
 
329
      const _Bin_record&
330
      _M_get_bin(size_t __which)
331
      { return _M_bin[__which]; }
332
 
333
      void
334
      _M_adjust_freelist(const _Bin_record& __bin, _Block_record* __block,
335
                         size_t __thread_id)
336
      {
337
        if (__gthread_active_p())
338
          {
339
            __block->_M_thread_id = __thread_id;
340
            --__bin._M_free[__thread_id];
341
            ++__bin._M_used[__thread_id];
342
          }
343
      }
344
 
345
      // XXX GLIBCXX_ABI Deprecated
346
      void
347
      _M_destroy_thread_key(void*);
348
 
349
      size_t
350
      _M_get_thread_id();
351
 
352
      explicit __pool()
353
      : _M_bin(NULL), _M_bin_size(1), _M_thread_freelist(NULL)
354
      { }
355
 
356
      explicit __pool(const __pool_base::_Tune& __tune)
357
      : __pool_base(__tune), _M_bin(NULL), _M_bin_size(1),
358
      _M_thread_freelist(NULL)
359
      { }
360
 
361
    private:
362
      // An "array" of bin_records each of which represents a specific
363
      // power of 2 size. Memory to this "array" is allocated in
364
      // _M_initialize().
365
      _Bin_record* volatile     _M_bin;
366
 
367
      // Actual value calculated in _M_initialize().
368
      size_t                    _M_bin_size;
369
 
370
      _Thread_record*           _M_thread_freelist;
371
      void*                     _M_thread_freelist_initial;
372
 
373
      void
374
      _M_initialize();
375
    };
376
#endif
377
 
378
  template<template <bool> class _PoolTp, bool _Thread>
379
    struct __common_pool
380
    {
381
      typedef _PoolTp<_Thread>          pool_type;
382
 
383
      static pool_type&
384
      _S_get_pool()
385
      {
386
        static pool_type _S_pool;
387
        return _S_pool;
388
      }
389
    };
390
 
391
  template<template <bool> class _PoolTp, bool _Thread>
392
    struct __common_pool_base;
393
 
394
  template<template <bool> class _PoolTp>
395
    struct __common_pool_base<_PoolTp, false>
396
    : public __common_pool<_PoolTp, false>
397
    {
398
      using  __common_pool<_PoolTp, false>::_S_get_pool;
399
 
400
      static void
401
      _S_initialize_once()
402
      {
403
        static bool __init;
404
        if (__builtin_expect(__init == false, false))
405
          {
406
            _S_get_pool()._M_initialize_once();
407
            __init = true;
408
          }
409
      }
410
    };
411
 
412
#ifdef __GTHREADS
413
  template<template <bool> class _PoolTp>
414
    struct __common_pool_base<_PoolTp, true>
415
    : public __common_pool<_PoolTp, true>
416
    {
417
      using  __common_pool<_PoolTp, true>::_S_get_pool;
418
 
419
      static void
420
      _S_initialize()
421
      { _S_get_pool()._M_initialize_once(); }
422
 
423
      static void
424
      _S_initialize_once()
425
      {
426
        static bool __init;
427
        if (__builtin_expect(__init == false, false))
428
          {
429
            if (__gthread_active_p())
430
              {
431
                // On some platforms, __gthread_once_t is an aggregate.
432
                static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
433
                __gthread_once(&__once, _S_initialize);
434
              }
435
 
436
            // Double check initialization. May be necessary on some
437
            // systems for proper construction when not compiling with
438
            // thread flags.
439
            _S_get_pool()._M_initialize_once();
440
            __init = true;
441
          }
442
      }
443
    };
444
#endif
445
 
446
  /// @brief  Policy for shared __pool objects.
447
  template<template <bool> class _PoolTp, bool _Thread>
448
    struct __common_pool_policy : public __common_pool_base<_PoolTp, _Thread>
449
    {
450
      template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp,
451
               bool _Thread1 = _Thread>
452
        struct _M_rebind
453
        { typedef __common_pool_policy<_PoolTp1, _Thread1> other; };
454
 
455
      using  __common_pool_base<_PoolTp, _Thread>::_S_get_pool;
456
      using  __common_pool_base<_PoolTp, _Thread>::_S_initialize_once;
457
  };
458
 
459
 
460
  template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
461
    struct __per_type_pool
462
    {
463
      typedef _Tp                       value_type;
464
      typedef _PoolTp<_Thread>          pool_type;
465
 
466
      static pool_type&
467
      _S_get_pool()
468
      {
469
        // Sane defaults for the _PoolTp.
470
        typedef typename pool_type::_Block_record _Block_record;
471
        const static size_t __a = (__alignof__(_Tp) >= sizeof(_Block_record)
472
                                   ? __alignof__(_Tp) : sizeof(_Block_record));
473
 
474
        typedef typename __pool_base::_Tune _Tune;
475
        static _Tune _S_tune(__a, sizeof(_Tp) * 64,
476
                             sizeof(_Tp) * 2 >= __a ? sizeof(_Tp) * 2 : __a,
477
                             sizeof(_Tp) * size_t(_Tune::_S_chunk_size),
478
                             _Tune::_S_max_threads,
479
                             _Tune::_S_freelist_headroom,
480
                             getenv("GLIBCXX_FORCE_NEW") ? true : false);
481
        static pool_type _S_pool(_S_tune);
482
        return _S_pool;
483
      }
484
    };
485
 
486
  template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
487
    struct __per_type_pool_base;
488
 
489
  template<typename _Tp, template <bool> class _PoolTp>
490
    struct __per_type_pool_base<_Tp, _PoolTp, false>
491
    : public __per_type_pool<_Tp, _PoolTp, false>
492
    {
493
      using  __per_type_pool<_Tp, _PoolTp, false>::_S_get_pool;
494
 
495
      static void
496
      _S_initialize_once()
497
      {
498
        static bool __init;
499
        if (__builtin_expect(__init == false, false))
500
          {
501
            _S_get_pool()._M_initialize_once();
502
            __init = true;
503
          }
504
      }
505
    };
506
 
507
 #ifdef __GTHREADS
508
 template<typename _Tp, template <bool> class _PoolTp>
509
    struct __per_type_pool_base<_Tp, _PoolTp, true>
510
    : public __per_type_pool<_Tp, _PoolTp, true>
511
    {
512
      using  __per_type_pool<_Tp, _PoolTp, true>::_S_get_pool;
513
 
514
      static void
515
      _S_initialize()
516
      { _S_get_pool()._M_initialize_once(); }
517
 
518
      static void
519
      _S_initialize_once()
520
      {
521
        static bool __init;
522
        if (__builtin_expect(__init == false, false))
523
          {
524
            if (__gthread_active_p())
525
              {
526
                // On some platforms, __gthread_once_t is an aggregate.
527
                static __gthread_once_t __once = __GTHREAD_ONCE_INIT;
528
                __gthread_once(&__once, _S_initialize);
529
              }
530
 
531
            // Double check initialization. May be necessary on some
532
            // systems for proper construction when not compiling with
533
            // thread flags.
534
            _S_get_pool()._M_initialize_once();
535
            __init = true;
536
          }
537
      }
538
    };
539
#endif
540
 
541
  /// @brief  Policy for individual __pool objects.
542
  template<typename _Tp, template <bool> class _PoolTp, bool _Thread>
543
    struct __per_type_pool_policy
544
    : public __per_type_pool_base<_Tp, _PoolTp, _Thread>
545
    {
546
      template<typename _Tp1, template <bool> class _PoolTp1 = _PoolTp,
547
               bool _Thread1 = _Thread>
548
        struct _M_rebind
549
        { typedef __per_type_pool_policy<_Tp1, _PoolTp1, _Thread1> other; };
550
 
551
      using  __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_get_pool;
552
      using  __per_type_pool_base<_Tp, _PoolTp, _Thread>::_S_initialize_once;
553
  };
554
 
555
 
556
  /// @brief  Base class for _Tp dependent member functions.
557
  template<typename _Tp>
558
    class __mt_alloc_base
559
    {
560
    public:
561
      typedef size_t                    size_type;
562
      typedef ptrdiff_t                 difference_type;
563
      typedef _Tp*                      pointer;
564
      typedef const _Tp*                const_pointer;
565
      typedef _Tp&                      reference;
566
      typedef const _Tp&                const_reference;
567
      typedef _Tp                       value_type;
568
 
569
      pointer
570
      address(reference __x) const
571
      { return &__x; }
572
 
573
      const_pointer
574
      address(const_reference __x) const
575
      { return &__x; }
576
 
577
      size_type
578
      max_size() const throw()
579
      { return size_t(-1) / sizeof(_Tp); }
580
 
581
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
582
      // 402. wrong new expression in [some_] allocator::construct
583
      void
584
      construct(pointer __p, const _Tp& __val)
585
      { ::new(__p) _Tp(__val); }
586
 
587
      void
588
      destroy(pointer __p) { __p->~_Tp(); }
589
    };
590
 
591
#ifdef __GTHREADS
592
#define __thread_default true
593
#else
594
#define __thread_default false
595
#endif
596
 
597
  /**
598
   *  @brief  This is a fixed size (power of 2) allocator which - when
599
   *  compiled with thread support - will maintain one freelist per
600
   *  size per thread plus a "global" one. Steps are taken to limit
601
   *  the per thread freelist sizes (by returning excess back to
602
   *  the "global" list).
603
   *
604
   *  Further details:
605
   *  http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html
606
   */
607
  template<typename _Tp,
608
           typename _Poolp = __common_pool_policy<__pool, __thread_default> >
609
    class __mt_alloc : public __mt_alloc_base<_Tp>
610
    {
611
    public:
612
      typedef size_t                            size_type;
613
      typedef ptrdiff_t                         difference_type;
614
      typedef _Tp*                              pointer;
615
      typedef const _Tp*                        const_pointer;
616
      typedef _Tp&                              reference;
617
      typedef const _Tp&                        const_reference;
618
      typedef _Tp                               value_type;
619
      typedef _Poolp                            __policy_type;
620
      typedef typename _Poolp::pool_type        __pool_type;
621
 
622
      template<typename _Tp1, typename _Poolp1 = _Poolp>
623
        struct rebind
624
        {
625
          typedef typename _Poolp1::template _M_rebind<_Tp1>::other pol_type;
626
          typedef __mt_alloc<_Tp1, pol_type> other;
627
        };
628
 
629
      __mt_alloc() throw() { }
630
 
631
      __mt_alloc(const __mt_alloc&) throw() { }
632
 
633
      template<typename _Tp1, typename _Poolp1>
634
        __mt_alloc(const __mt_alloc<_Tp1, _Poolp1>&) throw() { }
635
 
636
      ~__mt_alloc() throw() { }
637
 
638
      pointer
639
      allocate(size_type __n, const void* = 0);
640
 
641
      void
642
      deallocate(pointer __p, size_type __n);
643
 
644
      const __pool_base::_Tune
645
      _M_get_options()
646
      {
647
        // Return a copy, not a reference, for external consumption.
648
        return __policy_type::_S_get_pool()._M_get_options();
649
      }
650
 
651
      void
652
      _M_set_options(__pool_base::_Tune __t)
653
      { __policy_type::_S_get_pool()._M_set_options(__t); }
654
    };
655
 
656
  template<typename _Tp, typename _Poolp>
657
    typename __mt_alloc<_Tp, _Poolp>::pointer
658
    __mt_alloc<_Tp, _Poolp>::
659
    allocate(size_type __n, const void*)
660
    {
661
      if (__builtin_expect(__n > this->max_size(), false))
662
        std::__throw_bad_alloc();
663
 
664
      __policy_type::_S_initialize_once();
665
 
666
      // Requests larger than _M_max_bytes are handled by operator
667
      // new/delete directly.
668
      __pool_type& __pool = __policy_type::_S_get_pool();
669
      const size_t __bytes = __n * sizeof(_Tp);
670
      if (__pool._M_check_threshold(__bytes))
671
        {
672
          void* __ret = ::operator new(__bytes);
673
          return static_cast<_Tp*>(__ret);
674
        }
675
 
676
      // Round up to power of 2 and figure out which bin to use.
677
      const size_t __which = __pool._M_get_binmap(__bytes);
678
      const size_t __thread_id = __pool._M_get_thread_id();
679
 
680
      // Find out if we have blocks on our freelist.  If so, go ahead
681
      // and use them directly without having to lock anything.
682
      char* __c;
683
      typedef typename __pool_type::_Bin_record _Bin_record;
684
      const _Bin_record& __bin = __pool._M_get_bin(__which);
685
      if (__bin._M_first[__thread_id])
686
        {
687
          // Already reserved.
688
          typedef typename __pool_type::_Block_record _Block_record;
689
          _Block_record* __block = __bin._M_first[__thread_id];
690
          __bin._M_first[__thread_id] = __block->_M_next;
691
 
692
          __pool._M_adjust_freelist(__bin, __block, __thread_id);
693
          __c = reinterpret_cast<char*>(__block) + __pool._M_get_align();
694
        }
695
      else
696
        {
697
          // Null, reserve.
698
          __c = __pool._M_reserve_block(__bytes, __thread_id);
699
        }
700
      return static_cast<_Tp*>(static_cast<void*>(__c));
701
    }
702
 
703
  template<typename _Tp, typename _Poolp>
704
    void
705
    __mt_alloc<_Tp, _Poolp>::
706
    deallocate(pointer __p, size_type __n)
707
    {
708
      if (__builtin_expect(__p != 0, true))
709
        {
710
          // Requests larger than _M_max_bytes are handled by
711
          // operators new/delete directly.
712
          __pool_type& __pool = __policy_type::_S_get_pool();
713
          const size_t __bytes = __n * sizeof(_Tp);
714
          if (__pool._M_check_threshold(__bytes))
715
            ::operator delete(__p);
716
          else
717
            __pool._M_reclaim_block(reinterpret_cast<char*>(__p), __bytes);
718
        }
719
    }
720
 
721
  template<typename _Tp, typename _Poolp>
722
    inline bool
723
    operator==(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&)
724
    { return true; }
725
 
726
  template<typename _Tp, typename _Poolp>
727
    inline bool
728
    operator!=(const __mt_alloc<_Tp, _Poolp>&, const __mt_alloc<_Tp, _Poolp>&)
729
    { return false; }
730
 
731
#undef __thread_default
732
} // namespace __gnu_cxx
733
 
734
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.