diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7db0e574f12..4876e73d696 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,30 @@
+2002-10-18 Loren J. Rittle
+ Brad Spencer (provided alternate
+ patch and improvements)
+
+ * docs/html/23_containers/howto.html (GLIBCPP_FORCE_NEW): Document
+ new environment variable which replaces all uses of __USE_MALLOC
+ macro.
+ * docs/html/ext/howto.html (GLIBCPP_FORCE_NEW): Likewise.
+ (__mem_interface): Remove all references to old internal typedef.
+ * include/backward/alloc.h (__USE_MALLOC): Remove it and all
+ guarded code.
+ * include/bits/c++config (__USE_MALLOC): Update related error
+ message and comment.
+ * include/bits/stl_alloc.h (__USE_MALLOC): Remove it and all
+ guarded code. Update all related comments.
+ (__mem_interface): Unconditionally replace it with __new_alloc.
+ However, leave the typedef around in case anyone used it.
+ (__default_alloc_template<>::_S_force_new): New class static.
+ (__default_alloc_template<>::allocate, deallocate): Add
+ run-time controlled feature similar to what __USE_MALLOC code
+ path had provided.
+ * src/stl-inst.cc (__USE_MALLOC): Remove it and all
+ guarded code.
+ * testsuite/21_strings/capacity.cc: Remove reference to __USE_MALLOC.
+ Add documentation on GLIBCPP_FORCE_NEW environment variable.
+ * testsuite/ext/allocators.cc: Likewise.
+
2002-10-18 Phil Edwards
* configure.in: Use target, not target_alias, when matching triplet
diff --git a/libstdc++-v3/docs/html/23_containers/howto.html b/libstdc++-v3/docs/html/23_containers/howto.html
index 94226a21b7e..008017a8827 100644
--- a/libstdc++-v3/docs/html/23_containers/howto.html
+++ b/libstdc++-v3/docs/html/23_containers/howto.html
@@ -251,41 +251,11 @@
solution would probably be more trouble than it's worth.
The STL implementation is currently configured to use the
- high-speed caching memory allocator. If you absolutely think
- you must change this on a global basis for your platform to better
- support multi-threading, then please consult all commentary in
- include/bits/stl_alloc.h and the allocators link below.
+ high-speed caching memory allocator. Some people like to
+ test and/or normally run threaded programs with a different
+ default. For all details about how to globally override this
+ at application run-time see here.
-
- (Explicit warning since so many people get confused while
- attempting this:)
-
- Adding -D__USE_MALLOC on the command
- line is almost certainly a bad idea. Memory efficiency is
- almost guaranteed to suffer as a result; this is
- why
- we disabled it for 3.0 in the first place.
-
- Related to threading or otherwise, the current recommendation is
- that users not add any macro defines on the command line to remove or
- otherwise disable features of libstdc++-v3. There is
- no condition under which it will help you without causing other
- issues to perhaps raise up (possible linkage/ABI problems). In
- particular, __USE_MALLOC should only be added to a libstdc++-v3
- configuration file, include/bits/c++config (where such user
- action is cautioned against), and the entire library should be
- rebuilt. If you do not, then you might be violating the
- one-definition rule of C/C++ and you might cause yourself untold
- problems.
-
-
- If you find any platform where gcc reports a
- threading model other than single, and where libstdc++-v3 builds
- a buggy container allocator when used with threads unless you
- define __USE_MALLOC, we want to hear about it ASAP. In the
- past, correctness was the main reason people were led to believe
- that they should define __USE_MALLOC when using threads.
-
There is a better way (not standardized yet): It is possible to
force the malloc-based allocator on a per-case-basis for some
application code. The library team generally believes that this
diff --git a/libstdc++-v3/docs/html/ext/howto.html b/libstdc++-v3/docs/html/ext/howto.html
index 2a038267627..007335b6569 100644
--- a/libstdc++-v3/docs/html/ext/howto.html
+++ b/libstdc++-v3/docs/html/ext/howto.html
@@ -280,19 +280,16 @@
same as allocator<T>
.
-
An internal typedef, __mem_interface
, is defined to be
- __new_alloc
by default.
-
Normally,
__default_alloc_template<bool thr, int inst>
is also available. This is the high-speed pool, called the default
node allocator. The reusable memory is shared among identical
instantiations of
- this type. It calls through __mem_interface
to obtain
+ this type. It calls through __new_alloc
to obtain
new memory when its lists run out. If a client container requests a
block larger than a certain threshold size, then the pool is bypassed,
and the allocate/deallocate request is passed to
- __mem_interface
directly.
+ __new_alloc
directly.
Its inst
parameter is described below. The
thr
boolean determines whether the pool should be
@@ -313,17 +310,25 @@
A cannon to swat a fly: __USE_MALLOC
If you've already read this
- advice and decided to define this macro, then the situation changes
- thusly:
+ advice but still think you remember how to use this macro from
+ SGI STL days. We have removed it in gcc 3.3. See next section
+ for the new way to get the same effect.
+
+ Globally disabling memory caching: GLIBCPP_FORCE_NEW
+ Starting with gcc 3.3, if you want to globally disable memory
+ caching within the library for the default allocator (i.e.
+ the one you get for all library objects when you do not specify
+ which one to use), merely set GLIBCPP_FORCE_NEW (at this time,
+ with any value) into your environment before running the
+ program. You will obtain a similar effect without having to
+ recompile your entire program and the entire library (the new
+ operator in gcc is a light wrapper around malloc). If your
+ program crashes with GLIBCPP_FORCE_NEW in the environment,
+ it likely means that you linked against objects built against
+ the older library. Code to support this extension is fully
+ compatible with 3.2 code if GLIBCPP_FORCE_NEW is not in the
+ environment.
-
- __mem_interface
, and
- __alloc
, and
- __single_client_alloc
are all typedef'd to
- __malloc_alloc_template
.
- __default_alloc_template
is no longer available.
- At all. Anywhere.
-
Writing your own allocators
Depending on your application (a specific program, a generic library,
etc), allocator classes tend to be one of two styles: "SGI"
diff --git a/libstdc++-v3/include/backward/alloc.h b/libstdc++-v3/include/backward/alloc.h
index 4344a1d902c..9482e4cfeba 100644
--- a/libstdc++-v3/include/backward/alloc.h
+++ b/libstdc++-v3/include/backward/alloc.h
@@ -53,10 +53,6 @@ using std::__debug_alloc;
using std::__alloc;
using std::__single_client_alloc;
using std::allocator;
-#ifdef __USE_MALLOC
-using std::malloc_alloc;
-#else
using std::__default_alloc_template;
-#endif
#endif
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 628e6c834e9..05f2f5a0bfc 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -74,13 +74,8 @@
// so, please report any possible issues to libstdc++@gcc.gnu.org .
// Do not define __USE_MALLOC on the command line. Enforce it here:
#ifdef __USE_MALLOC
-#error __USE_MALLOC should only be defined within \
-libstdc++-v3/include/bits/c++config before full recompilation of the library.
+#error __USE_MALLOC should never be defined. Read the release notes.
#endif
-// Define __USE_MALLOC after this point in the file in order to aid debugging
-// or globally change allocation policy. This breaks the ABI, thus
-// completely recompile the library. A patch to better support
-// changing the global allocator policy would be probably be accepted.
// The remainder of the prewritten config is mostly automatic; all the
// user hooks are listed above.
diff --git a/libstdc++-v3/include/bits/stl_alloc.h b/libstdc++-v3/include/bits/stl_alloc.h
index c3b4b19b176..fceed498df6 100644
--- a/libstdc++-v3/include/bits/stl_alloc.h
+++ b/libstdc++-v3/include/bits/stl_alloc.h
@@ -89,6 +89,8 @@
#include // For __throw_bad_alloc
#include
+#include
+
namespace std
{
/**
@@ -210,14 +212,8 @@ namespace std
}
#endif
-
- // Determines the underlying allocator choice for the node allocator.
-#ifdef __USE_MALLOC
- typedef __malloc_alloc_template<0> __mem_interface;
-#else
+ // Should not be referenced within the library anymore.
typedef __new_alloc __mem_interface;
-#endif
-
/**
* @if maint
@@ -307,23 +303,16 @@ namespace std
};
-#ifdef __USE_MALLOC
-
- typedef __mem_interface __alloc;
- typedef __mem_interface __single_client_alloc;
-
-#else
-
-
/**
* @if maint
- * Default node allocator. "SGI" style. Uses __mem_interface for its
- * underlying requests (and makes as few requests as possible).
- * **** Currently __mem_interface is always __new_alloc, never __malloc*.
+ * Default node allocator. "SGI" style. Uses various allocators to
+ * fulfill underlying requests (and makes as few requests as possible
+ * when in default high-speed pool mode).
*
* Important implementation properties:
+ * 0. If globally mandated, then allocate objects from __new_alloc
* 1. If the clients request an object of size > _MAX_BYTES, the resulting
- * object will be obtained directly from the underlying __mem_interface.
+ * object will be obtained directly from __new_alloc
* 2. In all other cases, we allocate an object of size exactly
* _S_round_up(requested_size). Thus the client has enough size
* information that we can return the object to the proper free list
@@ -394,54 +383,69 @@ namespace std
} __attribute__ ((__unused__));
friend struct _Lock;
+ static _Atomic_word _S_force_new;
+
public:
// __n must be > 0
static void*
allocate(size_t __n)
{
- void* __ret = 0;
+ void* __ret = 0;
- if (__n > (size_t) _MAX_BYTES)
- __ret = __mem_interface::allocate(__n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- _Obj* __restrict__ __result = *__my_free_list;
- if (__result == 0)
- __ret = _S_refill(_S_round_up(__n));
- else
- {
- *__my_free_list = __result -> _M_free_list_link;
- __ret = __result;
- }
- }
- return __ret;
- };
+ // If there is a race through here, assume answer from getenv
+ // will resolve in same direction. Inspired by techniques
+ // to efficiently support threading found in basic_string.h.
+ if (_S_force_new == 0)
+ {
+ if (getenv("GLIBCPP_FORCE_NEW"))
+ __atomic_add(&_S_force_new, 1);
+ else
+ __atomic_add(&_S_force_new, -1);
+ // Trust but verify...
+ assert (_S_force_new != 0);
+ }
+
+ if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+ __ret = __new_alloc::allocate(__n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ _Obj* __restrict__ __result = *__my_free_list;
+ if (__result == 0)
+ __ret = _S_refill(_S_round_up(__n));
+ else
+ {
+ *__my_free_list = __result -> _M_free_list_link;
+ __ret = __result;
+ }
+ }
+ return __ret;
+ }
// __p may not be 0
static void
deallocate(void* __p, size_t __n)
{
- if (__n > (size_t) _MAX_BYTES)
- __mem_interface::deallocate(__p, __n);
- else
- {
- _Obj* volatile* __my_free_list = _S_free_list
- + _S_freelist_index(__n);
- _Obj* __q = (_Obj*)__p;
+ if ((__n > (size_t) _MAX_BYTES) || (_S_force_new > 0))
+ __new_alloc::deallocate(__p, __n);
+ else
+ {
+ _Obj* volatile* __my_free_list = _S_free_list
+ + _S_freelist_index(__n);
+ _Obj* __q = (_Obj*)__p;
- // Acquire the lock here with a constructor call. This
- // ensures that it is released in exit or during stack
- // unwinding.
- _Lock __lock_instance;
- __q -> _M_free_list_link = *__my_free_list;
- *__my_free_list = __q;
- }
+ // Acquire the lock here with a constructor call. This
+ // ensures that it is released in exit or during stack
+ // unwinding.
+ _Lock __lock_instance;
+ __q -> _M_free_list_link = *__my_free_list;
+ *__my_free_list = __q;
+ }
}
#ifdef _GLIBCPP_DEPRECATED
@@ -450,6 +454,8 @@ namespace std
#endif
};
+ template _Atomic_word
+ __default_alloc_template<__threads, __inst>::_S_force_new = 0;
template
inline bool
@@ -465,8 +471,8 @@ namespace std
// We allocate memory in large chunks in order to avoid fragmenting the
- // malloc heap (or whatever __mem_interface is using) too much. We assume
- // that __size is properly aligned. We hold the allocation lock.
+ // heap too much. We assume that __size is properly aligned. We hold
+ // the allocation lock.
template
char*
__default_alloc_template<__threads, __inst>::
@@ -503,7 +509,7 @@ namespace std
((_Obj*)_S_start_free) -> _M_free_list_link = *__my_free_list;
*__my_free_list = (_Obj*)_S_start_free;
}
- _S_start_free = (char*) __mem_interface::allocate(__bytes_to_get);
+ _S_start_free = (char*) __new_alloc::allocate(__bytes_to_get);
if (0 == _S_start_free)
{
size_t __i;
@@ -528,7 +534,7 @@ namespace std
}
}
_S_end_free = 0; // In case of exception.
- _S_start_free = (char*)__mem_interface::allocate(__bytes_to_get);
+ _S_start_free = (char*)__new_alloc::allocate(__bytes_to_get);
// This should either throw an exception or remedy the situation.
// Thus we assume it succeeded.
}
@@ -618,7 +624,6 @@ namespace std
typedef __default_alloc_template __alloc;
typedef __default_alloc_template __single_client_alloc;
-#endif /* ! __USE_MALLOC */
/**
@@ -628,10 +633,6 @@ namespace std
* of stl_alloc.h.)
*
* The underlying allocator behaves as follows.
- * - if __USE_MALLOC then
- * - thread safety depends on malloc and is entirely out of our hands
- * - __malloc_alloc_template is used for memory requests
- * - else (the default)
* - __default_alloc_template is used via two typedefs
* - "__single_client_alloc" typedef does no locking for threads
* - "__alloc" typedef is threadsafe via the locks
@@ -908,7 +909,6 @@ namespace std
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
-#ifndef __USE_MALLOC
template
struct _Alloc_traits<_Tp, __default_alloc_template<__threads, __inst> >
{
@@ -918,7 +918,6 @@ namespace std
typedef __allocator<_Tp, __default_alloc_template<__threads, __inst> >
allocator_type;
};
-#endif
template
struct _Alloc_traits<_Tp, __debug_alloc<_Alloc> >
@@ -941,7 +940,6 @@ namespace std
typedef __allocator<_Tp, __malloc_alloc_template<__inst> > allocator_type;
};
-#ifndef __USE_MALLOC
template
struct _Alloc_traits<_Tp, __allocator<_Tp1, __default_alloc_template<__thr, __inst> > >
{
@@ -951,7 +949,6 @@ namespace std
typedef __allocator<_Tp, __default_alloc_template<__thr,__inst> >
allocator_type;
};
-#endif
template
struct _Alloc_traits<_Tp, __allocator<_Tp1, __debug_alloc<_Alloc> > >
@@ -967,11 +964,7 @@ namespace std
// NB: This syntax is a GNU extension.
extern template class allocator;
extern template class allocator;
-#ifdef __USE_MALLOC
- extern template class __malloc_alloc_template<0>;
-#else
extern template class __default_alloc_template;
-#endif
} // namespace std
#endif
diff --git a/libstdc++-v3/src/stl-inst.cc b/libstdc++-v3/src/stl-inst.cc
index d8879a7bccd..d80a7186718 100644
--- a/libstdc++-v3/src/stl-inst.cc
+++ b/libstdc++-v3/src/stl-inst.cc
@@ -39,9 +39,5 @@ namespace std
template class allocator;
template class allocator;
-#ifdef __USE_MALLOC
- template class __malloc_alloc_template<0>;
-#else
template class __default_alloc_template;
-#endif
} // namespace std
diff --git a/libstdc++-v3/testsuite/21_strings/capacity.cc b/libstdc++-v3/testsuite/21_strings/capacity.cc
index 3c45b005017..99a5b655f58 100644
--- a/libstdc++-v3/testsuite/21_strings/capacity.cc
+++ b/libstdc++-v3/testsuite/21_strings/capacity.cc
@@ -209,7 +209,7 @@ void test01()
sz02 = str011.length();
VERIFY( sz02 > sz01 );
- // trickster allocator (__USE_MALLOC, luke) issues involved with these:
+ // trickster allocator issues involved with these:
std::string str3 = "8-chars_8-chars_";
const char* p3 = str3.c_str();
std::string str4 = str3 + "7-chars";
diff --git a/libstdc++-v3/testsuite/ext/allocators.cc b/libstdc++-v3/testsuite/ext/allocators.cc
index b3068e0b2dd..58152145e7e 100644
--- a/libstdc++-v3/testsuite/ext/allocators.cc
+++ b/libstdc++-v3/testsuite/ext/allocators.cc
@@ -20,7 +20,6 @@
// 20.4.1.1 allocator members
-#undef __USE_MALLOC
#include
#include
#include