SystemC/TLM (C++) sharing memory pool; static members, static methods, Singleton or? - c++

Context:
I am writing a specific communication protocol to be used between TLM models (HW blocks described with SystemC and thus C++).
TLM notion is not important, just note that this communication is mimicked by allocating objects, the generic payloads (gps), that are passed between these C++ models of HW blocks.
Aim:
Together with the protocol, I want to provide a memory manager that should be able to efficiently handle the gps; this is quite important since in one simulation lots of gps are constructed, used and destroyed and this can slow down things a lot.
My goal is also to create something simple that could be used by others without efforts.
Issues:
The first issue I had was in creating a single shared pool for all the blocks communicating with that protocol. I thought about creating a static member in the mm class, but then I realized that:
Static members require a definition in the cpp. This makes the mm class less intuitive to use (with different people using this, some will forget to do so) and I would prefer to avoid that.
Depending on where (and in which?) in the cpp file the static variable definition is done, the pool might not have wet the parameters needed to be initialized (i.e., the number of mm instances created).
The second issue is similar to the first one. I want to count the number of instances and thus instead of a pool I need to create a shared counter to be used then by the pool to initialize itself. Again, I wanted to avoid static variable definitions in a cpp file and to guarantee the order of initialization.
I have considered mainly:
static members (discarded for the reasons above)
Singletons (discarded because I don't need to create a whole class for the pool to make it visible by others and single-instanced)
static methods (the approaches I finally picked and that is not far from a complete Singleton)
This is the code I produced (only relevant part included):
/**
* Helper class to count another class' number of instances.
*/
class counter {
public:
// Constructor
counter() : count(0) {}
//Destructor
virtual ~counter() {}
private:
unsigned int count;
public:
unsigned int get_count() {return count;}
void incr_count() {count++;}
void decr_count() {count--;}
};
template <unsigned int MAX = 1>
class mm: public tlm::tlm_mm_interface {
//////////////////////////////TYPEDEFS AND ENUMS/////////////////////////////
public:
typedef tlm::tlm_generic_payload gp_t;
///////////////////////////CLASS (CON/DE)STRUCTOR////////////////////////////
public:
// Constructor
mm() {inst_count().incr_count();}
// Copy constructor
mm(const mm&) {inst_count().incr_count();}
// Destructor
virtual ~mm() {} // no need to decrease instance count in our case
////////////////////////////////CLASS METHODS////////////////////////////////
public:
// Counter for number of isntances.
static counter& inst_count() {
static counter cnt;
return cnt;
}
/* This pattern makes sure that:
-- 1. The pool is created only when the first alloc appears
-- 2. All instances of mm have been already created (known instance sequence)
-- 3. Only one pool exists */
static boost::object_pool<gp_t>& get_pool() {
static boost::object_pool<gp_t> p(
mm<MAX>::inst_count().get_count() * MAX / 2, // creation size
mm<MAX>::inst_count().get_count() * MAX // max size used
);
return p;
}
// Allocate
virtual gp_t* allocate() {
//...
return gp;
}
// Free the generic payload and data_ptr
virtual void free(gp_t* gp) {
//...
get_pool().destroy(gp);
}
}
Now, the initiator block class header should have a member:
mm m_mm;
And the initiator block class cpp should use this like:
tlm_generic_payload* gp;
gp = m_mm.allocate();
//...
m_mm.free(gp); // In truth this is called by gp->release()...
// ...not important here
Having an electronic HW background, I am mainly trying to improve coding style, learn new approaches and optimize speed/memory allocation.
Is there a better way to achieve this? In particular considering my doubts:
It seems to me a not optimal workaround to encapsulate the counter in a class, put it locally (but static) in a static method and then do the same for the pool.
even though SystemC "simulation kernel" is single-threaded, I need to consider a multithread case...I am not sure that the relationship between those two static methods is safe even thou independently they should be safe...with C++03 g++ adds code to guarantee it and with C++11:
ยง6.7 [stmt.dcl] p4 If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
Thanks in advance.

Related

C++ classes vs. C different files

Currently in a project there is a clear set of functions that pertain to a clear responsibility. Because the responsibility is a periodic process that requires buffers and counters for each iteration, I have to reset the variables used by those functions after each cycle. The variables are mostly static because per cycle the functions are called thousands of times. (It is a set of digital FIR filters that process the 5 second data that is coming in every 2 minutes or so). The variables have to be declared in the file scope, because the functions share them. E.g. the reset / initialize function and the actual filter functions.
As of now, the whole project is in C (but C++ is easily supported, as the possibly breaking parts already contain 'extern C {}'). To make the code cleaner, I thought to group the functions and variables in a separate implementation file. But of course, I could also use C++ classes, which I would like to work with more.
What are the essential differences between these options?
Simplified example of what I mean:
In this example, I just kept the structure of the program. The Filter() function is called for example 1000 times in 5 seconds for the first iteration. Then for the next iterations, the Reset() function is called prior to the actual Filter() function calls, to reset all the buffers that are used.
// File-scope variables
static float buffer[BUFFER_SIZE];
static uint8_t bufferOffset = 0;
// Filter
static float Filter (const float sample)
{
buffer[bufferOffset] = sample;
// Removed actual filter code here
return result;
}
// Reset functions
static void Reset (void)
{
memset(buffer, 0, sizeof(buffer));
bufferOffset = 0;
}
The usual approach in C to avoid those shared states is to define a structure encapsulating all the relevant state, pass it to every function and operate solely on it.
Example:
// buffer.h
#pragma once
// opaque data structure whose content
// isn't available to the outside
struct buffer;
// but you may allocate and free such a data structure
struct buffer *alloc_buffer();
void free_buffer(struct buffer *b);
// and you may operate on it with the following functions
float filter_buffer(struct buffer *b);
void reset_buffer(struct buffer *b);
void add_to_buffer(struct buffer *b, const float *data, size_t size);
And the source looks like this:
// buffer.c
#include "buffer.h"
struct buffer {
float content[BUFFER_SIZE];
uint8_t offset;
}
struct buffer *alloc_buffer() {
return malloc(sizeof(struct buffer));
}
void free_buffer(struct buffer *b) {
free(b);
}
float filter_buffer(struct buffer *b) {
// work with b->content and b->offset instead
// on global buffer and bufferOffset
return result;
}
void reset_buffer(struct buffer *b) {
memset(b->content, 0, BUFFER_SIZE);
b->offset = 0;
}
void add_to_buffer(struct buffer *b, const float *data, size_t num) {
memcpy(b->content + b->offset, data, sizeof(float) * num);
b->offset += num;
}
Thus you avoid a global state which for example dramatically simplifies multi-threaded applications of your code. And since you return an opaque data structure, you avoid leaking information about the internal structure of your buffer.
Now you may use this data structure in a different source file:
#include "buffer.h"
int main() {
struct buffer *const b = alloc_buffer();
// b->content[0] = 1; // <-- error, buffer is an opaque data type and
// you may only use the functions declared in
// buffer.h to access and modify it
const float data[2] = { 3.1415926, 2.71828 }
add_to_buffer(b, data, sizeof(data) / sizeof(data[0]));
const float result = filter_buffer(b);
return 0;
}
To answer you question: Even though you could separate your functions and global state even further into several compilation units, in the end you still have a shared global state. Except in some special cases I consider this a code smell.
The above described solution more or less corresponds to a C++ solution. You define a class encapsulating some state and methods operating on it. All instantiated objects are independent from each other.
To declare static file scope variables is the simplest form of private encapsulation. Such design is particularly common in embedded systems and hardware-related code. It's perfectly OK practice in a single-threaded program where there is just one single instance of the module/ADT that uses the variables ("singleton pattern").
Given your simple example, this should be just fine for your specific case. The art of program design is to know when to add extra layers of abstraction and when to avoid them. It isn't easy to teach, this mostly comes with experience.
A rule of thumb for the inexperienced programmer: if you are uncertain how to make the code more abstract, then don't add that extra abstraction. It is very likely to cause more far harm than it does good.
In case the code turns more complex, the next level of abstraction is simply to split it into several related files. Or rather into several .h + .c file pairs.
The point where this turns burdensome is where you need multiple instances of the module doing the same thing. Suppose you need multiple filters using the same code, but getting called by unrelated caller code. Having one set of static variables won't work then.
The sloppy but old school way of taking such abstraction further in C is to make a struct definition visible to the caller, then provide an interface such as void fir_init (fir_t* obj); where obj is allocated on the caller-side. This solves the multiple instances problem, but breaks private encapsulation.
The professional design would rather be to use the concept of opaque types (which is explained in multiple posts elsewhere on this site), where you only expose an incomplete struct type to the caller and let your module handle the allocation. This gives true OO design - you can declare multiple instances of the object while maintaining private encapsulation.
The C++ equivalent of opaque type is class and abstract base classes behave in exactly the same manner as opaque types in C - the caller can declare a pointer/reference to one, but not declare an object. C++ also provides constructors/destructors, which is more convenient than calling some "init" function manually. But this also leads to execution overhead when static storage duration objects have their default constructors called at start-up.
Also, C++ member functions come with their this pointer, so you don't need to pass a pointer to the object along manually. You can also have static members in a class and they behave just like C file scope static, with a single instance shared between all instances.

static members and encapsulation in c++

Let us assume the following class:
class FileManipulator
{
static InputTypeOne * const fileone;
InputTypeTwo *filetwo;
public:
FileManipulator( InputTypeTwo *filetwo )
{
this->filetwo = filetwo;
}
int getResult();
};
FileManipulator uses data from both files to obtain output from getResult(). This means multiple iterations over filetwo and multiple constructions of FileManipulators via iterations for different InputTypeTwo objects. Inputs are, let us say, some .csv databases. InputTypeOne remains the same for the whole task.
The program itself is multi-modular and the operation above is only its small unit.
My question is how can I handle that static field in accordance with the object-oriented paradigm and encapsulation. The field must be initialized somehow since it is not a fixed value over different program executions. As far as I understand C++ rules I cannot create a method for setting the field, but making it public and initializing it outside of any class (FileManipulator or a befriended class) seems to me at odds with the encapsulation.
What can I do then? The only thing that comes to my mind is to do it in a C manner, namely initialize it in an isolated enough compilation unit. Is it really all I can do? How would that be solved in a professional manner?
edit
I corrected pointer to constant to constant pointer, which was my initial intention.
You can write a public static method of FileManipulator that would initialize the field for you:
static void init()
{
fileone = something();
}
And then call it from main() or some place where your program is being initialized.
One way of doing this which comes to mind is:
In the .cpp file
FileManipulator::fileone = NULL;
Then modify constructor to do the following:
FileManipulator( InputTypeTwo *filetwo, InputTypeOne *initValue = NULL)
{
if(fileone == NULL)
{
fileone = initValue;
}
this->filetwo = filetwo;
}
Or you could also define an init function and make sure to call it before using the class and after the CTOR. the init function will include the logic of how to init fileone.

dumb data object holds all common values c++, is this correct

So I am new to c++ and I'm writing for a scientific application.
Data needs to be read in from a few input text files.
At the moment I am storing these input variables in an object. (lets call it inputObj).
Is it right that I have to pass this "inputObj" around all my objects now. It seems like it has just become a complicated version of global variables. So I think I may be missing the point of OOP.
I have created a g++ compilable small example of my program:
#include<iostream>
class InputObj{
// this is the class that gets all the data
public:
void getInputs() {
a = 1;
b = 2;
};
int a;
int b;
};
class ExtraSolver{
//some of the work may be done in here
public:
void doSomething(InputObj* io) {
eA = io->a;
eB = io->b;
int something2 = eA+eB;
std::cout<<something2<<std::endl;
};
private:
int eA;
int eB;
};
class MainSolver{
// I have most things happening from here
public:
void start() {
//get inputs;
inputObj_ = new InputObj();
inputObj_ -> getInputs();
myA = inputObj_->a;
myB = inputObj_->b;
//do some solve:
int something = myA*myB;
//do some extrasolve
extraSolver_ = new ExtraSolver();
extraSolver_ -> doSomething(inputObj_);
};
private:
InputObj* inputObj_;
ExtraSolver* extraSolver_;
int myA;
int myB;
};
int main() {
MainSolver mainSolver;
mainSolver.start();
}
Summary of question: A lot of my objects need to use the same variables. Is my implementation the correct way of achieving this.
Don't use classes when functions will do fine.
Don't use dynamic allocation using new when automatic storage will work fine.
Here's how you could write it:
#include<iostream>
struct inputs {
int a;
int b;
};
inputs getInputs() {
return { 1, 2 };
}
void doSomething(inputs i) {
int something2 = i.a + i.b;
std::cout << something2 << std::endl;
}
int main() {
//get inputs;
inputs my_inputs = getInputs();
//do some solve:
int something = my_inputs.a * my_inputs.b;
//do some extrasolve
doSomething(my_inputs);
}
I'll recommend reading a good book: The Definitive C++ Book Guide and List
my answer would be based off your comment
"Yea I still haven't got the feel for passing objects around to each other, when it is essentially global variables im looking for "
so this 'feel for passing object' will come with practice ^^, but i think it's important to remember some of the reasons why we have OO,
the goal (in it simplified version) is to modularise your code so as increase the reuse segment of code.
you can create several InputObj without redefining or reassignig them each time
another goal is data hiding by encapsulation,
sometimes we don't want a variable to get changed by another function, and we don't want to expose those variable globally to protect their internal state.
for instance, if a and b in your InputObj where global variable declared and initialized at the beginning of your code, can you be certain that there value doesn't get changed at any given time unless you want to ? for simple program yes.. but as your program scale so does the chances of your variable to get inadvertently changed (hence some random unexpected behavior)
also there if you want the initial state of a and b to be preserved , you will have to do it yourself ( more temp global variables? )
you get more control over the flow of your code by adding level abstractions with classes/inheritances/operation overriding/polymorphisms/Abtract and interface and a bunch of other concepts that makes our life easier to build complex architectures.
now while many consider global variable to be evil, i think they are good and useful when used properly... otherwise is the best way to shoot yourself in the foot.
I hope this helped a bit to clear out that uneasy feeling for passing out objects :)
Is using your approach good or not strongly depends on situation.
If you need some high speed calculation you can't provide incapsulation methods for your InputObj class, though they are recommended, because it will strongly reduce speed of calculation.
However there are two rules that your can follow to reduce bugs:
1) Carefully using 'const' keyword every time you really don't want your object to modify:
void doSomething(InputObj * io) -> void doSomething(const InputObj * io)
2) Moving every action related with initial state of the object(in your case, as far as I can guess, your InputObj is loaded from file and thus without this file loading is useless) to constructor:
Instead of:
InputObj() { }
void getInputs(String filename) {
//reading a,b from file
};
use:
InputObj(String filename) {
//reading a,b from file
};
You are right that this way you have implemented global variables, but I would call your approach structured, and not complicated, as you encapsulate your global values in an object. This will make your program more maintainable, as global values are not spread all over the place.
You can make this even nicer by implementing the global object as a singleton (http://en.wikipedia.org/wiki/Singleton_pattern) thus ensuring there is only one global object.
Further, access the object through a static member or function. That way you don't need to pass it around as a variable, but any part of your program can easily access it.
You should be aware that a global object like this will e.g. not work well in a multithreaded application, but I understand that this not the case.
You should also be aware that there is a lot of discussions if you should use a singleton for this kind of stuff or not. Search SO or the net for "C++ singleton vs. global static object"

What is the proper way to handle a large number of interface implementations?

For one of my current projects I have an interface defined for which I have a large number of implementations. You could think of it as a plugin interface with many plugins.
These "plugins" each handle a different message type in a network protocol.
So when I get a new message, I loop through a list of my plugins, see who can handle it, and call into them via the interface.
The issue I am struggling with is how to allocate, initialize, and "load" all the implementations into my array/vector/whatever.
Currently I am declaring all of the "plugins" in main(), then calling an "plugin_manager.add_plugin(&plugin);" for each one. This seems less than ideal.
So, the actual questions:
1. Is there a standardized approach to this sort of thing?
2. Is there any way to define an array (global?) pre-loaded with the plugins?
3. Am I going about this the wrong way entirely? Are there other (better?) architecture options for this sort of problem?
Thanks.
EDIT:
This compiles (please excuse the ugly code)... but it kind of seems like a hack.
On the other hand, it solves the issue of allocation, and cleans up main()... Is this a valid solution?
class intf
{
public:
virtual void t() = 0;
};
class test : public intf
{
public:
test(){}
static test* inst(){ if(!_inst) _inst = new test; return _inst; }
static test* _inst;
void t(){}
};
test* test::_inst = NULL;
intf* ints[] =
{
test::inst(),
NULL
};
Store some form of smart pointer in a container. Dynamically allocate the plugins and register them in the container so that they can be used later.
One possible approach for your solution would be, if you have some form of message id that the plugin can decode, to use a map from that id to the plugin that handles that. This approach allows you to have fast lookup of the plugin given the input message.
One way of writing less code would be to use templates for the instantiation function. Then you only need to write one and put it in the interface, instead of having one function per implementation class.
class intf
{
public:
virtual void t() = 0;
template<class T>
static T* inst()
{
static T instance;
return &instance;
}
};
class test : public intf { ... };
intf* ints[] =
{
intf::inst<test>(),
NULL
};
The above code also works around two bugs you have in your code: One is a memory leak, in your old inst() function you allocate but you never free; The other is that the constructor sets the static member to NULL.
Other tips is to read more about the "singleton" pattern, which is what you have. It can be useful in some situations, but is generally advised against.

Reconciling classes, inheritance, and C callbacks

In my C++ project, I've chosen to use a C library. In my zeal to have a well-abstracted and simple design, I've ended up doing a bit of a kludge. Part of my design requirement is that I can easily support multiple APIs and libraries for a given task (due, primarily, to my requirement for cross-platform support). So, I chose to create an abstract base class which would uniformly handle a given selection of libraries.
Consider this simplification of my design:
class BaseClass
{
public:
BaseClass() {}
~BaseClass() {}
bool init() { return doInit(); }
bool run() { return doWork(); }
void shutdown() { destroy(); }
private:
virtual bool doInit() = 0;
virtual bool doWork() = 0;
virtual void destroy() = 0;
};
And a class that inherits from it:
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass()
: BaseClass(), state_manager(new SomeOtherClass()) {}
int callbackA(int a, int b);
private:
virtual bool doInit();
virtual bool doWork();
virtual void destroy();
SomeOtherClass* state_manager;
};
// LSC.cpp:
bool LibrarySupportClass::doInit()
{
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&LibrarySupportClass::callbackA);
return true;
}
// ... and so on
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks. I would prefer doing all of these callbacks within the class because the class carries a state object.
What I ended up doing is...
static LibrarySupportClass* _inst_ptr = NULL;
static int callbackADispatch(int a, int b)
{
_inst_ptr->callbackA(a, b);
}
bool LibrarySupportClass::doInit()
{
_inst_ptr = this;
if (!libraryInit()) return false;
// the issue is that I can't do this:
libraryCallbackA(&callbackADispatch);
return true;
}
This will clearly do Bad Things(TM) if LibrarySupportClass is instantiated more than once, so I considered using the singleton design, but for this one reason, I can't justify that choice.
Is there a better way?
You can justify that choice: your justification is that the C library only supports one callback instance.
Singletons scare me: It's not clear how to correctly destroy a singleton, and inheritance just complicates matters. I'll take another look at this approach.
Here's how I'd do it.
LibrarySupportClass.h
class LibrarySupportClass : public BaseClass
{
public:
LibrarySupportClass();
~LibrarySupportClass();
static int static_callbackA(int a, int b);
int callbackA(int a, int b);
private:
//copy and assignment are rivate and not implemented
LibrarySupportClass(const LibrarySupportClass&);
LibrarySupportClass& operator=(const LibrarySupportClass&);
private:
static LibrarySupportClass* singleton_instance;
};
LibrarySupportClass.cpp
LibrarySupportClass* LibrarySupportClass::singleton_instance = 0;
int LibrarySupportClass::static_callbackA(int a, int b)
{
if (!singleton_instance)
{
WHAT? unexpected callback while no instance exists
}
else
{
return singleton_instance->callback(a, b);
}
}
LibrarySupportClass::LibrarySupportClass()
{
if (singleton_instance)
{
WHAT? unexpected creation of a second concurrent instance
throw some kind of exception here
}
singleton_instance = this;
}
LibrarySupportClass::~LibrarySupportClass()
{
singleton_instance = 0;
}
My point is that you don't need to give it the external interface of a canonical 'singleton' (which e.g. makes it difficult to destroy).
Instead, the fact that there is only one of it can be a private implementation detail, and enforced by a private implementation detail (e.g. by the throw statement in the constructor) ... assuming that the application code is already such that it will not try to create more than one instance of this class.
Having an API like this (instead of the more canonical 'singleton' API) means that you can for example create an instance of this class on the stack if you want to (provided you don't try to create more than one of it).
The external constraint of the c library dictates that when your callback is called you don't have the identification of the "owning" instance of the callback. Therefore I think that your approach is correct.
I would suggest to declare the callbackDispatch method a static member of the class, and make the class itself a singleton (there are lots of examples of how to implement a singleton). This will let you implement similar classes for other libraries.
Dani beat me to the answer, but one other idea is that you could have a messaging system where the call back function dispatch the results to all or some of the instances of your class. If there isn't a clean way to figure out which instance is supposed to get the results, then just let the ones that don't need it ignore the results.
Of course this has the problem of performance if you have a lot of instances, and you have to iterate through the entire list.
The problem the way I see it is that because your method is not static, you can very easily end up having an internal state in a function that isn't supposed to have one, which, because there's a single instance on the top of the file, can be carried over between invocations, which is a -really- bad thing (tm). At the very least, as Dani suggested above, whatever methods you're calling from inside your C callback would have to be static so that you guarantee no residual state is left from an invocation of your callback.
The above assumes you have static LibrarySupportClass* _inst_ptr declared at the very top. As an alternative, consider having a factory function which will create working copies of your LibrarySupportClass on demand from a pool. These copies can then return to the pool after you're done with them and be recycled, so that you don't go around creating an instance every time you need that functionality.
This way you can have your objects keep state during a single callback invocation, since there's going to be a clear point where your instance is released and gets a green light to be reused. You will also be in a much better position for a multi-threaded environment, in which case each thread gets its own LibrarySupportClass instance.
The problem I've run into is that because this is a C library, I'm required to provide a C-compatible callback of the form int (*)(int, int), but the library doesn't support an extra userdata pointer for these callbacks
Can you elaborate? Is choosing a callback type based on userdata a problem?
Could your callback choose an instance based on a and/or b? If so, then register your library support classes in a global/static map and then have callbackADispatch() look up the correct instance in the map.
Serializing access to the map with a mutex would be a reasonable way to make this thread-safe, but beware: if the library holds any locks when it invokes your callback, then you may have to do something more clever to avoid deadlocks, depending on your lock hierarchy.