Skip to content

Commit 43861c0

Browse files
committed
Reenable serialization of std::shared_ptr, making std::weak_ptr serialization dependent on SST_SERIALIZE_WEAK_PTR
1 parent 5f6c6a6 commit 43861c0

File tree

6 files changed

+49
-19
lines changed

6 files changed

+49
-19
lines changed

src/sst/core/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ nobase_dist_sst_HEADERS = \
110110
serialization/impl/serialize_insertable.h \
111111
serialization/impl/serialize_optional.h \
112112
serialization/impl/ser_shared_ptr_tracker.h \
113+
serialization/impl/serialize_shared_ptr.h \
113114
serialization/impl/serialize_tuple.h \
114115
serialization/impl/serialize_unique_ptr.h \
115116
serialization/impl/serialize_utility.h \
@@ -243,6 +244,7 @@ sst_core_sources = \
243244
serialization/impl/mapper.cc \
244245
serialization/impl/serialize_array.cc \
245246
serialization/impl/serialize_trivial.cc \
247+
serialization/impl/serialize_shared_ptr.cc \
246248
sstinfo.h \
247249
interfaces/TestEvent.cc \
248250
interfaces/stdMem.cc \

src/sst/core/serialization/impl/serialize_shared_ptr.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[], in
2828
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[], int[], int>>;
2929
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[], int[], size_t>>;
3030
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[], size_t>>;
31+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int, int[10], int>>;
32+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int, int[10], size_t>>;
33+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int>>;
34+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int[10], int>>;
35+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int[10], size_t>>;
36+
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], size_t>>;
37+
38+
#if SST_SERIALIZE_WEAK_PTR
39+
3140
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int, int>>;
3241
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int, int[], int>>;
3342
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int, int[], size_t>>;
@@ -36,13 +45,6 @@ template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[], int[
3645
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[], int[], int>>;
3746
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[], int[], size_t, std::shared_ptr<int[]>>>;
3847
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[], int[], size_t>>;
39-
40-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int, int[10], int>>;
41-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int, int[10], size_t>>;
42-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int>>;
43-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int[10], int>>;
44-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], int[10], size_t>>;
45-
template class serialize_impl<pvt::shared_ptr_wrapper<std::shared_ptr, int[10], size_t>>;
4648
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int, int[10], int>>;
4749
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int, int[10], size_t>>;
4850
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[10], int[10], int, std::shared_ptr<int[10]>>>;
@@ -51,4 +53,6 @@ template class serialize_impl<
5153
pvt::shared_ptr_wrapper<std::weak_ptr, int[10], int[10], size_t, std::shared_ptr<int[10]>>>;
5254
template class serialize_impl<pvt::shared_ptr_wrapper<std::weak_ptr, int[10], int[10], size_t>>;
5355

56+
#endif // SST_SERIALIZE_WEAK_PTR
57+
5458
} // namespace SST::Core::Serialization

src/sst/core/serialization/impl/serialize_shared_ptr.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#ifndef SST_CORE_SERIALIZATION_IMPL_SERIALIZE_SHARED_PTR_H
1313
#define SST_CORE_SERIALIZATION_IMPL_SERIALIZE_SHARED_PTR_H
1414

15+
// Many older versions of C++ libraries do not support std::weak_ptr correctly, especially std::weak_ptr with arrays.
16+
// If a macro test can be found to disable SST_SERIALIZE_WEAK_PTR on platforms which have std::weak_ptr bugs but enable
17+
// it on all others, it should be used here.
18+
#define SST_SERIALIZE_WEAK_PTR 0
19+
1520
#ifndef SST_INCLUDING_SERIALIZE_H
1621
#warning \
1722
"The header file sst/core/serialization/impl/serialize_shared_ptr.h should not be directly included as it is not part of the stable public API. The file is included in sst/core/serialization/serialize.h"
@@ -83,15 +88,25 @@ template <template <class> class PTR_TEMPLATE, class PTR_TYPE>
8388
std::pair<size_t, bool>
8489
get_shared_ptr_owner_tag(const PTR_TEMPLATE<PTR_TYPE>& ptr, serializer& ser)
8590
{
91+
92+
#if SST_SERIALIZE_WEAK_PTR
8693
// Workaround for libstdc++ bug 120561 which prevents converting std::weak_ptr<array> to std::weak_ptr<const void>
8794
if constexpr ( std::conjunction_v<is_same_template<PTR_TEMPLATE, std::weak_ptr>, std::is_array<PTR_TYPE>> ) {
8895
// We set weak_ptr on a separate statement so that ptr's shared_ptr refcount is restored before return statement
8996
std::weak_ptr<const void> weak_ptr = ptr.lock();
9097

9198
// Return this function using the newly cast std::weak_ptr<const void> instead of std::weak_ptr<array>
9299
return get_shared_ptr_owner_tag(weak_ptr, ser);
100+
101+
// End of workaround. This constexpr-if-branch should be removed at some point, but not before
102+
// SST_SERIALIZE_WEAK_PTR is enabled and undergoes many rounds of testings on many platforms.
103+
// This libstdc++ workaround bug has lasted much longer than other more serious std::weak_ptr
104+
// bugs without practical workarounds, which require totally disabling SST_SERIALIZE_WEAK_PTR.
93105
}
94-
else {
106+
else
107+
#endif // SST_SERIALIZE_WEAK_PTR
108+
109+
{
95110
if ( ser.mode() == serializer::SIZER )
96111
return ser.sizer().get_shared_ptr_owner_tag(ptr);
97112
else
@@ -382,6 +397,8 @@ class serialize_impl<std::shared_ptr<PTR_TYPE>,
382397
SST_FRIEND_SERIALIZE();
383398
};
384399

400+
#if SST_SERIALIZE_WEAK_PTR
401+
385402
// Serialize a std::weak_ptr, assuming that it points to the beginning of the managed object.
386403
// For std::weak_ptr to unbounded arrays with runtime size, the wrapper function must be used.
387404
// std::weak_ptr to functions is not supported.
@@ -405,6 +422,8 @@ class serialize_impl<std::weak_ptr<PTR_TYPE>,
405422
SST_FRIEND_SERIALIZE();
406423
};
407424

425+
#endif // SST_SERIALIZE_WEAK_PTR
426+
408427
namespace pvt {
409428

410429
// Wrapper class which references a std::shared_ptr or std::weak_ptr and a std::shared_ptr which manages ownership
@@ -519,6 +538,8 @@ shared_ptr(std::shared_ptr<PTR_TYPE>& ptr)
519538
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
520539
// std::weak_ptr wrappers
521540

541+
#if SST_SERIALIZE_WEAK_PTR
542+
522543
// SST_SER( SST::Core::Serialization::weak_ptr( std::weak_ptr&, std::shared:ptr& ) ) serializes a std::weak_ptr with a
523544
// parent std::shared_ptr managing the owned object.
524545
template <class PTR_TYPE, class PARENT_TYPE>
@@ -558,6 +579,8 @@ weak_ptr(std::weak_ptr<PTR_TYPE>& ptr)
558579
return ptr;
559580
}
560581

582+
#endif // SST_SERIALIZE_WEAK_PTR
583+
561584
} // namespace SST::Core::Serialization
562585

563586
#endif // SST_CORE_SERIALIZATION_IMPL_SERIALIZE_SHARED_PTR_H

src/sst/core/serialization/serialize.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ sst_ser_or_helper(Args... args)
425425
#include "sst/core/serialization/impl/serialize_bitset.h"
426426
#include "sst/core/serialization/impl/serialize_insertable.h"
427427
#include "sst/core/serialization/impl/serialize_optional.h"
428-
// Disable until more stable across platforms
429-
// #include "sst/core/serialization/impl/serialize_shared_ptr.h"
428+
#include "sst/core/serialization/impl/serialize_shared_ptr.h"
430429
#include "sst/core/serialization/impl/serialize_string.h"
431430
#include "sst/core/serialization/impl/serialize_trivial.h"
432431
#include "sst/core/serialization/impl/serialize_tuple.h"

src/sst/core/testElements/coreTest_Serialization.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ checkSameOwner(const T1& t1, const T2& t2)
757757
}
758758

759759
// Compare two std::shared_ptr
760-
/*template <typename T>
760+
template <typename T>
761761
bool
762762
checkSharedPtr(
763763
const std::shared_ptr<T>& p1, const std::shared_ptr<T>& p2, size_t* p1_size = nullptr, size_t* p2_size = nullptr)
@@ -781,9 +781,9 @@ checkSharedPtr(
781781
else
782782
return objectEqual(*reinterpret_cast<T*>(p1.get()), *reinterpret_cast<T*>(p2.get()));
783783
}
784-
*/
784+
785785
// Compare two std::weak_ptr
786-
/*template <typename T>
786+
template <typename T>
787787
bool
788788
checkSharedPtr(
789789
const std::weak_ptr<T>& p1, const std::weak_ptr<T>& p2, size_t* p1_size = nullptr, size_t* p2_size = nullptr)
@@ -800,9 +800,9 @@ checkSharedPtr(const std::tuple<T...>& p1, const std::tuple<T...>& p2)
800800
[&](auto&&... p1s) { return std::apply([&](auto&&... p2s) { return (checkSharedPtr(p1s, p2s) && ...); }, p2); },
801801
p1);
802802
}
803-
*/
803+
804804
// Test std::shared_ptr and std::weak_ptr
805-
/*void
805+
void
806806
testSharedPtr(Output& output, const std::unique_ptr<SST::RNG::Random>& rng)
807807
{
808808
auto test = [&](auto value, auto rand) {
@@ -830,6 +830,7 @@ testSharedPtr(Output& output, const std::unique_ptr<SST::RNG::Random>& rng)
830830
}
831831
}
832832

833+
#if SST_SERIALIZE_WEAK_PTR
833834
// a duplicated std::shared_ptr with a std::weak_ptr
834835
{
835836
std::shared_ptr<T> in1 = std::make_shared<T>(rand()), in2 = in1;
@@ -854,6 +855,7 @@ testSharedPtr(Output& output, const std::unique_ptr<SST::RNG::Random>& rng)
854855
output.output("ERROR: shared_ptr did not serialize/deserialize properly (test 4)\n");
855856
}
856857
}
858+
#endif // SST_SERIALIZE_WEAK_PTR
857859

858860
// an aliasing std::shared_ptr
859861
{
@@ -955,7 +957,7 @@ testSharedPtr(Output& output, const std::unique_ptr<SST::RNG::Random>& rng)
955957
return v;
956958
});
957959
}
958-
*/
960+
959961
coreTestSerialization::coreTestSerialization(ComponentId_t id, Params& params) :
960962
Component(id)
961963
{
@@ -1028,7 +1030,7 @@ coreTestSerialization::coreTestSerialization(ComponentId_t id, Params& params) :
10281030
checkSimpleSerializeDeserialize<std::string*>::check_all("test_string", out, "std::string*");
10291031
}
10301032
else if ( test == "shared_ptr" ) {
1031-
// testSharedPtr(out, rng);
1033+
testSharedPtr(out, rng);
10321034
}
10331035
else if ( test == "array" ) {
10341036
{

tests/testsuite_default_Serialization.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ def test_Serialization_unique_ptr(self):
7272
def test_Serialization_variant(self):
7373
self.serialization_test_template("variant")
7474

75-
#def test_Serialization_shared_ptr(self):
76-
# self.serialization_test_template("shared_ptr")
75+
def test_Serialization_shared_ptr(self):
76+
self.serialization_test_template("shared_ptr")
7777

7878
def test_Serialization_aggregate(self):
7979
self.serialization_test_template("aggregate")

0 commit comments

Comments
 (0)