Replaced use of while(isRunning()) { YieldCurrentThread(); } style loops with use of join() to avoid false positives being reported by valgrind when using the helgrind tool for thread debugging.
git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14460 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
@@ -21,21 +21,21 @@
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// The idea of user stats is that you record times or values in the viewer's
|
||||
// stats, and you also tell the stats handler to watch those values each
|
||||
// The idea of user stats is that you record times or values in the viewer's
|
||||
// stats, and you also tell the stats handler to watch those values each
|
||||
// frame. The stats handler can display the stats in three ways:
|
||||
// - A numeric time beside the stat name
|
||||
// Requires that an elapsed time be recorded in the viewer's stats for the
|
||||
// Requires that an elapsed time be recorded in the viewer's stats for the
|
||||
// "timeTakenName".
|
||||
// - A bar in the top bar graph
|
||||
// Requires that two times (relative to the viewer's start tick) be
|
||||
// Requires that two times (relative to the viewer's start tick) be
|
||||
// recorded in the viewer's stats for the "beginTimeName" and "endTimeName".
|
||||
// - A line in the bottom graph
|
||||
// Requires that an elapsed time be recorded in the viewer's stats for the
|
||||
// Requires that an elapsed time be recorded in the viewer's stats for the
|
||||
// "timeTakenName".
|
||||
|
||||
|
||||
// Anything you want to time has to use a consistent name in both the stats
|
||||
// Anything you want to time has to use a consistent name in both the stats
|
||||
// handler and the viewer stats, so it's a good idea to use constants to make
|
||||
// sure the names are the same everywhere.
|
||||
const std::string frameNumberName = "Custom Frame Number";
|
||||
@@ -49,54 +49,54 @@ const std::string otherThreadTimeName = "Thread";
|
||||
void initUserStats(osgViewer::StatsHandler* statsHandler)
|
||||
{
|
||||
// This line displays the frame number. It's not averaged, just displayed as is.
|
||||
statsHandler->addUserStatsLine("Frame", osg::Vec4(0.7,0.7,0.7,1), osg::Vec4(0.7,0.7,0.7,0.5),
|
||||
statsHandler->addUserStatsLine("Frame", osg::Vec4(0.7,0.7,0.7,1), osg::Vec4(0.7,0.7,0.7,0.5),
|
||||
frameNumberName, 1.0, false, false, "", "", 0.0);
|
||||
|
||||
// This line displays the frame time (from beginning of event to end of draw). No bars.
|
||||
statsHandler->addUserStatsLine("MS/frame", osg::Vec4(1,0,1,1), osg::Vec4(1,0,1,0.5),
|
||||
statsHandler->addUserStatsLine("MS/frame", osg::Vec4(1,0,1,1), osg::Vec4(1,0,1,0.5),
|
||||
frameTimeName, 1000.0, true, false, "", "", 0.02);
|
||||
|
||||
// This line displays the sum of update and main camera cull times.
|
||||
statsHandler->addUserStatsLine("Custom", osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,0.5),
|
||||
statsHandler->addUserStatsLine("Custom", osg::Vec4(1,1,1,1), osg::Vec4(1,1,1,0.5),
|
||||
customTimeName + " time taken", 1000.0, true, false, customTimeName + " begin", customTimeName + " end", 0.016);
|
||||
|
||||
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
|
||||
statsHandler->addUserStatsLine("Sleep1", osg::Vec4(1,0,0,1), osg::Vec4(1,0,0,0.5),
|
||||
statsHandler->addUserStatsLine("Sleep1", osg::Vec4(1,0,0,1), osg::Vec4(1,0,0,0.5),
|
||||
operation1TimeName + " time taken", 1000.0, true, false, operation1TimeName + " begin", operation1TimeName + " end", 0.016);
|
||||
|
||||
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
|
||||
statsHandler->addUserStatsLine("Sleep2", osg::Vec4(1,0.5,0.5,1), osg::Vec4(1,0.5,0.5,0.5),
|
||||
statsHandler->addUserStatsLine("Sleep2", osg::Vec4(1,0.5,0.5,1), osg::Vec4(1,0.5,0.5,0.5),
|
||||
operation2TimeName + " time taken", 1000.0, true, false, operation2TimeName + " begin", operation2TimeName + " end", 0.016);
|
||||
|
||||
// This line displays the time taken by a function below ( doSomethingAndTimeIt() )
|
||||
statsHandler->addUserStatsLine("Thread", osg::Vec4(0,0.5,0,1), osg::Vec4(0,0.5,0,0.5),
|
||||
statsHandler->addUserStatsLine("Thread", osg::Vec4(0,0.5,0,1), osg::Vec4(0,0.5,0,0.5),
|
||||
otherThreadTimeName + " time taken", 1000.0, true, false, otherThreadTimeName + " begin", otherThreadTimeName + " end", 0.016);
|
||||
}
|
||||
|
||||
|
||||
void updateUserStats(osgViewer::Viewer& viewer)
|
||||
{
|
||||
// Test the custom stats line by just adding up the update and cull
|
||||
// Test the custom stats line by just adding up the update and cull
|
||||
// times for the viewer main camera for the previous frame.
|
||||
if (viewer.getViewerStats()->collectStats("update") && viewer.getCamera()->getStats()->collectStats("rendering"))
|
||||
{
|
||||
// First get the frame number. The code below assumes that
|
||||
// First get the frame number. The code below assumes that
|
||||
// updateUserStats() is called after advance(), so the frame number
|
||||
// that will be returned is for the frame that has just started and is
|
||||
// not rendered yet. The previous frame is framenumber-1, but we can't
|
||||
// use that frame's timings because it's probably not finished
|
||||
// use that frame's timings because it's probably not finished
|
||||
// rendering yet (in multithreaded viewer modes). So we'll use the
|
||||
// timings for framenumber-2 for this demo.
|
||||
unsigned int framenumber = viewer.getFrameStamp()->getFrameNumber();
|
||||
|
||||
// Get the update time and the viewer main camera's cull time. We use
|
||||
// getAveragedAttribute() in order to get the actual time elapsed as
|
||||
// Get the update time and the viewer main camera's cull time. We use
|
||||
// getAveragedAttribute() in order to get the actual time elapsed as
|
||||
// calculated by the stats.
|
||||
double update = 0.0, cull = 0.0;
|
||||
viewer.getViewerStats()->getAveragedAttribute("Update traversal time taken", update);
|
||||
viewer.getCamera()->getStats()->getAveragedAttribute("Cull traversal time taken", cull);
|
||||
|
||||
// Get various begin and end times, note these are not elapsed times
|
||||
// Get various begin and end times, note these are not elapsed times
|
||||
// in a frame but rather the simulation time at those moments.
|
||||
double eventBegin = 0.0, updateBegin = 0.0, cullEnd = 0.0, drawEnd = 0.0;
|
||||
viewer.getViewerStats()->getAttribute(framenumber-2, "Event traversal begin time", eventBegin);
|
||||
@@ -112,11 +112,11 @@ void updateUserStats(osgViewer::Viewer& viewer)
|
||||
|
||||
// This line displays the sum of update and main camera cull times.
|
||||
viewer.getViewerStats()->setAttribute(framenumber-1, customTimeName + " time taken", update+cull);
|
||||
// Since we give begin and end times that correspond to the begin of
|
||||
// the update phase and the end of the cull phase, the bar in the
|
||||
// graph will not correspond to the summed times above if something
|
||||
// happened between update and cull (as in this demo). Also, we need
|
||||
// to translate the updateBegin and cullEnd times by one frame since
|
||||
// Since we give begin and end times that correspond to the begin of
|
||||
// the update phase and the end of the cull phase, the bar in the
|
||||
// graph will not correspond to the summed times above if something
|
||||
// happened between update and cull (as in this demo). Also, we need
|
||||
// to translate the updateBegin and cullEnd times by one frame since
|
||||
// we're taking the times for framenumber-2 but using them to display
|
||||
// in the framenumber-1 graph.
|
||||
viewer.getViewerStats()->setAttribute(framenumber-1, customTimeName + " begin", updateBegin + (1.0/60.0));
|
||||
@@ -125,7 +125,7 @@ void updateUserStats(osgViewer::Viewer& viewer)
|
||||
}
|
||||
|
||||
|
||||
/// Utility function you call before something you want to time, so that the
|
||||
/// Utility function you call before something you want to time, so that the
|
||||
/// recorded times will all be consistent using the viewer's time.
|
||||
void startTiming(osgViewer::Viewer& viewer, const std::string& name)
|
||||
{
|
||||
@@ -136,7 +136,7 @@ void startTiming(osgViewer::Viewer& viewer, const std::string& name)
|
||||
viewer.getViewerStats()->setAttribute(framenumber, name + " begin", currentTime);
|
||||
}
|
||||
|
||||
/// Utility function you call after something you want to time, so that the
|
||||
/// Utility function you call after something you want to time, so that the
|
||||
/// recorded times will all be consistent using the viewer's time.
|
||||
void endTiming(osgViewer::Viewer& viewer, const std::string& name)
|
||||
{
|
||||
@@ -157,7 +157,7 @@ void endTiming(osgViewer::Viewer& viewer, const std::string& name)
|
||||
}
|
||||
|
||||
|
||||
/// Will just sleep for the given number of milliseconds in the same thread
|
||||
/// Will just sleep for the given number of milliseconds in the same thread
|
||||
/// as the caller, recording the time taken in the viewer's stats.
|
||||
void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, double milliseconds)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, do
|
||||
//------------------------------------------------------------
|
||||
// Your processing goes here.
|
||||
|
||||
// Do nothing for the specified number of milliseconds, just so we can
|
||||
// Do nothing for the specified number of milliseconds, just so we can
|
||||
// see it in the stats.
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
while (osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick()) < milliseconds)
|
||||
@@ -179,8 +179,8 @@ void doSomethingAndTimeIt(osgViewer::Viewer& viewer, const std::string& name, do
|
||||
}
|
||||
|
||||
|
||||
/// Thread that will sleep for the given number of milliseconds, recording
|
||||
/// the time taken in the viewer's stats, whenever its process() method is
|
||||
/// Thread that will sleep for the given number of milliseconds, recording
|
||||
/// the time taken in the viewer's stats, whenever its process() method is
|
||||
/// called.
|
||||
class UselessThread : public OpenThreads::Thread
|
||||
{
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
//------------------------------------------------------------
|
||||
// Your processing goes here.
|
||||
|
||||
// Do nothing for the specified number of milliseconds, just so we can
|
||||
// Do nothing for the specified number of milliseconds, just so we can
|
||||
// see it in the stats.
|
||||
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
||||
while (osg::Timer::instance()->delta_m(startTick, osg::Timer::instance()->tick()) < _timeToRun)
|
||||
@@ -337,7 +337,7 @@ int main(int argc, char** argv)
|
||||
|
||||
viewer.realize();
|
||||
|
||||
// Start up a thread that will just run for a fixed time each frame, in
|
||||
// Start up a thread that will just run for a fixed time each frame, in
|
||||
// parallel to the frame loop.
|
||||
UselessThread thread(viewer, 6.0);
|
||||
thread.start();
|
||||
@@ -357,7 +357,7 @@ int main(int argc, char** argv)
|
||||
viewer.eventTraversal();
|
||||
viewer.updateTraversal();
|
||||
|
||||
// Eat up some time on the viewer thread between the update and cull
|
||||
// Eat up some time on the viewer thread between the update and cull
|
||||
// phases.
|
||||
doSomethingAndTimeIt(viewer, operation2TimeName, 3.0);
|
||||
|
||||
@@ -365,9 +365,6 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
thread.cancel();
|
||||
while (thread.isRunning())
|
||||
{
|
||||
OpenThreads::Thread::YieldCurrentThread();
|
||||
}
|
||||
thread.join();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user