Commit 4c017151 authored by schultezub's avatar schultezub
Browse files

* fixed memory leaks

 * fixed kisscl::CommandQueue destructor
 * documented OpenGLJobProcessor scheduling strategy

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@254 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 61d44af5
......@@ -29,6 +29,8 @@
#ifndef TUMVISAPPLICATION_H__
#define TUMVISAPPLICATION_H__
//#include <vld.h> // Uncomment this for using Visual Leak Detector
#include "sigslot/sigslot.h"
#include <QApplication>
#include <utility>
......
......@@ -41,7 +41,16 @@ namespace TUMVis {
}
OpenGLJobProcessor::~OpenGLJobProcessor() {
// delete all per-context job queues and unfinished jobs
for (tbb::concurrent_vector<tgt::GLCanvas*>::const_iterator it = _contexts.begin(); it != _contexts.end(); ++it) {
tbb::concurrent_hash_map<tgt::GLCanvas*, PerContextJobQueue*>::const_accessor a;
if (_contextQueueMap.find(a, *it)) {
delete a->second;
}
}
_contextQueueMap.clear();
_contexts.clear();
}
void OpenGLJobProcessor::stop() {
......@@ -57,6 +66,7 @@ namespace TUMVis {
while (! _stopExecution) {
// this is a simple round-robing scheduling between all contexts:
bool hadWork = false;
// TODO: consider only non-empty context queues here
clock_t maxTimePerContext = 30 / _contexts.size();
for (size_t i = 0; i < _contexts.size(); ++i) {
......
......@@ -48,7 +48,23 @@ namespace tgt {
namespace TUMVis {
/**
* \todo Explain scheduling technique.
* Singleton class for managing and executing work items (jobs) that need an active OpenGL context.
* After an OpenGL context has been registered you can enqueue jobs that are to be executed within that
* context to the job queue. Enqueued jobs are executed asynchroniously using a specific scheduling
* strategy, depending on the given JobType:
*
* OpenGLJobProcessor implements a round-robin scheduling strategy for the registered OpenGL contexts,
* meaning that each context gets roughly the same computing time. Thereby, it tries to maintain an update
* frequency of 30fps for each context.
* The jobs for each contexts are scheduled using the following technique: As mentioned above, each context
* has a time slot of \a n milliseconds. At first, as much serial jobs are executed as possible until their
* queue is empty or or the time is up. Then, one low priority job is executed. Finally, the PaintJob is
* executed (if existant) before switching to the next context.
*
* This class implements the Runnable interface, hence, runs in its own thread. Furthermore, it uses
* conditional wait, when there are currently no jobs to process.
*
* This class is to be considered as thread-safe.
*/
class OpenGLJobProcessor : public tgt::Singleton<OpenGLJobProcessor>, public Runnable, public sigslot::has_slots<> {
friend class tgt::Singleton<OpenGLJobProcessor>;
......@@ -63,6 +79,9 @@ namespace TUMVis {
LowPriorityJob ///< Low priority jobs have the lowest priority, can be executed at any time. The only guarantee is that thay won't starve.
};
/**
* Destructor, deletes all unfinished jobs.
*/
virtual ~OpenGLJobProcessor();
......@@ -102,7 +121,20 @@ namespace TUMVis {
*/
PerContextJobQueue()
: _paintJob(0)
{
{}
/**
* Destructor, deletes all enqueued jobs.
*/
~PerContextJobQueue() {
if (_paintJob != 0)
delete _paintJob;
AbstractJob* jobToDelete = 0;
while (_serialJobs.try_pop(jobToDelete))
delete jobToDelete;
while (_lowPriorityJobs.try_pop(jobToDelete))
delete jobToDelete;
}
AbstractJob* _paintJob; ///< PaintJob of the context
......
......@@ -33,6 +33,11 @@ namespace kisscl {
}
CLRuntime::~CLRuntime() {
// delete all command queues
for (std::map< std::pair<Context*, Device*>, CommandQueue*>::iterator it = _commandQueues.begin(); it != _commandQueues.end(); ++it)
delete it->second;
// delete all platforms and with it all devices
for (std::vector<Platform*>::iterator it = _platforms.begin(); it != _platforms.end(); ++it)
delete *it;
}
......
......@@ -63,8 +63,7 @@ namespace kisscl {
// = getters and setters ==========================================================================
CommandQueue::~CommandQueue() {
if (_id != 0)
clReleaseCommandQueue(_id);
}
const Context* CommandQueue::getContext() const {
......
......@@ -99,6 +99,7 @@ namespace TUMVis {
void CLRaycaster::deinit() {
CLRtm.dispose(_clProgram);
delete _clContext;
VisualizationProcessor::deinit();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment