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]

[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
  
  


   


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