HEBench
|
Backend engines are expected to be shared libraries (.so in Linux, .dll in Windows) that expose the API Bridge functionality. The functionality can be implemented by directly defining the required functions specified in the hebench::APIBridge or extending the C++ wrapper hebench::cpp .
The C++ wrapper offers a collection of pre-defined classes and functionality designed to ease the creation of backends by hiding boilerplate details required by the C API.
Backends created by extending the C++ wrapper require linking to a pre-compiled archive (.a in Linux, .lib in Windows). In contrast to the header-only API Bridge, the C++ wrapper archive can be generated by building the API Bridge project. This will also generate a simple example backend that uses the C++ wrapper.
For full information, check the full reference below, and for a practical use example, see the tutorial at the end of this page.
The C++ wrapper offers a variety of helper classes and functionality to ease development of backends. Users must extend classes hebench::cpp::BaseEngine
, hebench::cpp::BenchmarkDescription
, and hebench::cpp::BaseBenchmark
to create a backend.
As communication between Test Harness and a backend through API Bridge occurs via opaque handles of type hebench::APIBridge::Handle
, C++ wrapper offers a handy set of methods, part of hebench::cpp::BaseEngine
to assist on the creation of and extraction of information from opaque handles.
Templated method hebench::cpp::BaseEngine::createHandle()
allows for the creation of an opaque handle that wraps around the constructed object. As part of its parameters, it takes the parameters to construct the object getting wrapped. It is convenient to use CopyConstructible
or CopyMovable
objects as it may be easier to construct an object and modify it before wrapping it in a handle. This method also allows for tagging and checks that the tag respects the C++ wrapper convention.
Users can call templated method hebench::cpp::BaseEngine::retrieveFromHandle()
to retrieve a reference to an object wrapped in an opaque handle by createHandle()
method. It also allows for tag checking to make sure that handle contains the correct information.
Method hebench::cpp::BaseEngine::duplicateHandle()
allows the shallow duplication of handles created by createHandle()
, ensuring correct destruction order by keeping reference count of all the duplicated handles pointing to the same underlying object. This is a useful method when an API Bridge function needs to return its input handle(s) as results since most API Bridge functions require that returned handles are valid even after the input handles used to generate the result are destroyed. Note that as shallow copies, duplicated handles point to the same underlying object; therefore, modifying this object will affect all handles that point to it. Users must provide their own mechanisms to perform deep copies if and when required.
Opaque handles expose a tag
field of type std::int64_t
. The tag field is designed for backends to identify their handles and be able to retrieve and process the information contained in the opaque handle correctly.
The values and usage of the tag
are backend dependent and can be anything. However, backends that extend C++ wrapper must be aware that the 8 most significant bits of the tag
are reserved for use by the C++ wrapper. Attempts to modify these bits may result in unexpected behavior. As a consequence, backends may use the remaining 56 least significant bits of the tag
for their purposes. See hebench::cpp::ITaggedObject
for more information.
The preferred way to report an error inside a C++ wrapper-enabled backend is by throwing an exception of type hebench::cpp::HEBenchError
. This type of exception is interpreted by the wrapper and converted to the appropriate error, updating all related functionality expected by the API Bridge.
The error code for hebench::cpp::HEBenchError
must be an error code compatible with hebench::APIBridge::ErrorCode
.
The message is whichever message users expect to be associated with this error. Macros HEBERROR_MSG_CLASS
and HEBERROR_MSG
offer shortcuts that will create messages containing the file name, function, line number, etc. where the error was thrown. Macro HEBERROR_MSG_CLASS
can only be used inside a class where macro HEBERROR_DECLARE_CLASS_NAME
has been added to the class definition. See examples and tutorial for more information on using these macros.