This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [v3] allocator switches


Benjamin Kosnik wrote:

There are still two bits that need to go into __mt_alloc. One, the
switch to new/delete from malloc/free (This shows up as an
allocator/1.cc fail in the testsuite runs when it's the default). The
other is GLIBCXX_FORCE_NEW support.


2004-01-28 Stefan Olsson <stefan@snon.net>

* include/ext/mt_allocator.h: Replaced all malloc() calls with operator new(). Added support for the env variable GLIBCXX_FORCE_NEW (this required the _S_init call to be the first one in allocate() as well). Fix typos.

Brgds

/Stefan
*** /home/admin/mt_allocator.h	Wed Jan 28 10:15:09 2004
--- mt_allocator.h	Wed Jan 28 10:49:33 2004
*************** namespace __gnu_cxx
*** 125,130 ****
--- 125,136 ----
        static bool volatile _S_initialized;
  
        /*
+        * If the env var GLIBCXX_FORCE_NEW is set during _S_init()
+        * we set this var to true which causes all allocations to use new()
+        */
+       static bool _S_force_new;
+ 
+       /*
         * Using short int as type for the binmap implies we are never caching
         * blocks larger than 65535 with this allocator
         */
*************** namespace __gnu_cxx
*** 227,244 ****
        allocate(size_t __n, std::allocator<void>::const_pointer __h = 0)
        {
          /*
-          * Requests larger than _S_max_bytes are handled by
-          * new/delete directly
-          */
-         if (__n * sizeof(_Tp) > _S_max_bytes)
-           {
-             void* __ret = malloc(__n * sizeof(_Tp));
-             if (!__ret)
-               __throw_bad_alloc();
-             return static_cast<_Tp*>(__ret);
-           }
- 	
-         /*
           * Although the test in __gthread_once() would suffice, we
           * wrap test of the once condition in our own unlocked
           * check. This saves one function call to pthread_once()
--- 233,238 ----
*************** namespace __gnu_cxx
*** 259,264 ****
--- 253,270 ----
            }
  
          /*
+          * Requests larger than _S_max_bytes are handled by
+          * new/delete directly
+          */
+         if (__n * sizeof(_Tp) > _S_max_bytes || _S_force_new)
+           {
+             void* __ret = ::operator new(__n * sizeof(_Tp));
+             if (!__ret)
+               __throw_bad_alloc();
+             return static_cast<_Tp*>(__ret);
+           }
+ 
+         /*
           * Round up to power of 2 and figure out which bin to use
           */
          size_t bin = _S_binmap[__n * sizeof(_Tp)];
*************** namespace __gnu_cxx
*** 308,314 ****
                      __gthread_mutex_unlock(_S_bin[bin].mutex);
  
                      _S_bin[bin].first[thread_id] =
!                       (block_record*)malloc(_S_chunk_size);
  
                      if (!_S_bin[bin].first[thread_id])
                        __throw_bad_alloc();
--- 314,320 ----
                      __gthread_mutex_unlock(_S_bin[bin].mutex);
  
                      _S_bin[bin].first[thread_id] =
!                       static_cast<block_record*>(::operator new(_S_chunk_size));
  
                      if (!_S_bin[bin].first[thread_id])
                        __throw_bad_alloc();
*************** namespace __gnu_cxx
*** 375,381 ****
              else
  #endif
                {
!                 _S_bin[bin].first[0] = (block_record*)malloc(_S_chunk_size);
  
                  if (!_S_bin[bin].first[0])
                    __throw_bad_alloc();
--- 381,388 ----
              else
  #endif
                {
!                 _S_bin[bin].first[0] = 
!                   static_cast<block_record*>(::operator new(_S_chunk_size));
  
                  if (!_S_bin[bin].first[0])
                    __throw_bad_alloc();
*************** namespace __gnu_cxx
*** 425,431 ****
  #endif
            }
  
!         return static_cast<_Tp*>(static_cast<void*>((char*)block + sizeof(block_record)));
        }
  
        void
--- 432,439 ----
  #endif
            }
  
!         return static_cast<_Tp*>(static_cast<void*>((char*)block + 
!                                                     sizeof(block_record)));
        }
  
        void
*************** namespace __gnu_cxx
*** 435,441 ****
           * Requests larger than _S_max_bytes are handled by
           * malloc/free directly
           */
!         if (__n * sizeof(_Tp) > _S_max_bytes)
            {
              free(__p);
              return;
--- 443,449 ----
           * Requests larger than _S_max_bytes are handled by
           * malloc/free directly
           */
!         if (__n * sizeof(_Tp) > _S_max_bytes || _S_force_new)
            {
              free(__p);
              return;
*************** namespace __gnu_cxx
*** 546,551 ****
--- 554,572 ----
      __mt_alloc<_Tp>::
      _S_init()
      {
+       if (getenv("GLIBCXX_FORCE_NEW"))
+         {
+           _S_force_new = true;
+           _S_initialized = true;
+ 
+           /*
+            * Since none of the code in allocate/deallocate ever will be 
+            * executed due to that the GLIBCXX_FORCE_NEW flag is set
+            * there is no need to create the internal structures either.
+            */
+           return;
+         }
+ 
        /*
         * Calculate the number of bins required based on _S_max_bytes,
         * _S_no_of_bins is initialized to 1 below.
*************** namespace __gnu_cxx
*** 590,596 ****
        if (__gthread_active_p())
          {
            _S_thread_freelist_first =
!             (thread_record*)malloc(sizeof(thread_record) * _S_max_threads);
  
            if (!_S_thread_freelist_first)
              __throw_bad_alloc();
--- 611,618 ----
        if (__gthread_active_p())
          {
            _S_thread_freelist_first =
!             static_cast<thread_record*>(::operator 
!               new(sizeof(thread_record) * _S_max_threads));
  
            if (!_S_thread_freelist_first)
              __throw_bad_alloc();
*************** namespace __gnu_cxx
*** 625,631 ****
        /*
         * Initialize _S_bin and its members
         */
!       _S_bin = (bin_record*)malloc(sizeof(bin_record) * _S_no_of_bins);
  
        if (!_S_bin)
          __throw_bad_alloc();
--- 647,654 ----
        /*
         * Initialize _S_bin and its members
         */
!       _S_bin = static_cast<bin_record*>(::operator 
!         new(sizeof(bin_record) * _S_no_of_bins));
  
        if (!_S_bin)
          __throw_bad_alloc();
*************** namespace __gnu_cxx
*** 639,652 ****
  
        for (size_t bin = 0; bin < _S_no_of_bins; bin++)
          {
!           _S_bin[bin].first = (block_record**) 
!             malloc(sizeof(block_record*) * __n);
  
            if (!_S_bin[bin].first)
              __throw_bad_alloc();
  
!           _S_bin[bin].last = (block_record**) 
!             malloc(sizeof(block_record*) * __n);
  
            if (!_S_bin[bin].last)
              __throw_bad_alloc();
--- 662,675 ----
  
        for (size_t bin = 0; bin < _S_no_of_bins; bin++)
          {
!           _S_bin[bin].first = static_cast<block_record**>(::operator 
!             new(sizeof(block_record*) * __n));
  
            if (!_S_bin[bin].first)
              __throw_bad_alloc();
  
!           _S_bin[bin].last = static_cast<block_record**>(::operator 
!             new(sizeof(block_record*) * __n));
  
            if (!_S_bin[bin].last)
              __throw_bad_alloc();
*************** namespace __gnu_cxx
*** 654,670 ****
  #ifdef __GTHREADS
            if (__gthread_active_p())
              {
!               _S_bin[bin].free = (size_t*) malloc(sizeof(size_t) * __n);
  
                if (!_S_bin[bin].free)
                  __throw_bad_alloc();
  
!               _S_bin[bin].used = (size_t*) malloc(sizeof(size_t) * __n);
  
                if (!_S_bin[bin].used)
                  __throw_bad_alloc();
  
!               _S_bin[bin].mutex =(__gthread_mutex_t*) malloc(sizeof(__gthread_mutex_t));
  
  #ifdef __GTHREAD_MUTEX_INIT
                {
--- 677,696 ----
  #ifdef __GTHREADS
            if (__gthread_active_p())
              {
!               _S_bin[bin].free = static_cast<size_t*>(::operator 
!                 new(sizeof(size_t) * __n));
  
                if (!_S_bin[bin].free)
                  __throw_bad_alloc();
  
!               _S_bin[bin].used = static_cast<size_t*>(::operator 
!                 new(sizeof(size_t) * __n));
  
                if (!_S_bin[bin].used)
                  __throw_bad_alloc();
  
!               _S_bin[bin].mutex = static_cast<__gthread_mutex_t*>(::operator 
!                 new(sizeof(__gthread_mutex_t)));
  
  #ifdef __GTHREAD_MUTEX_INIT
                {
*************** namespace __gnu_cxx
*** 758,763 ****
--- 784,792 ----
    template<typename _Tp> bool
    volatile __mt_alloc<_Tp>::_S_initialized = false;
  
+   template<typename _Tp> bool
+   __mt_alloc<_Tp>::_S_force_new = false;
+ 
    template<typename _Tp> typename __mt_alloc<_Tp>::binmap_type*
    __mt_alloc<_Tp>::_S_binmap = NULL;
  
*************** namespace __gnu_cxx
*** 770,776 ****
    __mt_alloc<_Tp>::_S_max_bytes = 128;
  
    /*
!    * In order to avoid fragmenting and minimize the number of malloc()
     * calls we always request new memory using this value. Based on
     * previous discussions on the libstdc++ mailing list we have
     * choosen the value below. See
--- 799,805 ----
    __mt_alloc<_Tp>::_S_max_bytes = 128;
  
    /*
!    * In order to avoid fragmenting and minimize the number of new()
     * calls we always request new memory using this value. Based on
     * previous discussions on the libstdc++ mailing list we have
     * choosen the value below. See

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]