Using QtConcurrent::map() function on QList yields segmentation fault - c++

I am familiarizing myself with QtConcurrent library. I have a UI (MainWindow) where I run my functions to simulate a real world example of multithreading.
The QtConcurrent::map() function I am using requires some:
Iterator or a Sequence, in my case I am using a QList.
Further, it requires a MapFunctor (which supports lambdas*) but for this purpose, I am choosing to stick to a static method for testing.
What I have tried
I attempted using both map() functions (the first is left uncommented)
QtConcurrent::map(Sequence &sequence, MapFunctor function
QtConcurrent::map(Iterator begin, Iterator end, MapFunctor function)
I tried searching for a Sequence and a MapFunctor, but I could only find it in templates which did not help alot, thus I had to try and use my intuition to make sense of it.
The Code:
Somewhere inside my MainWindow.cpp
// counter variable stored in MainWindow
int i = 0;
// MapFunctor
void mapSumToQString(QPair<int, int> pair)
{
i++;
qDebug() << "Execute " << i << " = " << QString::number(pair.first, pair.second);;
}
and the code to start it all
// UI class decl
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Create list of integers to perform map function on (here I don't write back to the original sequence i.e. list)
QList<QPair<int, int>> intPairList = QList<QPair<int, int>>();
for (int i = 0; i < 1000; i++) {
int i1 = qrand();
int i2 = qrand();
intPairList.append(QPair<int, int>(i1, i2));
}
QFuture<void> future;
future = QtConcurrent::map(intPairList, mapSumToQString);
// future = QtConcurrent::map(intPairList.begin(), intPairList.end(), mapSumToQString);
}
Problem:
Running this snippet of code results in a SEGV here
namespace QtConcurrent {
// map kernel, works with both parallel-for and parallel-while
template <typename Iterator, typename MapFunctor>
class MapKernel : public IterateKernel<Iterator, void>
{
MapFunctor map;
public:
typedef void ReturnType;
MapKernel(Iterator begin, Iterator end, MapFunctor _map)
: IterateKernel<Iterator, void>(begin, end), map(_map)
{ }
bool runIteration(Iterator it, int, void *) override
{
map(*it); <--------SEGV line
return false;
}
//...
}
Stacktrace (copied from debugger)
1 QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIteration qtconcurrentmapkernel.h 68 0x404ee8
2 QtConcurrent::MapKernel<QList<QPair<int, int>>::iterator, QtConcurrent::FunctionWrapper1<void, QPair<int, int>>>::runIterations qtconcurrentmapkernel.h 77 0x404f82
3 QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::forThreadFunction qtconcurrentiteratekernel.h 255 0x40466e
4 QtConcurrent::IterateKernel<QList<QPair<int, int>>::iterator, void>::threadFunction qtconcurrentiteratekernel.h 217 0x404486
5 QtConcurrent::ThreadEngineBase::run qtconcurrentthreadengine.cpp 302 0x6d881973
6 QThreadPoolThread::run qthreadpool.cpp 99 0x111b36a
7 QThreadPrivate::start(void *) *4 qthread_win.cpp 403 0x11163eb
8 KERNEL32!BaseThreadInitThunk 0x74d56359
9 ntdll!RtlGetAppContainerNamedObjectPath 0x77467c24
10 ntdll!RtlGetAppContainerNamedObjectPath 0x77467bf4
11 ??
For the record, there is another question related to this, but most certainly does not provide a usable solution.
Why do I get this SEGV, what is causing this access violation?

Honestly, some parts of your question are not clear for me. However, please take into account the followings (although you may have considered some or all of them):
the functor is highly recommended to be a static function. From your code, it seems that you may have not declared the static function properly. Please put the following in your MainWindow.h:
static void mapSumToQString(QPair<int, int> pair);
and modify the implementation as follows:
// MapFunctor
void MainWindow::mapSumToQString(QPair<int, int> pair)
{
j++;
qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);;
}
mapSumToQString is static, hence you cannot use non-static members of the MainWindow inside it. Hence, the i must be static as well.
static int j; //in MainWindow.h ---> I changed i to j to make it differ from your For loop variable
int MainWindow::j = 0;//in MainWindow.cpp ----> static variables have to be initialized
Modify MainWindow.cpp as follows:
// counter variable stored in MainWindow
j = 0;
QFuture<void> future;
future = QtConcurrent::map(intPairList, mapSumToQString);
future.waitForFinished();
One thing that I cannot understand is that you are converting an integer to a string with a random base?!
qDebug() << "Execute " << j << " = " << QString::number(pair.first, pair.second);
//Herein, pair.second is random, and hence QString::number's second input (base) is always a random number. Do you really want it?

Related

QLibrary functions work slow on first call

I'm using QLibrary to load functions from one .dll file.
I succesfully load it, succesfully resolve functions.
But when i use some function from that .dll for the first time, this function works very slow(even if it is very simple one). Next time i use it again - and the speed is just fine (immediately, as it should be).
What is the reason for such behaviour? I suspect some caсhing somewhere.
Edit 1: Code:
typedef int(*my_type)(char *t_id);
QLibrary my_lib("Path_to_lib.dll");
my_lib.load();
if(my_lib.isLoaded){
my_type func = (my_type)my_lib.resolve("_func_from_dll");
if(func){
char buf[50] = {0};
char buf2[50] = {0};
//Next line works slow
qint32 resultSlow = func(buf);
//Next line works fast
qint32 resultFast = func(buf2);
}
}
I wouldn't blame QLibrary: func simply takes long the first time it's invoked. I bet that you'll have identical results if you resolve its address using platform-specific code, e.g. dlopen and dlsym on Linux. QLibrary doesn't really do much besides wrapping the platform API. There's nothing specific to it that would make the first call slow.
There is some code smell of doing file I/O in constructors of presumably generic classes: do the users of the class know that the constructor may block on disk I/O and thus ideally shouldn't be invoked from the GUI thread? Qt makes the doing this task asynchronously fairly easy, so I'd at least try to be nice that way:
class MyClass {
QLibrary m_lib;
enum { my_func = 0, other_func = 1 };
QFuture<QVector<FunctionPointer>> m_functions;
my_type my_func() {
static my_type value;
if (Q_UNLIKELY(!value) && m_functions.size() > my_func)
value = reinterpret_cast<my_type>(m_functions.result().at(my_func));
return value;
}
public:
MyClass() {
m_lib.setFileName("Path_to_lib.dll");
m_functions = QtConcurrent::run{
m_lib.load();
if (m_lib.isLoaded()) {
QVector<QFunctionPointer> funs;
funs.push_back(m_lib.resolve("_func_from_dll"));
funs.push_back(m_lib.resolve("_func2_from_dll"));
return funs;
}
return QVector<QFunctionPointer>();
}
}
void use() {
if (my_func()) {
char buf1[50] = {0}, buf2[50] = {0};
QElapsedTimer timer;
timer.start();
auto result1 = my_func()(buf1);
qDebug() << "first call took" << timer.restart() << "ms";
auto result2 = my_func()(buf2);
qDebug() << "second call took" << timer.elapsed() << "ms";
}
}
};

C++ member of class updated outside class

I have a question about pointers and references in C++. I am a programmer who normally programs in C# and PHP.
I have two classes (for now) which are the following.
The X/Y in Controller are continuously changing but i want them up to date in the Commands. I have multiple commands like Forward, Turn, Backward etc.
When i make the commands i give them the controller but the state (X, Y) of the controller are updating every second.
How can i fix that the controller attribute in the Commands are getting updated also every second?
class Forward : ICommand
{
Controller ctrl;
void Execute() {
int CurrentX = ctrl.X;
int CurrentY = ctrl.Y;
//Check here for the current location and calculate where he has to go.
}
}
class Controller
{
int X;
int Y;
void ExecuteCommand(ICommand command) {
command.Execute();
}
}
Main.cpp
Controller controller;
Forward cmd1 = new Forward(1, controller);
Turn cmd2 = new Turn(90, controller);
Forward cmd3 = new Forward(2, controller);
controller.Execute(cmd1);
controller.Execute(cmd2);
controller.Execute(cmd3);
I have read something about pointers and references and i think i have to use this but don't know how to use it in this situation.
(code can have some syntax errors but that's because i typed over. Everything is working further except for the updating).
If you use references rather than copy objects you can see changes.
#include <iostream>
using namespace std;
class ICommand
{
public:
virtual ~ICommand() = default;
virtual void Execute() = 0;
};
class Controller
{
public:
int X = 0;
int Y = 0;
void ExecuteCommand(ICommand & command) {
// ^-------
command.Execute();
}
};//,--- semicolons required
class Forward : public ICommand //note public
{
const int step;
Controller ctrlCopy;
Controller & ctrlReference;
public:
Forward(int step, Controller & ctrl) :
step(step),
ctrlCopy(ctrl), //this is a copy of an object
ctrlReference(ctrl) //this is a reference to an object
{
}
void Execute() {
std::cout << "copy: " << ctrlCopy.X << ", " << ctrlCopy.Y << '\n';
std::cout << " ref: " << ctrlReference.X << ", " << ctrlReference.Y << '\n';
//Check here for the current location and calculate where he has to go.
ctrlCopy.X += 10;
ctrlReference.X += 10;
}
};//<--- semicolons required
int main() {
Controller controller;
Forward cmd1(1, controller);
//Turn cmd2(90, controller); //Left for the OP to do
Forward cmd3(2, controller);
controller.ExecuteCommand(cmd1);
//controller.ExecuteCommand(cmd2);
controller.ExecuteCommand(cmd3);
//Do it again to show the copy and reference difference
std::cout << "Once more, with feeling\n";
controller.ExecuteCommand(cmd1);
controller.ExecuteCommand(cmd3);
}
Giving
copy: 0, 0
ref: 0, 0
copy: 0, 0 // [1]
ref: 10, 0 // [2]
Once more, with feeling
copy: 10, 0
ref: 20, 0
copy: 10, 0
ref: 30, 0
1 shows that the copy has X and Y of 0, while the reference shown in [2] has moved by the stated step (in controller.ExecuteCommand(cmd3))
Note, we don't need to use new to make this work (don't forget delete if you use new).
Also, void ExecuteCommand(ICommand command) now takes a reference instead otherwise the by-value copy does "slicing" (e.g. see here)

Is it better to sort from server and distribute to clients or send unsorted and let clients sort it?

This is an online game and I was paid to implement a game event, which is a Player versus Player game system.
In my design I have a server side class (named PvpEventManager which is the event manager and it processes when a player kills another one, when a player joins or leaves the event, be it by decision, by being disconnected...etc, and has many other functions.
Now, this class also holds a container with the player information during the event (named vPlayerInfo), for all kinds of processing. When a player kills someone else, his kill must be increased and the victim's death too, quite obviously. But it also happens that clients have a scoreboard and since it's the server job to process a kill and tell all other clients connected on the event about this, the container will get updated.
It is necessary that the container be sorted from kill struct member from ascending to descending order so that the scoreboard can be rendered (at client) properly.
What would be better?
To sort the container at server increasing server work and send the already-sorted ready-to-render-at-screen container to all clients.
To send the container unsorted and let every connected game client sort the container itself when receiving it.
Note that the server processes thousands of thousands of packets incoming and outcoming every tick and really processes A LOT, A LOT of other stuff.
This somewhat describes the design of it:
This code describes what is being done when sorting the container on part of the actual code.
#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <algorithm>
struct PlayerScoreBoardInfo
{
std::string name;
unsigned int kill, death, suicide;
unsigned int scorestreak;
PlayerScoreBoardInfo()
{
kill = death = suicide = scorestreak = 0;
name = "";
}
explicit PlayerScoreBoardInfo( std::string strname, unsigned int nkill, unsigned int ndeath, unsigned int nsuicide, unsigned int nscorestreak ) :
name(strname), kill(nkill), death(ndeath), suicide(nsuicide), scorestreak(nscorestreak)
{
}
};
class GameArenaManager
{
private:
GameArenaManager() {}
public:
std::map<u_long, PlayerScoreBoardInfo> m_Infos;
public:
static GameArenaManager& GetInstance()
{
static GameArenaManager InstanceObj;
return InstanceObj;
}
};
template <typename T1, typename T2> inline void SortVecFromMap( std::map<T1,T2>& maptodosort, std::vector<T2>& vectosort )
{
std::vector<T1> feedvector;
feedvector.reserve( maptodosort.size() );
for( const auto& it : maptodosort )
feedvector.push_back(it.second.kill);
std::sort(feedvector.begin(), feedvector.end(), std::greater<T1>());
for(const auto& itV : feedvector ) {
for( const auto& itM : maptodosort ) {
if( itM.second.kill == itV ) {
vectosort.push_back(itM.second );
}
}
}
}
int main()
{
GameArenaManager& Manager = GameArenaManager::GetInstance();
PlayerScoreBoardInfo info[5];
info[0] = PlayerScoreBoardInfo("ArchedukeShrimp", 5,4,0,0);
info[1] = PlayerScoreBoardInfo("EvilLactobacilus", 9,4,0,0);
info[2] = PlayerScoreBoardInfo("DolphinetelyOrcaward", 23,4,0,0);
info[3] = PlayerScoreBoardInfo("ChuckSkeet", 1,4,0,0);
info[4] = PlayerScoreBoardInfo("TrumpMcDuck", 87,4,0,0);
for( int i=0; i<5; i++)
Manager.m_Infos.insert( std::make_pair( i, info[i] ) );
std::vector<PlayerScoreBoardInfo> sortedvec;
SortVecFromMap( Manager.m_Infos, sortedvec );
for( std::vector<PlayerScoreBoardInfo>::iterator it = sortedvec.begin(); it != sortedvec.end(); it++ )
{
std::cout << "Name: " << (*it).name.c_str() << " ";
std::cout << "Kills: " << (*it).kill << std::endl;
}
return 0;
}
Here's a link for ideone compiled code: http://ideone.com/B08y9l
And one link for Wandbox in case you want to edit compile on real time: http://melpon.org/wandbox/permlink/6OVLBGEXiux5Vn34
This question will probably get closed down as "off topic". However,
First question: does the server ever need a sorted scoreboard?
If not, why do the work?
If anything, the server will want to index the scoreboard by player ID, which argues for either sorting by ID (to aid binary searches) or using a hashed container (O1 search time).
Furthermore, the ultimate bottleneck is network bandwidth. You'll eventually want to be in a position to send scoreboard deltas rather than state-of-the-world messages.
This further argues for making the clients do the work of resorting.
There is one more philosophical argument:
Is sorting by anything other than a primary key a data concern or a presentation concern? It's a presentation concern.
What does presentation? A client.
QED

LLVM storing Loop* in std::vector

I've stumbled into something very peculiar - I'm writing an LLVM module Pass. I iterate over all functions of the module and then all loops of every non-declaration function and I store pointers to loops in a std::vector. Here's the source:
virtual bool runOnModule(Module& Mod){
std::vector<Loop*> loops;
// first gather all loop info
for(Module::iterator f = Mod.begin(), fend = Mod.end(); f != fend; ++f){
if (!(*f).isDeclaration()){
LoopInfo& LI = getAnalysis<LoopInfo>(*f);
for(LoopInfo::iterator l = LI.begin(), lend = LI.end(); l != lend; ++l){
loops.push_back(*l);
}
}
}
for (auto& l: loops) errs () << *l << " ";
}
Now if I run this I get a runtime error - it can't print the loops, somehow I'm doing a null pointer dereference or sth. Any ideas?
You have to make sure that the LoopInfo pass actually runs before your pass. Here is a complete example - stanalone from opt:
class AnalyzeLoops : public FunctionPass {
public:
AnalyzeLoops()
: FunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
}
virtual bool runOnFunction(Function &F) {
LoopInfo &LI = getAnalysis<LoopInfo>();
for (LoopInfo::iterator L = LI.begin(), LE = LI.end(); L != LE; ++L) {
(*L)->dump();
}
return false;
}
static char ID;
};
In addition, when creating the passes, do:
PassManager PM;
PM.add(new LoopInfo());
PM.add(new AnalyzeLoops());
PM.run(*Mod);
I suspect that to make opt actually run LoopInfo before your pass, you should pass -loops too.
Also, note that I define getAnalysisUsage - this will make LLVM complain if LoopInfo didn't run before this pass, making the problem more obvious.
Note that LoopInfo is specifically a FunctionPass, and as an analysis it has to be used from another FunctionPass. The LoopInfo data structure doesn't really survive between different functions, and since it owns its data (those Loop* objects) they will be destroyed as well.
One thing you could do if you really need a ModulePass is just invoke LoopInfo manually and not as an analysis. When you iterate the functions in the module, for each function create a new LoopInfo object and use its runOnFunction method. Though even in this case, you have to make sure the LoopInfo that owns a given Loop* survives if you want to use the latter.
First of all LoopInfo should run just once before the for loop.
Secondly LoopInfo::iterator just includes top level loops of the Function. in order to visit all loops you also need to iterate over subloops of every loop. it can be implemented either as recursive function or by WorkList, like this`
virtual bool runOnFunction(Function &F) {
LoopInfo *loopinfo;
loopinfo = &getAnalysis<LoopInfo>();
std::vector<Loop*> allLoops;
for (LoopInfo::iterator Li = loopinfo->begin(), Le = loopinfo->end();
Li != Le; Li++) {
Loop *L = *Li;
allLoops.push_back(L);
dfsOnLoops(L, loopinfo, allLoops);
}
}
void dfsOnLoops(Loop *L, LoopInfo *loopinfo, std::vector<Loop*> LoopS) {
std::vector<Loop *> subloops = L->getSubLoops();
if (subloops.size()) {
// recursive on subloops
for (std::vector<Loop *>::iterator Li = subloops.begin();Li != subloops.end(); Li++){
LoopS.push_back(*Li);
dfsOnLoops(*Li, loopinfo, LoopS);
}
}
}
`
None of the answers really helped but I managed to solve the problem myself. Basically, each llvm pass can define a releaseMemory() method, read more here. The LoopInfo class had that method implemented and thus the analysis information would be lost every time we get out of scope from the call to getAnalysis. I simply removed the releaseMemory() method in Loopinfo.h and the memory was no longer released. Note that this triggered a big change in the codebase and even opt had to be rebuilt so doing this in general is probably a bad idea and this would definitely not be easily accepted as a change to llvm (I speculate, not sure).
I think the best way to solve this is to explicitly create LoopInfo objects and save them. Here is the Code for LLVM 3.5
using LoopInfoType=llvm::LoopInfoBase<llvm::BasicBlock, llvm::Loop>;
std::vector<llvm::Loop*> loopVec;
std::vector<LoopInfoType*> loopInfoVec;
for(llvm::Module::iterator F = M.begin(); F!= M.end(); F++){
//skip declrations
if(F->isDeclaration()){
continue;
}
//TODO that scope problem
llvm::DominatorTree DT = llvm::DominatorTree();
DT.recalculate(*F);
LoopInfoType *loopInfo = new LoopInfoType();
loopInfo->releaseMemory();
loopInfo->Analyze(DT);
loopInfoVec.push_back(loopInfo);
for(llvm::LoopInfo::iterator lit = loopInfo->begin(); lit != loopInfo->end(); lit++){
Loop * L = * lit;
loopVec.push_back(L);
//L->dump();
}
}//for all functions
cin.get();
for(auto loop : loopVec){
std::cout << "loop\n";
loop->dump();
for(llvm::Loop::block_iterator bit = loop->block_begin(); bit != loop->block_end(); bit++){
llvm::BasicBlock * B = * bit;
B->dump();
std::cout << "\n\n";
}
}

Issue with setting speed to DifferentialWheels in Webots C++

Small community here, but hopefully somebody sees this. I'm attempting to do a pure C++ implementation of a Webots simulation for an E-puck. The C++ documentation is sorely lacking, and I can't seem to find a resolution for this issue (the C implementation is stellar, but all the function calls were changed for C++).
Essentially, I'm just trying to get a simple application up and running...I want to make the E-puck move forward. I will post the entirety of my code below...all I'm doing is instantiating a Robot entity, printing out all the IR sensor values, and attempting to move it forward.
The issue is that it does not move. I'd think that there would be some call to link the DifferentialWheel object to the E-puck (similar to the camera = getCamera("camera") call).
If I comment out my call to setSpeed, the program works perfectly (doesn't move, but prints values). If I leave it in, the simulation freezes up after a single step, once it gets to that call. I'm not exactly sure what I'm doing wrong, to be honest.
// webots
#include <webots/Robot.hpp>
#include <webots/Camera.hpp>
#include <webots/DistanceSensor.hpp>
#include <webots/DifferentialWheels.hpp>
#include <webots/LED.hpp>
// standard
#include <iostream>
using namespace webots;
#define TIME_STEP 16
class MyRobot : public Robot
{
private:
Camera *camera;
DistanceSensor *distanceSensors[8];
LED *leds[8];
DifferentialWheels *diffWheels;
public:
MyRobot() : Robot()
{
// camera
camera = getCamera("camera");
// sensors
distanceSensors[0] = getDistanceSensor("ps0");
distanceSensors[1] = getDistanceSensor("ps1");
distanceSensors[2] = getDistanceSensor("ps2");
distanceSensors[3] = getDistanceSensor("ps3");
distanceSensors[4] = getDistanceSensor("ps4");
distanceSensors[5] = getDistanceSensor("ps5");
distanceSensors[6] = getDistanceSensor("ps6");
distanceSensors[7] = getDistanceSensor("ps7");
for (unsigned int i = 0; i < 8; ++i)
distanceSensors[i]->enable(TIME_STEP);
// leds
leds[0] = getLED("led0");
leds[1] = getLED("led1");
leds[2] = getLED("led2");
leds[3] = getLED("led3");
leds[4] = getLED("led4");
leds[5] = getLED("led5");
leds[6] = getLED("led6");
leds[7] = getLED("led7");
}
virtual ~MyRobot()
{
// cleanup
}
void run()
{
double speed[2] = {20.0, 0.0};
// main loop
while (step(TIME_STEP) != -1)
{
// read sensor values
for (unsigned int i = 0; i < 8; ++i)
std::cout << " [" << distanceSensors[i]->getValue() << "]";
std::cout << std::endl;
// process data
// send actuator commands
// this call kills the simulation
// diffWheels->setSpeed(1000, 1000);
}
}
};
int main(int argc, char* argv[])
{
MyRobot *robot = new MyRobot();
robot->run();
delete robot;
return 0;
}
Now, if this were the C implementation, I would call wb_differential_wheels_set_speed(1000, 1000); However, that call isn't available in the C++ header files.
The problem causing the freeze is due to the use of the uninitialized variable diffWheels.
DifferentialWheels (as well as Robot and Supervisor) doesn't need to be initialized.
You have to change the base class of your MyRobot class to DifferentialWheels
class MyRobot : public DifferentialWheels
and then simply call
setSpeed(1000, 1000)
and not
diffWheels->setSpeed(1000, 1000)
It doesn't seem as though you've initialized diffWheels, so I would imagine you're getting a segfault from dereferencing a garbage pointer. Try putting
diffWheels = new DifferentialWheels;
in the constructor of MyRobot.