rework Job representation

make class Job a real subclass of the
job definition struct and turn the
JobClosure into a trampoline
This commit is contained in:
Fischlurch 2012-02-19 00:43:35 +01:00
parent 0b25c2e08d
commit f8f011bb44
4 changed files with 107 additions and 45 deletions

View file

@ -45,6 +45,27 @@ namespace engine {
//
//class ExitNode;
/**
* a job closure represents the execution context of a job.
* This allows us to enqueue simple job-"functions" with the scheduler.
* By virtue of the JobClosure-pointer, embedded into #lumiera_jobDefinition,
* the invocation of such a job may re-gain the full context, including the
* actual ProcNode to pull and further specifics, like the media channel.
*/
class JobClosure
: public lumiera_jobClosure
{
public:
bool
verify (Time nominalJobTime) const
{
UNIMPLEMENTED ("access the underlying JobTicket and verify the given job time is within the relevant timeline segment");
return false;
}
};
/**
* execution plan for pulling a specific exit node.
* Usable as blue print for generating actual render jobs.
@ -81,7 +102,7 @@ namespace engine {
JobsPlanning
createJobsFor (FrameCoord coordinates)
{
UNIMPLEMENTED ("job planning and generation")
UNIMPLEMENTED ("job planning and generation");
}
bool

View file

@ -21,6 +21,18 @@
* *****************************************************/
/** @file job.cpp
** Implementation of render job invocation.
** Within this translation unit, the actual invocation of a frame rendering
** job takes place, after reconstruction of the job's execution environment (closure).
**
** @see JobTicket
** @see ProcNode
** @see nodeinvocation.hpp
**
*/
#include "proc/engine/job.hpp"
#include "proc/engine/job-ticket.hpp"
@ -29,7 +41,14 @@ namespace proc {
namespace engine {
namespace { // Details...
inline JobClosure&
myClosure (const Job * const self)
{
ASSERT (self);
ASSERT (self->jobClosure);
return *static_cast<JobClosure*> (self->jobClosure);
}
} // (END) Details...
@ -41,18 +60,31 @@ namespace engine {
/** @todo WIP-WIP 2/12
*/
void
Job::triggerJob (lumiera_jobParameter param) const
Job::triggerJob () const
{
UNIMPLEMENTED ("how to access the JobTicket and build the RenderInvocation");
}
void
Job::signalFailure (lumiera_jobParameter) const
Job::signalFailure () const
{
UNIMPLEMENTED ("how to organise job failure and abortion");
}
/** Render Job self verification.
* performs a parameter consistency check
* including a call-back to the defining JobTicket
*/
bool
Job::isValid() const
{
return this->jobClosure
&& this->parameter.invoKey > 0
&& myClosure(this).verify (getNominalTime());
;
}
}} // namespace proc::engine
@ -61,30 +93,28 @@ namespace {
using proc::engine::Job;
inline Job&
forwardInvocation (LumieraJobClosure jobFunctor)
forwardInvocation (lumiera_jobDefinition& jobDef)
{
Job* job = static_cast<Job*> (jobFunctor);
Job& job = static_cast<Job&> (jobDef);
REQUIRE (job);
REQUIRE (job->isValid());
return *job;
REQUIRE (job.isValid());
return job;
}
}
extern "C" { /* ==== implementation C interface for job invocation ======= */
void
lumiera_job_invoke (LumieraJobClosure jobFunctor, lumiera_jobParameter param)
lumiera_job_invoke (lumiera_jobDefinition jobDef)
{
forwardInvocation(jobFunctor).triggerJob (param);
forwardInvocation(jobDef).triggerJob();
}
void
lumiera_job_failure (LumieraJobClosure jobFunctor, lumiera_jobParameter param)
lumiera_job_failure (lumiera_jobDefinition jobDef)
{
forwardInvocation(jobFunctor).signalFailure (param);
forwardInvocation(jobDef).signalFailure();
}
}

View file

@ -68,24 +68,37 @@ typedef struct lumiera_jobParameter_struct lumiera_jobParameter;
typedef lumiera_jobParameter* LumieraJobParameter;
/** complete definition of an individual job */
struct lumiera_jobDefinition_struct
{
LumieraJobClosure jobClosure;
lumiera_jobParameter parameter;
};
typedef struct lumiera_jobDefinition_struct lumiera_jobDefinition;
/**
* descriptor record used by the scheduler to organise job invocation.
* The invocation parameter and job closure necessary to invoke this
* job as a function is embedded into this descriptor.
* The actual job's definition, i.e. the invocation parameter and
* the closure necessary to invoke the job as a function
* is embedded (by value) into this descriptor.
*
* @note while this descriptor as such is self-contained,
* the referred LumieraJobClosure needs to be allocated
* and managed separately. Indeed, this closure happens
* to live within the segment data, as part of the JobTicket.
*/
struct lumiera_jobDescriptor_struct
{
gavl_time_t when;
JobState jobState;
lumiera_jobDefinition jobDefinition;
/* == Job prerequisites == */
LList waiting;
LList failed;
LList completed;
JobState jobstate;
LumieraJobClosure jobClosure;
lumiera_jobParameter parameter;
};
typedef struct lumiera_jobDescriptor_struct lumiera_jobDescriptor;
typedef lumiera_jobDescriptor* LumieraJobDescriptor;
@ -109,61 +122,57 @@ namespace engine {
//using lib::time::TimeSpan;
//using lib::time::Duration;
//using lib::time::FSecs;
using lib::time::TimeValue;
using lib::time::Time;
//
//class ExitNode;
/**
* Frame rendering task, represented as closure.
* This functor encodes all information necessary to actually
* trigger and invoke the rendering operation. It will be embedded
* by reference into a job descriptor and then enqueued with the scheduler
* This functor encodes all information necessary to trigger
* and invoke the actual rendering operation. It will be embedded
* by value into a job descriptor and then enqueued with the scheduler
* for invocation just in time. The job interface exposes everything necessary
* to plan, handle, schedule and abort jobs. The implementation refers to the
* concrete "execution plan" encoded into the corresponding engine::JobTicket.
* The latter is embedded into the storage for segment of the low-level model
* and thus is shared for all frames and channels within this part of the
* timeline. Thus, the lumiera_jobParameter struct contains the "moving parts"
* changing for each individual job.
* The latter is embedded into the storage for one segment of the low-level model
* and thus is shared for all frames and channels within this part of the timeline.
* Thus, the lumiera_jobParameter struct contains the "moving parts"
* different for each \em individual job.
*
* @todo 1/12 WIP-WIP-WIP defining the invocation sequence and render jobs
* @todo 2/12 WIP-WIP-WIP defining the invocation sequence and render jobs
*/
class Job
: public lumiera_jobClosure
: public lumiera_jobDefinition
{
public:
//////////////////////////////TODO: value semantics or turn this into an interface?
Job()
{
UNIMPLEMENTED ("job representation, planning and scheduling");
UNIMPLEMENTED ("job creation, planning and scheduling");
}
// using standard copy operations
void triggerJob (lumiera_jobParameter) const;
void signalFailure (lumiera_jobParameter) const;
void triggerJob() const;
void signalFailure() const;
Time
getNominalTime() const
{
UNIMPLEMENTED ("job representation, planning and scheduling");
return Time (TimeValue(parameter.nominalTime));
}
InvocationInstanceID
getInvocationInstanceID() const
{
UNIMPLEMENTED ("job representation, planning and scheduling");
return this->parameter.invoKey;
}
bool
isValid() const
{
UNIMPLEMENTED ("validity self check");
}
bool isValid() const;
};
@ -179,14 +188,14 @@ extern "C" {
/** trigger execution of a specific job,
* assuming availability of all prerequisites */
void lumiera_job_invoke (LumieraJobClosure, lumiera_jobParameter);
void lumiera_job_invoke (lumiera_jobDefinition);
/** signal inability to invoke this job
* @todo decide what and how to communicate details of the failure
* @remarks the purpose of this function is to allow for reliable checkpoints
* within the network of dependent jobs invocations, even after
* missing deadlines or aborting a sequence of jobs */
void lumiera_job_failure (LumieraJobClosure, lumiera_jobParameter);
void lumiera_job_failure (lumiera_jobDefinition);

View file

@ -32,11 +32,13 @@
#include "lib/time/timevalue.hpp"
#include "lib/time/timequant.hpp"
#include "lib/singleton.hpp"
#include "lib/util.hpp"
//#include <boost/scoped_ptr.hpp>
//#include <iostream>
using test::Test;
using util::isnil;
//using std::cout;
//using std::rand;