⚠ __This is a problematic decision__ It temporarily **breaks compatibility with 32bit** until this issue is resolved. == Explanation == Lumiera relies on a mix of the Standard library and Lib-Boost for calculation of hash values. Before C++11, the Standard did not support and hashtable implementation; meanwhile, we got several hash based containers in the STL and a framework for hashes, which unfortunately is incomplete and cumbersome to use. The C++ Committee has spend endless discussions and was not able to settle on a convincing solution without major drawbacks regarding one aspect or the other. This situation is problematic, since Lumiera relies heavily on the technique of building stable systematic identifiers based on chained hash values. It is thus essential to use a strong, reliable and portable hash function. But unfortunately... * the standard-fallback solution is known to be weak. * Lib-Boost automatically uses stronger implementations for 64bit systems * this implies that Hash-Values **are non-portable** As the Lumiera project currently has no developer time to expend on such a difficult and deep topic of fundamental research, today I decided to go down the path of least resistance and **effectively abandon any system that can not compile and use the 64bit `hash_combine` implementation. This changeset extracts code from Lib-Boost 1.67 and adds a static assertion to **break compilation** on non-64bit-platforms (whatever this means)
150 lines
4.8 KiB
C++
150 lines
4.8 KiB
C++
/*
|
|
JobTicket - execution plan for render jobs
|
|
|
|
Copyright (C) Lumiera.org
|
|
2012, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
* *****************************************************/
|
|
|
|
|
|
/** @file job-ticket.cpp
|
|
** Implementation details of preparing and performing job invocations.
|
|
**
|
|
** @todo WIP-WIP-WIP 3/2012
|
|
** @see Job
|
|
**
|
|
*/
|
|
|
|
|
|
#include "steam/engine/job-ticket.hpp"
|
|
#include "vault/gear/nop-job-functor.hpp"
|
|
#include "lib/hash-combine.hpp"
|
|
#include "lib/depend.hpp"
|
|
#include "lib/util.hpp"
|
|
|
|
|
|
namespace steam {
|
|
namespace engine {
|
|
|
|
using vault::gear::Job;
|
|
using vault::gear::JobClosure;
|
|
using lib::HashVal;
|
|
using lib::unConst;
|
|
using lib::time::FSecs;
|
|
|
|
|
|
namespace { // Details...
|
|
lib::Depend<vault::gear::NopJobFunctor> nopFunctor;
|
|
|
|
/* ======== hard wired =================*/
|
|
const FSecs JOB_MINIMUM_RUNTIME{1,1000};
|
|
|
|
} // (END) Details...
|
|
|
|
|
|
|
|
|
|
|
|
/** special »do nothing« JobTicket marker */
|
|
JobTicket JobTicket::NOP{}; ////////////////////////////////////////////////////////////////////TICKET #725 : do we actually need that for the final data structure?
|
|
|
|
JobTicket::JobTicket()
|
|
: provision_{nopFunctor(), ExitNode::NIL}
|
|
{ }
|
|
|
|
|
|
/**
|
|
* Generate a render job to invoke the render network configuration
|
|
* as defined and backing this JobTicket. The generated job descriptor record
|
|
* will include a specific InvocationInstanceID, which factors in the nominal
|
|
* frame time, but also the specific backing render configuration.
|
|
* The actual implementation of the job functionality will be delegated
|
|
* to the JobClosure, which was set up for this Segment and JobTiket
|
|
* after the last Builder run created this part of the render network.
|
|
*/
|
|
Job
|
|
JobTicket::createJobFor (Time nominalTime)
|
|
{
|
|
if (this->empty())
|
|
{ //////////////////////////////////////////////////////////////////////////////////TICKET #1296 : can we get away just with a do-nothing functor?
|
|
return Job(nopFunctor(), InvocationInstanceID(), nominalTime);
|
|
}
|
|
else
|
|
{
|
|
REQUIRE (this->isValid(), "Attempt to generate render job for incomplete or unspecified render plan.");
|
|
JobClosure& functor = static_cast<JobClosure&> (unConst(provision_.jobFunctor)); ////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs)
|
|
InvocationInstanceID invoKey{timeHash (nominalTime, provision_.invocationSeed)};
|
|
|
|
return Job(functor, invoKey, nominalTime);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Use observed runtime values of past job invocations to guess a sensible bound
|
|
* for the calculation time to expect for next invocation.
|
|
* @todo 6/2023 placeholder implementation with hard wired values in ExitNode
|
|
*/
|
|
Duration
|
|
JobTicket::getExpectedRuntime()
|
|
{
|
|
if (this->empty())
|
|
return Duration{JOB_MINIMUM_RUNTIME};
|
|
else
|
|
{
|
|
REQUIRE (isValid(), "Attempt to determine timings for incomplete or unspecified render plan.");
|
|
return provision_.exitNode.getUpperBoundRuntime();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Tag the precomputed invocation ID with the nominal frame time
|
|
*/
|
|
InvocationInstanceID
|
|
JobTicket::timeHash (Time nominalTime, InvocationInstanceID const& seed)
|
|
{
|
|
InvocationInstanceID res{seed};
|
|
HashVal timeMark = res.part.t;
|
|
lib::hash::combine (timeMark, hash_value (nominalTime));
|
|
res.part.t = timeMark;
|
|
return res;
|
|
}
|
|
|
|
|
|
namespace { ///////////////////////////////////////////////////////////////////////////////////////////TICKET #1287 : temporary workaround until we get rid of the C base structs
|
|
inline bool
|
|
operator== (InvocationInstanceID const& l, InvocationInstanceID const& r)
|
|
{
|
|
return lumiera_invokey_eq (unConst(&l), unConst(&r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper for tests: verify the given invocation parameters match this JobTicket.
|
|
*/
|
|
bool
|
|
JobTicket::verifyInstance (JobFunctor& functor, InvocationInstanceID const& invoKey, Time nominalTime) const
|
|
{
|
|
return util::isSameObject (provision_.jobFunctor, functor)
|
|
and invoKey == timeHash (nominalTime, provision_.invocationSeed);
|
|
}
|
|
|
|
|
|
|
|
|
|
}} // namespace steam::engine
|