This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC] V3 PATCH: Add support for aligned storage
- From: Gabriel Dos Reis <gdr at nerim dot net>
- To: libstdc++ at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org
- Date: 01 Aug 2002 11:24:14 +0200
- Subject: [RFC] V3 PATCH: Add support for aligned storage
Hi,
It is not uncommon to face the situtation where one wants to reserve
a non-free store memory, suitably aligned for some given types and
later construct objects there. Our implementations of standard C++
IOStream global objects are an example -- see libstdc++-3/src/globals.cc.
Another common example is alloctors (from static storage) for given types.
GCC has the __attribute__((aligned(N))) extension to support
such programming needs. This (library) patch automates the use of that
functionnality in the form of a binary class template
template<typename T, int Alignment = __alignof__ (T)>
struct aligned_storage {
typedef <implementation-defined> type; // see bits/storage.h
// for the details
};
with the following semantics:
1) the first template-parameter is the type for which we want to
provide an aligned storage;
2) the second template-parameter is optional. If explicitly
specified, then it designates the requested alignment; else it is
the natural alignment computed by the compiler.
3) the member "type" is an array of sizeof (T) 'unsigned char's,
aligned as specified by the second template-parameter.
I modified libstdc++-v3/src/globals.cc to take advantage of this new
extension.
User programs may have access to the aligned storage extension through
#include <ext/storage>. The aligned_storage<> template is defined in
the GNU C++ library implementation and extension namespace ::__gnu_cxx.
Comments?
-- Gaby
2002-08-01 Gabriel Dos Reis <gdr@nerim.net>
* include/ext/storage: New file.
* include/bits/storage.h: Like wise.
* src/globals.cc (std): #include "bits/storage.h". Use
aligned_storage<> instead of explicit manual type alignment.
* include/Makefile.am (ext_headers): Add ext/storage
(bits_headers): Add bits/storage.h
* include/Makefile.in: Regenerate.
Index: include/Makefile.am
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/include/Makefile.am,v
retrieving revision 1.41
diff -p -r1.41 Makefile.am
*** include/Makefile.am 25 Jul 2002 00:04:33 -0000 1.41
--- include/Makefile.am 1 Aug 2002 08:57:45 -0000
*************** bits_headers = \
*** 92,97 ****
--- 92,98 ----
${bits_srcdir}/stl_tree.h \
${bits_srcdir}/stl_uninitialized.h \
${bits_srcdir}/stl_vector.h \
+ ${bits_srcdir}/storage.h \
${bits_srcdir}/streambuf.tcc \
${bits_srcdir}/stringfwd.h \
${bits_srcdir}/type_traits.h \
*************** ext_headers = \
*** 158,164 ****
${ext_srcdir}/slist \
${ext_srcdir}/stl_hash_fun.h \
${ext_srcdir}/stl_hashtable.h \
! ${ext_srcdir}/stl_rope.h
# This is the common subset of files that all three "C" header models use.
c_base_srcdir = @C_INCLUDE_DIR@
--- 159,166 ----
${ext_srcdir}/slist \
${ext_srcdir}/stl_hash_fun.h \
${ext_srcdir}/stl_hashtable.h \
! ${ext_srcdir}/stl_rope.h \
! ${ext_srcdir}/storage
# This is the common subset of files that all three "C" header models use.
c_base_srcdir = @C_INCLUDE_DIR@
Index: include/bits/storage.h
===================================================================
RCS file: include/bits/storage.h
diff -N include/bits/storage.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- include/bits/storage.h 1 Aug 2002 08:57:45 -0000
***************
*** 0 ****
--- 1,45 ----
+ // The definition for the GNU -*- C++ -*- aligned storage type.
+
+ // Copyright (C) 2002 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction. Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License. This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+
+ // Written by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ #ifndef _GLIBCPP_STORAGE
+ #define _GLIBCPP_STORAGE 1
+
+ namespace __gnu_cxx
+ {
+ template<typename _Tp, int _Al = __alignof__(_Tp)>
+ struct aligned_storage
+ {
+ typedef unsigned char type[sizeof (_Tp)]
+ __attribute__((__aligned__(_Al)));
+ };
+ }
+
+ #endif // _GLIBCPP_STORAGE
Index: include/ext/storage
===================================================================
RCS file: include/ext/storage
diff -N include/ext/storage
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- include/ext/storage 1 Aug 2002 08:57:45 -0000
***************
*** 0 ****
--- 1,40 ----
+ // The definition for the GNU -*- C++ -*- aligned storage extension.
+
+ // Copyright (C) 2002 Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library. This library is free
+ // software; you can redistribute it and/or modify it under the
+ // terms of the GNU General Public License as published by the
+ // Free Software Foundation; either version 2, or (at your option)
+ // any later version.
+
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ // GNU General Public License for more details.
+
+ // You should have received a copy of the GNU General Public License along
+ // with this library; see the file COPYING. If not, write to the Free
+ // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ // USA.
+
+ // As a special exception, you may use this file as part of a free software
+ // library without restriction. Specifically, if other files instantiate
+ // templates or use macros or inline functions from this file, or you compile
+ // this file and link it with other files to produce an executable, this
+ // file does not by itself cause the resulting executable to be covered by
+ // the GNU General Public License. This exception does not however
+ // invalidate any other reasons why the executable file might be covered by
+ // the GNU General Public License.
+
+ // Written by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ #ifndef _GLIBCPP_EXT_STORAGE
+ #define _GLIBCPP_EXT_STORAGE 1
+
+ #pragma GCC system_header
+ #include <bits/storage.h>
+
+ #endif // _GLIBCPP_EXT_STORAGE
+
+
Index: src/globals.cc
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/src/globals.cc,v
retrieving revision 1.8
diff -p -r1.8 globals.cc
*** src/globals.cc 30 Apr 2002 19:04:40 -0000 1.8
--- src/globals.cc 1 Aug 2002 08:57:45 -0000
***************
*** 27,32 ****
--- 27,33 ----
#include "bits/c++config.h"
#include "bits/gthr.h"
+ #include "bits/storage.h"
#include <fstream>
#include <istream>
#include <ostream>
***************
*** 46,203 ****
// allocate the actual file buffers in this file.
namespace std
{
// Standard "C" locale.
! typedef char fake_locale[sizeof(locale)]
! __attribute__ ((aligned(__alignof__(locale))));
! fake_locale c_locale;
!
! typedef char fake_locale_Impl[sizeof(locale::_Impl)]
! __attribute__ ((aligned(__alignof__(locale::_Impl))));
! fake_locale_Impl c_locale_impl;
!
! typedef char fake_facet_vec[sizeof(locale::facet*)]
! __attribute__ ((aligned(__alignof__(locale::facet*))));
! fake_facet_vec facet_vec[_GLIBCPP_NUM_FACETS];
!
! typedef char fake_ctype_c[sizeof(std::ctype<char>)]
! __attribute__ ((aligned(__alignof__(std::ctype<char>))));
! fake_ctype_c ctype_c;
!
! typedef char fake_collate_c[sizeof(std::collate<char>)]
! __attribute__ ((aligned(__alignof__(std::collate<char>))));
! fake_collate_c collate_c;
!
! typedef char fake_numpunct_c[sizeof(numpunct<char>)]
! __attribute__ ((aligned(__alignof__(numpunct<char>))));
! fake_numpunct_c numpunct_c;
!
! typedef char fake_num_get_c[sizeof(num_get<char>)]
! __attribute__ ((aligned(__alignof__(num_get<char>))));
! fake_num_get_c num_get_c;
!
! typedef char fake_num_put_c[sizeof(num_put<char>)]
! __attribute__ ((aligned(__alignof__(num_put<char>))));
! fake_num_put_c num_put_c;
!
! typedef char fake_codecvt_c[sizeof(codecvt<char, char, mbstate_t>)]
! __attribute__ ((aligned(__alignof__(codecvt<char, char, mbstate_t>))));
! fake_codecvt_c codecvt_c;
!
! typedef char fake_moneypunct_c[sizeof(moneypunct<char, true>)]
! __attribute__ ((aligned(__alignof__(moneypunct<char, true>))));
! fake_moneypunct_c moneypunct_tc;
! fake_moneypunct_c moneypunct_fc;
!
! typedef char fake_money_get_c[sizeof(money_get<char>)]
! __attribute__ ((aligned(__alignof__(money_get<char>))));
! fake_money_get_c money_get_c;
!
! typedef char fake_money_put_c[sizeof(money_put<char>)]
! __attribute__ ((aligned(__alignof__(money_put<char>))));
! fake_money_put_c money_put_c;
!
! typedef char fake_timepunct_c[sizeof(__timepunct<char>)]
! __attribute__ ((aligned(__alignof__(__timepunct<char>))));
! fake_timepunct_c timepunct_c;
!
! typedef char fake_time_get_c[sizeof(time_get<char>)]
! __attribute__ ((aligned(__alignof__(time_get<char>))));
! fake_time_get_c time_get_c;
!
! typedef char fake_time_put_c[sizeof(time_put<char>)]
! __attribute__ ((aligned(__alignof__(time_put<char>))));
! fake_time_put_c time_put_c;
!
! typedef char fake_messages_c[sizeof(messages<char>)]
! __attribute__ ((aligned(__alignof__(messages<char>))));
! fake_messages_c messages_c;
#ifdef _GLIBCPP_USE_WCHAR_T
! typedef char fake_wtype_w[sizeof(std::ctype<wchar_t>)]
! __attribute__ ((aligned(__alignof__(std::ctype<wchar_t>))));
! fake_wtype_w ctype_w;
!
! typedef char fake_wollate_w[sizeof(std::collate<wchar_t>)]
! __attribute__ ((aligned(__alignof__(std::collate<wchar_t>))));
! fake_wollate_w collate_w;
!
! typedef char fake_numpunct_w[sizeof(numpunct<wchar_t>)]
! __attribute__ ((aligned(__alignof__(numpunct<wchar_t>))));
! fake_numpunct_w numpunct_w;
!
! typedef char fake_num_get_w[sizeof(num_get<wchar_t>)]
! __attribute__ ((aligned(__alignof__(num_get<wchar_t>))));
! fake_num_get_w num_get_w;
!
! typedef char fake_num_put_w[sizeof(num_put<wchar_t>)]
! __attribute__ ((aligned(__alignof__(num_put<wchar_t>))));
! fake_num_put_w num_put_w;
!
! typedef char fake_wodecvt_w[sizeof(codecvt<wchar_t, char, mbstate_t>)]
! __attribute__ ((aligned(__alignof__(codecvt<wchar_t, char, mbstate_t>))));
! fake_wodecvt_w codecvt_w;
!
! typedef char fake_moneypunct_w[sizeof(moneypunct<wchar_t, true>)]
! __attribute__ ((aligned(__alignof__(moneypunct<wchar_t, true>))));
! fake_moneypunct_w moneypunct_tw;
! fake_moneypunct_w moneypunct_fw;
!
! typedef char fake_money_get_w[sizeof(money_get<wchar_t>)]
! __attribute__ ((aligned(__alignof__(money_get<wchar_t>))));
! fake_money_get_w money_get_w;
!
! typedef char fake_money_put_w[sizeof(money_put<wchar_t>)]
! __attribute__ ((aligned(__alignof__(money_put<wchar_t>))));
! fake_money_put_w money_put_w;
!
! typedef char fake_timepunct_w[sizeof(__timepunct<wchar_t>)]
! __attribute__ ((aligned(__alignof__(__timepunct<wchar_t>))));
! fake_timepunct_w timepunct_w;
!
! typedef char fake_time_get_w[sizeof(time_get<wchar_t>)]
! __attribute__ ((aligned(__alignof__(time_get<wchar_t>))));
! fake_time_get_w time_get_w;
!
! typedef char fake_time_put_w[sizeof(time_put<wchar_t>)]
! __attribute__ ((aligned(__alignof__(time_put<wchar_t>))));
! fake_time_put_w time_put_w;
!
! typedef char fake_messages_w[sizeof(messages<wchar_t>)]
! __attribute__ ((aligned(__alignof__(messages<wchar_t>))));
! fake_messages_w messages_w;
#endif
// Standard stream objects.
! typedef char fake_istream[sizeof(istream)]
! __attribute__ ((aligned(__alignof__(istream))));
! typedef char fake_ostream[sizeof(ostream)]
! __attribute__ ((aligned(__alignof__(ostream))));
! fake_istream cin;
! fake_ostream cout;
! fake_ostream cerr;
! fake_ostream clog;
!
! typedef char fake_filebuf[sizeof(__gnu_cxx::stdio_filebuf<char>)]
! __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<char>))));
! fake_filebuf buf_cout;
! fake_filebuf buf_cin;
! fake_filebuf buf_cerr;
#ifdef _GLIBCPP_USE_WCHAR_T
! typedef char fake_wistream[sizeof(wistream)]
! __attribute__ ((aligned(__alignof__(wistream))));
! typedef char fake_wostream[sizeof(wostream)]
! __attribute__ ((aligned(__alignof__(wostream))));
! fake_wistream wcin;
! fake_wostream wcout;
! fake_wostream wcerr;
! fake_wostream wclog;
!
! typedef char fake_wfilebuf[sizeof(__gnu_cxx::stdio_filebuf<wchar_t>)]
! __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<wchar_t>))));
! fake_wfilebuf buf_wcout;
! fake_wfilebuf buf_wcin;
! fake_wfilebuf buf_wcerr;
#endif
--- 47,136 ----
// allocate the actual file buffers in this file.
namespace std
{
+ using __gnu_cxx::aligned_storage;
+
// Standard "C" locale.
! aligned_storage<locale>::type c_locale;
!
! aligned_storage<locale::_Impl>::type c_locale_impl;
!
! aligned_storage<locale::facet*>::type facet_vec[_GLIBCPP_NUM_FACETS];
!
! aligned_storage<std::ctype<char> >::type ctype_c;
!
! aligned_storage<std::collate<char> >::type collate_c;
!
! aligned_storage<numpunct<char> >::type numpunct_c;
!
! aligned_storage<num_get<char> >::type num_get_c;
!
! aligned_storage<num_put<char> >::type num_put_c;
!
! aligned_storage<codecvt<char, char, mbstate_t> >::type codecvt_c;
!
! aligned_storage<moneypunct<char, true> >::type moneypunct_tc;
! aligned_storage<moneypunct<char, true> >::type moneypunct_fc;
!
! aligned_storage<money_get<char> >::type money_get_c;
!
! aligned_storage<money_put<char> >::type money_put_c;
!
! aligned_storage<__timepunct<char> >::type timepunct_c;
!
! aligned_storage<time_get<char> >::type time_get_c;
!
! aligned_storage<time_put<char> >::type time_put_c;
!
! aligned_storage<messages<char> >::type messages_c;
#ifdef _GLIBCPP_USE_WCHAR_T
! aligned_storage<std::ctype<wchar_t> >::type ctype_w;
!
! aligned_storage<std::collate<wchar_t> >::type collate_w;
!
! aligned_storage<numpunct<wchar_t> >::type numpunct_w;
!
! aligned_storage<num_get<wchar_t> >::type num_get_w;
!
! aligned_storage<num_put<wchar_t> >::type num_put_w;
!
! aligned_storage<codecvt<wchar_t, char, mbstate_t> >::type codecvt_w;
!
! aligned_storage<moneypunct<wchar_t, true> >::type moneypunct_tw;
! aligned_storage<moneypunct<wchar_t, true> >::type moneypunct_fw;
!
! aligned_storage<money_get<wchar_t> >::type money_get_w;
!
! aligned_storage<money_put<wchar_t> >::type money_put_w;
!
! aligned_storage<__timepunct<wchar_t> >::type timepunct_w;
!
! aligned_storage<time_get<wchar_t> >::type time_get_w;
!
! aligned_storage<time_put<wchar_t> >::type time_put_w;
!
! aligned_storage<messages<wchar_t> >::type messages_w;
#endif
// Standard stream objects.
! aligned_storage<istream>::type cin;
! aligned_storage<ostream>::type cout;
! aligned_storage<ostream>::type cerr;
! aligned_storage<ostream>::type clog;
!
! aligned_storage<__gnu_cxx::stdio_filebuf<char> >::type buf_cout;
! aligned_storage<__gnu_cxx::stdio_filebuf<char> >::type buf_cin;
! aligned_storage<__gnu_cxx::stdio_filebuf<char> >::type buf_cerr;
#ifdef _GLIBCPP_USE_WCHAR_T
! aligned_storage<wistream>::type wcin;
! aligned_storage<wostream>::type wcout;
! aligned_storage<wostream>::type wcerr;
! aligned_storage<wostream>::type wclog;
!
! aligned_storage<__gnu_cxx::stdio_filebuf<wchar_t> >::type buf_wcout;
! aligned_storage<__gnu_cxx::stdio_filebuf<wchar_t> >::type buf_wcin;
! aligned_storage<__gnu_cxx::stdio_filebuf<wchar_t> >::type buf_wcerr;
#endif