meson: fix static initialization order race condition
When moving over to meson, openpower-proc-control started seg faulting
whenever it was run. It was not even making it to the main() function.
Upon investigation, it was found that when moving to meson, this code
started hitting an issue where the hw procedure registration code was
hitting a common static initialization race condition. Whether you hit
this issue is pretty much at the whim of the compiler and the build
system so Automake did not hit it, but meson does.
The following has a pretty good write up on the issue and how to avoid
it:
https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use-members
This commit utilizes the solution proposed in that doc
Tested:
- Verified that openpower-proc-control built via meson now works as
expected.
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I0ea5ef68e73fe4fa08e9cf8e4e3f1dbc8476a2de
diff --git a/meson.build b/meson.build
index c338266..ddcb411 100644
--- a/meson.build
+++ b/meson.build
@@ -89,7 +89,6 @@
'ext_interface.cpp',
'filedescriptor.cpp',
'proc_control.cpp',
- 'registration.cpp',
'targeting.cpp',
'procedures/common/cfam_overrides.cpp',
'procedures/common/cfam_reset.cpp',
diff --git a/registration.cpp b/registration.cpp
deleted file mode 100644
index 787d6cd..0000000
--- a/registration.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (C) 2017 IBM Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "registration.hpp"
-
-using namespace openpower::util;
-ProcedureMap Registration::procedures{};
diff --git a/registration.hpp b/registration.hpp
index 0f093ff..5b39887 100644
--- a/registration.hpp
+++ b/registration.hpp
@@ -40,7 +40,7 @@
*/
Registration(ProcedureName&& name, ProcedureFunction&& function)
{
- procedures.emplace(std::move(name), std::move(function));
+ procedures().emplace(std::move(name), std::move(function));
}
/**
@@ -48,11 +48,15 @@
*/
static const ProcedureMap& getProcedures()
{
- return procedures;
+ return procedures();
}
private:
- static ProcedureMap procedures;
+ static ProcedureMap& procedures()
+ {
+ static ProcedureMap procMap;
+ return procMap;
+ }
};
} // namespace util
diff --git a/test/utest.cpp b/test/utest.cpp
index fb73fd0..81aae58 100644
--- a/test/utest.cpp
+++ b/test/utest.cpp
@@ -26,8 +26,6 @@
using namespace openpower::util;
using namespace openpower::targeting;
-ProcedureMap Registration::procedures;
-
constexpr auto masterDir = "/tmp";
class TargetingTest : public ::testing::Test