I have created the above and linked it to the closed STDCXX-1066.
In short, my reading about this issue is that the kernel patch changed the
alignment of the userland mutex objects from a machine word to a double-word
boundary. No changes are required of the users who use such objects in their
programs unless users create mutex objects in buffers which may not be aligned
on a proper boundary. E.g., the following are safe:
mutex_t lock;
struct S {
char misalign;
mutex_t lock;
};
whereas the following is not:
union {
void* align;
char buf [sizeof mutex_t];
} u;
new (&u) mutex_t;
because the alignment requirements for void pointer are less strict than for
mutex_t. A few places in the library use the latter for all sorts of static
objects (mostly local statics). I looked esp. for places where we build objects
that contain mutex sub-objects inside a union-aligned buffer:
struct S {
char c;
mutex_t m;
};
...
union {
void* align; // <- incorrect
char buf [sizeof (S)];
} u;
new (&u) S ();
The alignment must be changed to a value equal or greater than the mutex
alignment requirements.
IMO, the patch I attached does not break binary compatibility. It uses a one
size fits all long double for alignment -- like we use in rw/_mutex.h -- but in
doing so dispenses with all sorts of preprocessor conditionals.
I still don't have access to a SPARC machine. Any feed-back and/or SPARC build
results are more than welcome!
Thanks!
Liviu
Index: src/messages.cpp
===================================================================
--- src/messages.cpp (revision 1390953)
+++ src/messages.cpp (working copy)
@@ -65,7 +65,7 @@ struct __rw_open_cat_data
{
nl_catd catd;
union {
- void *_C_align;
+ long double _C_align;
char _C_data [sizeof (_STD::locale)];
} loc;
};
Index: src/locale_body.cpp
===================================================================
--- src/locale_body.cpp (revision 1390953)
+++ src/locale_body.cpp (working copy)
@@ -1025,7 +1025,7 @@ _C_manage (__rw_locale *plocale, const c
// the classic C locale is statically allocated
// and not destroyed during the lifetime of the process
static union {
- void* _C_align;
+ long double _C_align;
char _C_buf [sizeof (__rw_locale)];
} classic_body;
Index: src/use_facet.h
===================================================================
--- src/use_facet.h (revision 1390953)
+++ src/use_facet.h (working copy)
@@ -64,7 +64,7 @@
else { \
/* construct an ordinary facet in static memory */ \
static union { \
- void *align_; \
+ long double align_; \
char data_ [sizeof (__rw_ ## fid ## _facet)]; \
} f; \
static __rw_facet* const pf = \
@@ -91,7 +91,7 @@
{ \
/* construct an ordinary facet in static memory */ \
static union { \
- void *align_; \
+ long double align_; \
char data_ [sizeof (__rw_ ## fid ## _facet)]; \
} f; \
static __rw_facet* const pf = \
Index: src/ctype.cpp
===================================================================
--- src/ctype.cpp (revision 1390953)
+++ src/ctype.cpp (working copy)
@@ -627,7 +627,7 @@ _RWSTD_EXPORT __rw_facet* __rw_ct_ctype
}
else {
static union {
- void *align_;
+ long double align_;
char data_ [sizeof (_STD::ctype<char>)];
} f;
static __rw_facet* const pf =
Index: src/locale_classic.cpp
===================================================================
--- src/locale_classic.cpp (revision 1390953)
+++ src/locale_classic.cpp (working copy)
@@ -39,7 +39,7 @@ _RWSTD_NAMESPACE (__rw) {
// static buffer for the classic "C" locale object
static union {
- void* _C_align;
+ long double _C_align;
char _C_buf [sizeof (_STD::locale)];
} __rw_classic;