/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/include/usr/util/impl/threadpool.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ #ifndef __UTIL_IMPL_THREADPOOL_H #define __UTIL_IMPL_THREADPOOL_H /** @file threadpool.H * * Contains the (mostly) untemplatized implementation details of the * threadpool. * * The idea is that Util::ThreadPool is a templatized class to give the * user flexibility but most of the details are implemented in a * non-templatized way to conserve space. When Util::ThreadPool is * instantiated there is only a small amount of code that is unique to T. */ #include #include #include #include #include namespace Util { namespace __Util_ThreadPool_Impl { /** * Export the container types used in the internal ThreadPool * implementation. * * The ThreadPoolImpl here is going to operate on a container of void*'s, * but the templatized code is going to assume it is operating on a * container of T*'s. Since an iterator and iterator have the * same behavior, we provide this template here so that the real * ThreadPool can use the same iterators by typename without knowing if * they are stored in a list, vector, etc. */ template struct ThreadPoolImplContainer { typedef std::list<_T*> worklist_t; typedef typename std::list<_T*>::iterator worklist_itr_t; }; /** * Internal implementation of the thread pool. */ class ThreadPoolImpl { public: /** Worklist container type. */ typedef ThreadPoolImplContainer::worklist_t worklist_t; /** Worklist container iterator type. */ typedef ThreadPoolImplContainer::worklist_itr_t worklist_itr_t; /** Typedef of function pointer passed to "start". */ typedef void*(*start_fn_t)(void*); /** Typedef of function poitner passed to "remove". */ typedef worklist_itr_t(*order_fn_t)(worklist_itr_t, worklist_itr_t); /** Simple constructor, call __init to avoid the in-charge and * not-in-charge construction costs. */ ThreadPoolImpl(bool i_checkChildRc = true) : iv_checkChildRc(i_checkChildRc) { __init(); }; protected: /** Initialize the object. */ void __init(); /** Insert a work-item onto the work-queue. */ void __insert(void*); /** Remove the next work item from the work-queue. * * Called by worker threads to find the next piece of work. * * @param[in] fn - Function to use to order the work by * priority. */ void* __remove(order_fn_t fn); /** Start the thread-pool. * * @param[in] fn - Function to use as the thread entry-point. * @param[in] instance - "this" to pass to worker threads. */ void __start(start_fn_t fn, void* instance); /** Stop the thread-pool. */ errlHndl_t __shutdown(); /** Outstanding work-list. */ worklist_t iv_worklist; /** Mutex to protect insert / remove. */ mutex_t iv_mutex; /** Condition variable to block on empty. */ sync_cond_t iv_condvar; /** List of worker threads created, to use for joining on * shutdown */ std::list iv_children; /** State of object. */ bool iv_shutdown; bool iv_checkChildRc; }; /** Prototype of 'search' functor against a threadpool. */ template struct ThreadPoolWorklistSearch; /** * Template specialization of the threadpool search functor for FIFO order. */ template struct ThreadPoolWorklistSearch<_T, false> { /** * Returns the next workitem out of a threadpool list. * * Since this is the FIFO specialization, this should just return * the next item in the list. * * @param[in] begin - Iterator to the beginning of the list. * @param[in] end - Iterator to the end of the list. * * @return begin */ static typename ThreadPoolImplContainer<_T>::worklist_itr_t search(typename ThreadPoolImplContainer<_T>::worklist_itr_t begin, typename ThreadPoolImplContainer<_T>::worklist_itr_t end) { return begin; } }; /** * Functor which performs (*a < *b). * * Since the items in a worklist are (WorkItem*)'s, they need to be * dereferenced prior to comparison. This functor performs the * dereference and comparison operation. */ template struct DerefLessCompare { bool operator()(_T* a, _T* b) { return ((*a) < (*b)); } }; /** * Template specialiation of the threadpool search functor for non-FIFO * order. */ template struct ThreadPoolWorklistSearch<_T, true> { /** * Returns the next workitem out of a threadpool list. * * Since this is the non-FIFO specialization, this should return the * minimum workitem. * * @param[in] begin - Iterator to the beginning of the list. * @param[in] end - Iterator to the end of the list. * * @return Iterator pointing to the minimum entry in the list. */ static typename ThreadPoolImplContainer<_T>::worklist_itr_t search(typename ThreadPoolImplContainer<_T>::worklist_itr_t begin, typename ThreadPoolImplContainer<_T>::worklist_itr_t end) { return std::min_element(begin,end, DerefLessCompare<_T>()); } }; }; }; #endif