Skip to content

Commit

Permalink
Process : Add acquireCollaborativeResult() method
Browse files Browse the repository at this point in the history
This will be used to replace the TaskMutex collaboration mechanism currently used via the LRUCaches in ValuePlug. The underlying collaboration mechanism is still a `task_arena/task_group` combo, but this arrangement has a few key benefits :

- Moving the collaboration out from the guts of the LRUCache gives us much more control over how it is performed, particularly for collaborating threads.
- We are now tracking interprocess dependencies completely ourselves, so we are no longer vulnerable to the deadlocks that TaskMutex couldn't prevent.
- We are no longer using `task_arena_observer`, which gives us much greater freedom to change implementation in future.
  • Loading branch information
johnhaddon committed Oct 9, 2023
1 parent 5773b55 commit 5211478
Show file tree
Hide file tree
Showing 4 changed files with 471 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Improvements
- Popups for string cells and row names are now sized to fit their column.
- Added "Triple" and "Quadruple" width options to the spreadsheet row name popup menu.

API
---

- Process : Added `acquireCollaborativeResult()` method, providing an improved mechanism for multiple threads to collaborate on TBB tasks spawned by a single process they all depend on.

1.3.4.0 (relative to 1.3.3.0)
=======

Expand Down
27 changes: 27 additions & 0 deletions include/Gaffer/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,34 @@ class GAFFER_API Process : private ThreadState::Scope
/// \todo This just exists for ABI compatibility. Remove it.
void handleException();

/// Searches for an in-flight process and waits for its result, collaborating
/// on any TBB tasks it spawns. If no such process exists, constructs one
/// using `args` and makes it available for collaboration by other threads,
/// publishing the result to a cache when the process completes.
///
/// Requirements :
///
/// - `ProcessType( args... )` constructs a process suitable for computing
/// the result for `cacheKey`.
/// - `ProcessType::ResultType` defines the result type for the process.
/// - `ProcessType::run()` does the work for the process and returns the
/// result.
/// - `ProcessType::g_cache` is a static LRUCache of type `ProcessType::CacheType`
/// to be used for the caching of the result.
/// - `ProcessType::cacheCostFunction()` is a static function suitable
/// for use with `CacheType::setIfUncached()`.
///
template<typename ProcessType, typename... ProcessArguments>
static typename ProcessType::ResultType acquireCollaborativeResult(
const typename ProcessType::CacheType::KeyType &cacheKey, ProcessArguments&&... args
);

private :

class Collaboration;
template<typename T>
class TypedCollaboration;

static bool forceMonitoringInternal( const ThreadState &s, const Plug *plug, const IECore::InternedString &processType );

void emitError( const std::string &error, const Plug *source = nullptr ) const;
Expand All @@ -111,6 +137,7 @@ class GAFFER_API Process : private ThreadState::Scope
const Plug *m_plug;
const Plug *m_destinationPlug;
const Process *m_parent;
const Collaboration *m_collaboration;

};

Expand Down
Loading

0 comments on commit 5211478

Please sign in to comment.