82/// This pool has an unlimited size, and uses a master to distribute the work to the worker threads.
83/**
84 i.e. it presumes an unlimited resource of threads. These threads exit after completing their work, but may
85 be re-used if there is enough work being submitted to the pool, fast enough.
86 Memory is dynamically allocated in the operation of the parallel algorithms, so a quality parallel memory-allocator is recommended such as Hoard or HeapLayers, if scalability is limited by excessive calls to the global operator new..
151 The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.
157/// Obtain access to any statistics data collected by the operation of the thread_pool.
158/**
159 Algorithmic complexity when specialised with no_statistics: constant time, otherwise O(pool_size()).
160 Note that the value computed for the statistics_type::total_vertical_work() is guaranteed to be accurate. This type of thread_pool does not perform horizontal threading, because it spawns a thread per closure_base-derived closure, so can never suffer deadlock through resource starvation, therefore the value of statistics_type::total_hrz_work() is zero. Therefore, because of the vagaries of multi-threading the following holds:
177// The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.
178// The natural object-destruction order causes the threads in the pool to be destroyed too late, so the pool must be emptied now.
214// It is important to let this go out of scope here, not inside the lock, otherwise we'll deadlock e.g. when trying to add closure_base-derived closure elsewhere.
338 The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.
357// i.e. we won't wait forever for a result from work that has been erased. (Although we may discard a calculated result. If we can't erase the work from the execution context, then wherever that work is, allow it to be processed to avoid deadlocking that waiting client.)
366/// Obtain access to any statistics data collected by the operation of the thread_pool.
367/**
368 Algorithmic complexity when specialised with no_statistics: constant time, otherwise O(pool_size()).
369 Note that the value computed for the statistics_type::total_vertical_work() is guaranteed to be accurate. This type of thread_pool does not perform horizontal threading, because it spawns a thread per closure_base-derived closure, so can never suffer deadlock through resource starvation, therefore the value of statistics_type::total_hrz_work() is zero. Therefore, because of the vagaries of multi-threading the following holds:
385// The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.
489 throw typename this->exception(_T("Cannot have an empty thread pool."), info::function(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("const typename pool_traits_type::pool_type::size_type max_num_threads"), tostring(num_threads))), JMMCG_REVISION_HDR(_T(LIBJMMCG_VERSION_NUMBER)));
490 }
491 }
492*/
493
494/**
495 The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.
515// i.e. we won't wait forever for a result from work that has been erased. (Although we may discard a calculated result. If we can't erase the work from the execution context, then wherever that work is, allow it to be processed to avoid deadlocking that waiting client.)
524/// Obtain access to any statistics data collected by the operation of the thread_pool.
525/**
526 Algorithmic complexity when specialised with no_statistics: constant time, otherwise O(pool_size()).
527 Note that the value computed for the statistics_type::total_vertical_work() is guaranteed to be accurate. This type of thread_pool does not perform horizontal threading, because it spawns a thread per closure_base-derived closure, so can never suffer deadlock through resource starvation, therefore the value of statistics_type::total_hrz_work() is zero. Therefore, because of the vagaries of multi-threading the following holds:
543// The destruction of the collection of threads is sequential, but the threads themselves can exit in parallel, thus speeding up the clean-up of the pool.