The expiration time for new job artifacts in CI/CD pipelines is now 30 days (GitLab default). Previously generated artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

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