-
Resolved conflicts: app/br/br.cpp openbr/core/bee.cpp openbr/plugins/output.cpp
-
A way to avoid deadlocks when using stream inside a distribute transform
-
Since we no longer put Stream threads on the global thread pool, the previous changes are unnecessary. Also, in distribute, set up the QFutureSyncrhonizer with futures in the opposite order. In Qt 5.1, the waiting thread will wait for each future in the order they are added to the synchronizer, and thread execution will proceed in the same order. This prevents the waiting thread from every doing anything besides waiting. Reversing the QFuture order (so that it is the opposite of execution order) allows the waiting thread to steal work as intended
-
Don't use the global thread pool for streams. Micro-managing the global thread pool's active thread count has proven infeasible, therefore in order to avoid thread based deadlocks, we don't use the global thread pool. Instead, we share thread pools across sibling Stream transforms. Misc. code cleanup and better last frame detection.
-
Start the individual project jobs in distribute as qrunnables rather than through qtconcurrent::run. This is necessary since run does not allow us to assign a priority to a task. Run the distribute tasks with a lower priority than stream tasks. This prevents a deadlock where a thread in stream::projectUpdate would try to start a job and wait for it to finish, but in the meantime a distribute job would use up the thread the stream thread released. Due to the use of TimeVaryingTransformWrapper in distribute, stream transforms are a limited resource, and the previously discussed situation would cause a deadlock where stream transforms (in stream::projectUpdate) were waiting for their job to finish, but the job never started because distribute transform threads were in resource waiting for stream transforms to become available. The current implementation has some important drawbacks. Not using qtconcurrent::run means we cannot use the QFutureSynchronizer API to wait for threads to finish. I am (temporarily) starting FakeMain in (in br) on a local thread pool, and in distribute waiting for the complete global thread pool to become available (this would be a self-blocking wait without starting FakeMain in a different thread pool). This is quite restrictive, we cannot currently ever nest distribute transforms for example. Also, using priority in this way is not general, nesting a distribute transform inside a stream is infeasible under this scheme (well it already wouldn't work due to the previously discussed problem, but this issue is a little more persistent).
-
In stream projectUpdate, queue the intial worker thread before calling releaseThread, and waiting. Also, call reserveThread before the last worker thread ends. The goal here is to avoid cases where the threadCount is increased, before the extra thread is used up by the current stream, as part of a scheme to avoid deadlocks related to using stream within an active distribute transform.
-
Expose Globals in resource.h, initialize Resource objects with Globals->parallelism resources, rather than idealThreadCount
-
Implementing AggregateFrames Transform
-
resolved conflicts: app/br/br.cpp openbr/core/bee.cpp openbr/core/classify.cpp openbr/core/cluster.cpp openbr/core/eval.h openbr/openbr.cpp openbr/openbr.h openbr/plugins/algorithms.cpp openbr/plugins/independent.cpp openbr/plugins/output.cpp openbr/plugins/svm.cpp