-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add channel controller base class (#165)
* Add ChannelController class * Add some ChannelController documentation
- Loading branch information
Showing
5 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/// \file ChannelController.h | ||
/// ChannelController class | ||
|
||
#pragma once | ||
|
||
#include "cali_definitions.h" | ||
|
||
#include <map> | ||
#include <memory> | ||
#include <string> | ||
|
||
namespace cali | ||
{ | ||
|
||
class Caliper; | ||
class Channel; | ||
|
||
typedef std::map<std::string, std::string> config_map_t; | ||
|
||
/// \class ChannelController | ||
/// \brief Base class for %Caliper channel controllers | ||
/// | ||
/// A channel controller wraps a %Caliper configuration and channel. | ||
/// The underlying channel is initially inactive, and will be created | ||
/// in the first call of the start() method. Derived classes can | ||
/// modify the configuration before the channel is created. | ||
/// | ||
/// ChannelController objects can be copied and moved. The underlying | ||
/// %Caliper channel will be deleted when the last ChannelController | ||
/// object referencing is destroyed. | ||
|
||
class ChannelController | ||
{ | ||
struct ChannelControllerImpl; | ||
std::shared_ptr<ChannelControllerImpl> mP; | ||
|
||
protected: | ||
|
||
/// \brief Return the underlying %Caliper channel object. | ||
Channel* channel(); | ||
|
||
/// \brief Provide access to the underlying config map. | ||
/// | ||
/// Note that configuration modifications are only effective before | ||
/// the underlying %Caliper channel has been created. | ||
config_map_t& config(); | ||
|
||
/// \brief Create the channel with the controller's | ||
/// name, flags, and config map | ||
Channel* create(); | ||
|
||
/// \brief Callback function, invoked after the underlying channel | ||
/// has been created. | ||
/// | ||
/// This can be used to setup additional functionality, e.g. | ||
/// registering %Caliper callbacks. | ||
virtual void on_create(Caliper* c, Channel* chn) { } | ||
|
||
public: | ||
|
||
/// \brief Create and activate the %Caliper channel, | ||
/// or reactivate a stopped %Caliper channel. | ||
void start(); | ||
|
||
/// \brief Deactivate the %Caliper channel. | ||
void stop(); | ||
|
||
/// \brief Returns true if channel exists and is active, false otherwise. | ||
bool is_active() const; | ||
|
||
/// \brief Flush the underlying %Caliper channel. | ||
/// | ||
/// Allows derived classes to implement custom %Caliper data processing. | ||
/// The base class implementation invokes Caliper::flush_and_write(). | ||
virtual void flush(); | ||
|
||
/// \brief Create channel controller with given name, flags, and config. | ||
ChannelController(const char* name, int flags, const config_map_t& cfg); | ||
|
||
virtual ~ChannelController(); | ||
}; | ||
|
||
} // namespace cali; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include "caliper/ChannelController.h" | ||
|
||
#include "caliper/common/Log.h" | ||
#include "caliper/common/RuntimeConfig.h" | ||
|
||
#include "caliper/Caliper.h" | ||
|
||
using namespace cali; | ||
|
||
struct ChannelController::ChannelControllerImpl | ||
{ | ||
std::string name; | ||
int flags; | ||
config_map_t config; | ||
|
||
Channel* channel = nullptr; | ||
|
||
ChannelControllerImpl(const char* cname, int cflags, const config_map_t& cfg) | ||
: name(cname), | ||
flags(cflags), | ||
config(cfg) | ||
{ } | ||
|
||
~ChannelControllerImpl() { | ||
if (channel) { | ||
Caliper c; | ||
c.delete_channel(channel); | ||
} | ||
} | ||
}; | ||
|
||
Channel* | ||
ChannelController::channel() | ||
{ | ||
return mP->channel; | ||
} | ||
|
||
config_map_t& | ||
ChannelController::config() | ||
{ | ||
return mP->config; | ||
} | ||
|
||
Channel* | ||
ChannelController::create() | ||
{ | ||
if (mP->channel) | ||
return mP->channel; | ||
|
||
RuntimeConfig cfg; | ||
|
||
cfg.allow_read_env(mP->flags & CALI_CHANNEL_ALLOW_READ_ENV); | ||
cfg.import(mP->config); | ||
|
||
Caliper c; | ||
|
||
mP->channel = c.create_channel(mP->name.c_str(), cfg); | ||
|
||
if (!mP->channel) { | ||
Log(0).stream() << "ChannelController::create(): Could not create channel " | ||
<< mP->name << std::endl; | ||
return nullptr; | ||
} | ||
|
||
if (mP->flags & CALI_CHANNEL_LEAVE_INACTIVE) | ||
c.deactivate_channel(mP->channel); | ||
|
||
on_create(&c, mP->channel); | ||
|
||
return mP->channel; | ||
} | ||
|
||
void | ||
ChannelController::start() | ||
{ | ||
Caliper c; | ||
Channel* chn = mP->channel; | ||
|
||
if (!chn) | ||
chn = create(); | ||
if (chn) | ||
c.activate_channel(chn); | ||
} | ||
|
||
void | ||
ChannelController::stop() | ||
{ | ||
if (mP->channel) | ||
Caliper().deactivate_channel(mP->channel); | ||
} | ||
|
||
bool | ||
ChannelController::is_active() const | ||
{ | ||
return mP->channel && mP->channel->is_active(); | ||
} | ||
|
||
void | ||
ChannelController::flush() | ||
{ | ||
Channel* chn = channel(); | ||
|
||
if (chn) | ||
Caliper().flush_and_write(chn, nullptr); | ||
} | ||
|
||
ChannelController::ChannelController(const char* name, int flags, const config_map_t& cfg) | ||
: mP { new ChannelControllerImpl(name, flags, cfg) } | ||
{ | ||
} | ||
|
||
ChannelController::~ChannelController() | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include "caliper/cali.h" | ||
#include "caliper/ChannelController.h" | ||
|
||
#include "caliper/Caliper.h" | ||
|
||
#include <gtest/gtest.h> | ||
|
||
using namespace cali; | ||
|
||
TEST(ChannelControllerTest, ChannelController) | ||
{ | ||
struct TestCC : public ChannelController { | ||
bool saw_create_callback = false; | ||
Channel* the_channel = nullptr; | ||
|
||
void on_create(Caliper*, Channel* chn) { | ||
saw_create_callback = true; | ||
the_channel = chn; | ||
} | ||
|
||
TestCC() | ||
: ChannelController("testCC", 0, { | ||
{ "CALI_CHANNEL_FLUSH_ON_EXIT", "false" }, | ||
{ "CALI_CHANNEL_CONFIG_CHECK", "false" } | ||
}) | ||
{ } | ||
}; | ||
|
||
TestCC testCC; | ||
|
||
EXPECT_FALSE(testCC.is_active()); | ||
EXPECT_FALSE(testCC.saw_create_callback); | ||
|
||
testCC.stop(); // shouldn't do anything | ||
|
||
testCC.start(); | ||
|
||
EXPECT_TRUE(testCC.is_active()); | ||
EXPECT_TRUE(testCC.saw_create_callback); | ||
|
||
ASSERT_NE(testCC.the_channel, nullptr); | ||
EXPECT_EQ(testCC.the_channel->name(), std::string("testCC")); | ||
|
||
testCC.stop(); | ||
|
||
EXPECT_FALSE(testCC.is_active()); | ||
} |