Here is a draft of a top-level view that shows the execution paths and interactions between components, with focus on scheduling and not resource description.
Each box represents a runtime object, for some multiple instances can exist. There are two sources of action: the user code (on the left) and the worker threads (bottom right). Starting from the user code, a task will be added to the graphs and then ends up in the reach of the scheduler which caches relevant tasks. A set of workers waits on a queue to then execute the tasks. Note that the represented execution paths are taken concurrently from multiple threads. Therefore each queue in the scheduler, the scheduling-graph and each precedence-graph (there are multiple because they are nested) have a mutex.
Here is a draft of a top-level view that shows the execution paths and interactions between components, with focus on scheduling and not resource description. Each box represents a runtime object, for some multiple instances can exist. There are two sources of action: the user code (on the left) and the worker threads (bottom right). Starting from the user code, a task will be added to the graphs and then ends up in the reach of the scheduler which caches relevant tasks. A set of workers waits on a queue to then execute the tasks. Note that the represented execution paths are taken concurrently from multiple threads. Therefore each queue in the scheduler, the scheduling-graph and each precedence-graph (there are multiple because they are nested) have a mutex.