Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed size buffers manager #1807

Merged
merged 10 commits into from
Oct 3, 2018
Merged

Conversation

valegagge
Copy link
Member

In this PR I developed the FixedSizeBufferManager, a manager of fixed size buffers for multi-threads environment.
The buffers are allocated when the manager is created and the user can get a buffer, uses and releases it when he/she doesn't need anymore. If all buffers are busy and a new buffer is required, than the manager creates new one.

I used FixedSizeBufferManager in the "implementation" layer of Control Board interfaces in order to remove all dynamic allocations.. Please see #1684.

@valegagge valegagge requested a review from drdanz July 19, 2018 08:04
Copy link
Member

@Nicogene Nicogene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check the code in its functionality, the amount of peaky comments is due to the fact that introducing new classes in YARP_OS is very delicate, sorry 😅
Speaking about, I'm not sure that these classes( as the one of this PR #1516 ) should stay in YARP_OS, but another proper library should be created(cc @drdanz) .

The last 2 comments:

  • Missing some lines in the changelog.
  • Missing tests

The last point is very important, each new class introduced should have a test, otherwise maintain it become very difficult.

Probably this PR should be merged in yarp 3.2.0, since there is the feature freeze until 3.1.0 is released(cc @drdanz).



template <typename T>
yarp::os::Buffer<T>::Buffer():key(0), dataPtr(nullptr), numOfElements(0){;}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra ;

yarp::os::Buffer<T>::Buffer():key(0), dataPtr(nullptr), numOfElements(0){;}

template <typename T>
yarp::os::Buffer<T>::~Buffer(){;}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra ;

if(index<numOfElements)
return dataPtr[index];
else
throw std::out_of_range("yarp::os::Buffer::getValue(index): index is out f range");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure to introduce exceptions in yarp?
They are a good thing if they are handled through try{} catch{} statement, bad otherwise.
In other yarp containers if the index is out of range usually a dummy object is returned ( return T();)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behaviour of buffer is quite equal to std::vector regarding excpetions: std::vector lauches an std::out_of_range exception when a std::vector::at(index) function is called with a wrong index; in the same way, yarp::os::Buffer launches the same exception when set/get functions are invoked with a wrong index.
Both std::vector and yarp::os::Buffer has operator [] that lets user to access an element without any check of index.

Moreover in yarp we use the std::vector and if no try-catch statements is used is a developer's choise.
For example I dind't use the try-catch in implementation layer, because when I access to a buffer's element I'm sure that the index is minor of its size.

* If @index is not minor of size of buffer than a std::out_of_range is thrown.
*
*/
void setValue(uint32_t index, T value) throw (std::out_of_range);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the other comment about exceptions


#include "FixedSizeBuffersManager-inl.h"

#endif // YARP_OS_FIXEDSIZEBUFFERSMANAGER_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing endline at the end of the file


// Defined in this file:
namespace yarp { namespace os { template <typename T> class FixedSizeBuffersManager; }}
namespace yarp { namespace os { template <typename T> class Buffer; }}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can remove these 2 forward declarations, you don't need them

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, you are wrong.
We need them because `FixedSizeBufferManager' is a friend class of Buffer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right ! Yet another reason why I don't like friend classes 😬

m_mutex.lock();
//get fisrt free buffer
Buffer<T> buffer;
uint32_t i;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing initialization of i


private:
uint32_t key;
T* dataPtr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how is feasible but for new classes I discourage the usage of C pointers, I'd prefer std::unique_ptr.
unique_ptr has overhead only in constructor and destructor if they are not trivial, but it is not the case if T is a literal type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think std::unique_ptr is a good feature that let developer to forget delete statements, but in this case I prefer continue to use pointer C style, because this is a Manager of buffer and its abojective is alloc and dealloc memory in the right moment.

Moreover, I already tested the buffer and it works.
So I don't see the need to change something to seems ok without add real improvements.

The std::unique_ptr can be use in user-code where it is necessary to allocate and to deallocate memory most frequently, in order to avoid the usual bug about delete (forgot a delete or delete something not exists anymore)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the Buffer does not own the memory pointed by dataPtr (that is actually owned by FixedSizeBuffersManager, and "shared" with the Buffer object), so I do not think that unique_ptr can be used here.

*/

template <typename T>
class Buffer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing YARP_OS_api

*
*/
template <typename T>
class FixedSizeBuffersManager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing YARP_OS_api

Copy link
Member

@Nicogene Nicogene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussed f2f with @valegagge, long story short:
This class will be integrated in yarp 3.2.0, probably in a different library respect YARP_OS, for this reason changelog and tests are not already provided.
All the comment about the implementation will be ignored for now, and rekindled once we will find a place for these classes 😅

But Travis and Appveyor are failing, we should fix it 🤔

@Nicogene Nicogene changed the title Fixed size buffers manager [WIP] Fixed size buffers manager Jul 19, 2018
@Nicogene Nicogene added PR Type: Feat/Enh This PR adds some new feature or enhances some part of YARP Component: Devices PR Status: Changelog - Not OK This PR does not have a changelog entry, or the changelog needs to be fixed PR Status: Commits - Not OK Commits in this PR needs to be squashed or re-organized PR Status: Rebase - Not OK This PR needs to be rebased over the latest commit in the target branch Target: YARP v3.2.0 labels Jul 19, 2018
@valegagge
Copy link
Member Author

Since the FixedSizeBuffer and Buffer classes have been developed for general porpouse, I think their should be added in the basic part of yarp, where there are all classes general porpouse. I know that @drdanz and you are working to separate general porpouse code in a approppriate namespace. So, please feel free to move these classes in the new namespace.

If you need a start point to develop test you can use this files:
https://github.com/valegagge/my_appls/blob/master/buffersHelperTest_RFModule/src/buffHelpTest.cpp
https://github.com/valegagge/my_appls/blob/master/buffersHelperTest_RFModule/src/buffHelpTest.h
They are not the last version, but I lost it. sorry!

@randaz81
Copy link
Member

There are some typos in the comments, so I recommended to turn on the spell checker in the IDE.
Probably it is a good idea to complete tests and add them to this PR before merging.

@randaz81
Copy link
Member

I would rename class Buffer into something else, e.g. ManagedBuffer.
It is better to avoid names that are too general, they may generate confusion, especially in yarp that already employs classes with similar names.

@traversaro
Copy link
Member

traversaro commented Jul 20, 2018

General comment: the yarp::os::Buffer, except for the key attribute and the friendship discussed in https://github.com/robotology/yarp/pull/1807/files#r203654714 , is quite similar to the upcoming C++20 std::span class, for which we discussed introducing a YARP-compatible equivalent in #1750 (comment) and #1582 (comment) (we already did something similar in iDynTree that can be directly imported, see robotology/idyntree#434).

I am not really sure if it is fair to block @valegagge work on this, but perhaps it could make sense to refactor the yarp::os::Buffer in something std::span API-compatible and just have a small class/struct that contains a yarp::Span (regardless of how it is actually called) and a key for the use of the FixedSizeBufferManager. @drdanz @Nicogene

int *modes_tmp=new int [nj];
for(int idx=0; idx<nj; idx++)
Buffer<int> buffValues = buffManager->getBuffer();
for(int idx=0; idx<castToMapper(helper)->axes(); idx++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would simplify the code using nj instead castToMapper(helper)->axes().
Same in all other interfaces.
Additionally, we are in the process of replacing all these int to size_t.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@randaz81 for semplify do you mean "more performing" or "more readable"?
I think that in both case with don't get an andvantage
Anyway feel free to sobstitute nj with castToMapper(helper)->axes() and int with size_t.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just readable.. I can't find any good reason to ask to some else an info that I already know...

@valegagge
Copy link
Member Author

About the name of class Buffer, you can choose wich you prefer, then we need to find/replace only in all implement control board interfaces.
For me is ok ManagedBuffer or we can change the word buffer in array. Other proposals?

Instead about std::span, if someone would like to change the implementation can do (since code is open) but before I would like to merge this PR.

@Nicogene
Copy link
Member

Nicogene commented Jul 20, 2018

I like very much the idea of @traversaro to uniform the class to the std::span in order to, one day, replace it when we will support c++20.

He is right about not stopping the work of @valegagge , my advice is to fix the typos and minor issues of this PR, make happy travis and appveyor(I didn't check what is the problem) and make these classes impl, so invisible to the user for now, but used by us internally in the ControlBoardImpl.

This will give us more freedom, in the future changing its name, api etc without any problem of backward compatiblity

@Nicogene
Copy link
Member

Nicogene commented Jul 20, 2018

Tip for fixing typos:

$ pip install codespell
$ cd $YARP_ROOT/src/libYARP_OS/include/yarp/os
$ codespell -w ./FixedSizeBuffersManager.h  ./FixedSizeBuffersManager-inl.h

@drdanz drdanz force-pushed the fixedSizeBuffersManager branch from 8e1e090 to 4f70a12 Compare August 2, 2018 16:24
Copy link
Member

@drdanz drdanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest I'm not confortable with adding new classes to yarp::os, I'm moving it to yarp/dev/impl...

uint32_t yarp::os::Buffer<T>::getSize() {return numOfElements;}

template <typename T>
T yarp::os::Buffer<T>::getValue(uint32_t index) throw (std::out_of_range)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw (std::out_of_range) is deprecated

{
}
doubleBuffManager(nullptr),
intBuffManager(nullptr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a -Wreorder warning

Buffer<int> buffJoints = intBuffManager->getBuffer();
Buffer<double> buffValues = doubleBuffManager->getBuffer();

if(n_joint > intBuffManager->getBufferSize())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes a -Wsign-compare warning

@drdanz drdanz force-pushed the fixedSizeBuffersManager branch from 4f70a12 to 113976f Compare August 2, 2018 16:27
@Nicogene
Copy link
Member

The failures are in ControlBoardRemapperTest both in appveyor and travis.

@valegagge
Copy link
Member Author

Hi @drdanz,
if I understand the log of appVeyor in the right way, the error is due to controlBoardremapperTest.
I run the same test on devel branch and it fails anyway.

How can we move on?

@valegagge valegagge force-pushed the fixedSizeBuffersManager branch from a812ffa to d6b3eb4 Compare October 3, 2018 11:54
@Nicogene Nicogene added PR Status: Changelog - Not Required This PR does not need a changelog entry PR Status: Commits - OK Commits in this PR are OK PR Status: Rebase - OK This PR does not need to be rebased PR Status: Copyright - OK Files in this PR don't have copyright issues and removed PR Status: Changelog - Not OK This PR does not have a changelog entry, or the changelog needs to be fixed PR Status: Commits - Not OK Commits in this PR needs to be squashed or re-organized PR Status: Rebase - Not OK This PR needs to be rebased over the latest commit in the target branch labels Oct 3, 2018
@Nicogene
Copy link
Member

Nicogene commented Oct 3, 2018

Since now they have move to the impl part of YARP_dev, no update to the changelog is required.
Am I right @drdanz ?

Copy link
Member

@Nicogene Nicogene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, if it has been successfully tested on the robots we can merge it 👍

@drdanz
Copy link
Member

drdanz commented Oct 3, 2018

Since now they have move to the impl part of YARP_dev, no update to the changelog is required.

Confirming this. Perhaps we should rebase this over master if it became just bugfix, but I'm not 100% sure it is worth, @valegagge what do you think?
Anyway, let's merge this if it finally builds, we can cherry-pick the branch later

@drdanz
Copy link
Member

drdanz commented Oct 3, 2018

Actually there are several changes in the "protected" part of the public interfaces, therefore it should not be in master, please forget about my previous comment.

@valegagge valegagge changed the title [WIP] Fixed size buffers manager Fixed size buffers manager Oct 3, 2018
@drdanz drdanz merged commit 1248a5b into robotology:devel Oct 3, 2018
@drdanz
Copy link
Member

drdanz commented Oct 3, 2018

Merged, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: Devices PR Status: Changelog - Not Required This PR does not need a changelog entry PR Status: Commits - OK Commits in this PR are OK PR Status: Copyright - OK Files in this PR don't have copyright issues PR Status: Rebase - OK This PR does not need to be rebased PR Type: Feat/Enh This PR adds some new feature or enhances some part of YARP Resolution: Merged Target: YARP v3.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants