From d9bdcf729783afbd32ec8d030cd49455dff88e9b Mon Sep 17 00:00:00 2001 From: Matt Spinler Date: Thu, 9 Mar 2017 15:06:23 -0600 Subject: Register procedures For a procedure to be available to run, it needs to have a call to a REGISTER_PROCEDURE macro. This macro wraps a call to a Register class that adds the procedure to the list along with the name to call it. Change-Id: I20d02e8f004c1c726228469465ae89b60ee52d66 Signed-off-by: Matt Spinler --- Makefile.am | 1 + p9_procedures.hpp | 22 -------------- proc_control.cpp | 27 +++++++---------- procedures/p9/start_host.cpp | 2 ++ procedures/p9/vcs_workaround.cpp | 3 ++ registration.cpp | 20 +++++++++++++ registration.hpp | 64 ++++++++++++++++++++++++++++++++++++++++ test/Makefile.am | 2 +- test/utest.cpp | 30 +++++++++++++++++++ 9 files changed, 131 insertions(+), 40 deletions(-) delete mode 100644 p9_procedures.hpp create mode 100644 registration.cpp create mode 100644 registration.hpp diff --git a/Makefile.am b/Makefile.am index 57c0e2c..6f785bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,6 +7,7 @@ openpower_proc_control_SOURCES = \ proc_control.cpp \ cfam_access.cpp \ filedescriptor.cpp \ + registration.cpp \ targeting.cpp \ procedures/p9/start_host.cpp \ procedures/p9/vcs_workaround.cpp diff --git a/p9_procedures.hpp b/p9_procedures.hpp deleted file mode 100644 index 2e7ff1a..0000000 --- a/p9_procedures.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -namespace openpower -{ -namespace p9 -{ - -/** - * @brief Starts the self boot engine on P9 position 0 to kick off a boot. - * @return void - */ -void startHost(); - - -/** - * @brief Performs the 'VCS Workaround' on all P9s in the system. - * @return void - */ -void vcsWorkaround(); - -} -} diff --git a/proc_control.cpp b/proc_control.cpp index 8f6f86c..10c3ffa 100644 --- a/proc_control.cpp +++ b/proc_control.cpp @@ -17,51 +17,44 @@ #include #include #include -#include "p9_procedures.hpp" +#include "registration.hpp" -constexpr auto procedures = -{ - std::make_tuple("startHost", openpower::p9::startHost), - std::make_tuple("vcsWorkaround", openpower::p9::vcsWorkaround) -}; +using namespace openpower::util; -void usage(char** argv) +void usage(char** argv, const ProcedureMap& procedures) { std::cerr << "Usage: " << argv[0] << " [action]\n"; std::cerr << " actions:\n"; for (const auto& p : procedures) { - std::cerr << " " << std::get<0>(p) << "\n"; + std::cerr << " " << p.first << "\n"; } } int main(int argc, char** argv) { + const ProcedureMap& procedures = Registration::getProcedures(); + if (argc != 2) { - usage(argv); + usage(argv, procedures); return -1; } std::string action{argv[1]}; - auto finder = [&action](const auto& p) - { - return std::get<0>(p) == action; - }; - auto procedure = std::find_if(procedures.begin(), procedures.end(), finder); + auto procedure = procedures.find(action); if (procedure == procedures.end()) { - usage(argv); + usage(argv, procedures); return -1; } - auto function = std::get<1>(*procedure); try { - function(); + procedure->second(); } catch (std::exception& e) { diff --git a/procedures/p9/start_host.cpp b/procedures/p9/start_host.cpp index f781e68..a31503b 100644 --- a/procedures/p9/start_host.cpp +++ b/procedures/p9/start_host.cpp @@ -16,6 +16,7 @@ #include #include "cfam_access.hpp" #include "p9_cfam.hpp" +#include "registration.hpp" #include "targeting.hpp" namespace openpower @@ -71,6 +72,7 @@ void startHost() writeRegWithMask(master, P9_CBS_CS, 0x80000000, 0x80000000); } +REGISTER_PROCEDURE("startHost", startHost); } } diff --git a/procedures/p9/vcs_workaround.cpp b/procedures/p9/vcs_workaround.cpp index 64b41c1..07e7fd0 100644 --- a/procedures/p9/vcs_workaround.cpp +++ b/procedures/p9/vcs_workaround.cpp @@ -16,6 +16,7 @@ #include #include "cfam_access.hpp" #include "p9_cfam.hpp" +#include "registration.hpp" #include "targeting.hpp" namespace openpower @@ -60,5 +61,7 @@ void vcsWorkaround() } } +REGISTER_PROCEDURE("vcsWorkaround", vcsWorkaround); + } } diff --git a/registration.cpp b/registration.cpp new file mode 100644 index 0000000..f45f767 --- /dev/null +++ b/registration.cpp @@ -0,0 +1,20 @@ +/** + * Copyright © 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 new file mode 100644 index 0000000..d0dde00 --- /dev/null +++ b/registration.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include +#include +#include +#include + +namespace openpower +{ +namespace util +{ + +using ProcedureName = std::string; +using ProcedureFunction = std::function; +using ProcedureMap = std::map; + +/** + * This macro can be used in each procedure cpp file to make it + * available to the openpower-proc-control executable. + */ +#define REGISTER_PROCEDURE(name, func) \ + namespace func##_ns \ + { \ + openpower::util::Registration r{ \ + std::move(name), std::move(func)}; \ + } + + +/** + * Used to register procedures. Each procedure function can then + * be found in a map via its name. + */ +class Registration +{ + public: + + /** + * Adds the procedure name and function to the internal + * procedure map. + * + * @param[in] name - the procedure name + * @param[in] function - the function to run + */ + Registration(ProcedureName&& name, + ProcedureFunction&& function) + { + procedures.emplace(std::move(name), std::move(function)); + } + + /** + * Returns the map of procedures + */ + static const ProcedureMap& getProcedures() + { + return procedures; + } + + private: + + static ProcedureMap procedures; +}; + +} +} diff --git a/test/Makefile.am b/test/Makefile.am index ce78754..bf86e6a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,4 +13,4 @@ utest_LDFLAGS = -lgtest_main -lgtest $(PTHREAD_LIBS) $(OESDK_TESTCASE_FLAGS) \ $(PHOSPHOR_LOGGING_LIBS) -lstdc++fs utest_SOURCES = utest.cpp -utest_LDADD = $(top_srcdir)/targeting.cpp +utest_LDADD = $(top_srcdir)/targeting.cpp $(top_srcdir)/registration.cpp diff --git a/test/utest.cpp b/test/utest.cpp index d91004d..0d3c2c9 100644 --- a/test/utest.cpp +++ b/test/utest.cpp @@ -17,8 +17,10 @@ #include #include #include +#include "registration.hpp" #include "targeting.hpp" +using namespace openpower::util; using namespace openpower::targeting; namespace fs = std::experimental::filesystem; @@ -98,3 +100,31 @@ TEST_F(TargetingTest, CreateTargets) } } } + + +void func1() +{ + std::cout << "Hello\n"; +} + +void func2() +{ + std::cout << "World\n"; +} + +REGISTER_PROCEDURE("hello", func1); +REGISTER_PROCEDURE("world", func2); + + +TEST(RegistrationTest, TestReg) +{ + int count = 0; + for (const auto& p : Registration::getProcedures()) + { + std::cout << p.first << std::endl; + p.second(); + count++; + } + + ASSERT_EQ(count, 2); +} -- cgit v1.2.1