ThreadPool.h revision 85133c817f6f387cd7d072988a8818f18bb53702
1d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten/* 2d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 4d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * you may not use this file except in compliance with the License. 6d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * You may obtain a copy of the License at 7d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 8d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * 10d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * See the License for the specific language governing permissions and 14d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten * limitations under the License. 15d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten */ 16d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 17369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \file ThreadPool.h ThreadPool interface */ 18d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 19cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten/** Kind of closure */ 20cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten 21cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kastentypedef enum { 22cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten CLOSURE_KIND_PPI, // void *, void *, int 2385133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi CLOSURE_KIND_PPII, // void *, void *, int, int 2485133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi CLOSURE_KIND_PIIPP // void *, int, int, void *, void * 25cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten} ClosureKind; 26cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten 27cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten/** Closure handlers */ 28cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten 2985133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivitypedef void (*ClosureHandler_generic)(void *p1, void *p2, void *p3, int i1, int i2); 3085133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivitypedef void (*ClosureHandler_ppi) (void *p1, void *p2, int i1); 3185133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivitypedef void (*ClosureHandler_ppii) (void *p1, void *p2, int i1, int i2); 3285133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivitypedef void (*ClosureHandler_piipp) (void *p1, int i1, int i2, void *p2, void *p3); 33cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten 34369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Closure represents a deferred computation */ 35369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 36369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kastentypedef struct { 37cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten union { 38cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten ClosureHandler_ppi mHandler_ppi; 39cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten ClosureHandler_ppii mHandler_ppii; 4085133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi ClosureHandler_piipp mHandler_piipp; 41cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten } mHandler; 42cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten ClosureKind mKind; 43cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten void *mContext1; 44cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten void *mContext2; 4585133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi void *mContext3; 46cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten int mParameter1; 47cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kasten int mParameter2; 48d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} Closure; 49d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 50369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief ThreadPool manages a pool of worker threads that execute Closures */ 51369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten 52d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastentypedef struct { 53369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten unsigned mInitialized; ///< Indicates which of the following 3 fields are initialized 54d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten pthread_mutex_t mMutex; 55369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten pthread_cond_t mCondNotFull; ///< Signalled when a client thread could be unblocked 56369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten pthread_cond_t mCondNotEmpty; ///< Signalled when a worker thread could be unblocked 57369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten SLboolean mShutdown; ///< Whether shutdown of thread pool has been requested 58369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten unsigned mWaitingNotFull; ///< Number of client threads waiting to enqueue 59369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten unsigned mWaitingNotEmpty; ///< Number of worker threads waiting to dequeue 60369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten unsigned mMaxClosures; ///< Number of slots in circular buffer for closures, not counting spare 61369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten unsigned mMaxThreads; ///< Number of worker threads 62369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten Closure **mClosureArray; ///< The circular buffer of closures 63d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten Closure **mClosureFront, **mClosureRear; 64369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten /// Saves a malloc in the typical case 65d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten#define CLOSURE_TYPICAL 15 66d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten Closure *mClosureTypical[CLOSURE_TYPICAL+1]; 67369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten pthread_t *mThreadArray; ///< The worker threads 68b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#ifdef ANDROID 694c7bd0776ee7fd256b12bc1b0c4d6704153f5677Glenn Kasten#define THREAD_TYPICAL 2 70b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#else 71d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten#define THREAD_TYPICAL 4 72b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten#endif 73d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten pthread_t mThreadTypical[THREAD_TYPICAL]; 74d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} ThreadPool; 75d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten 76d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern SLresult ThreadPool_init(ThreadPool *tp, unsigned maxClosures, unsigned maxThreads); 77d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern void ThreadPool_deinit(ThreadPool *tp); 78cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kastenextern SLresult ThreadPool_add(ThreadPool *tp, ClosureKind kind, 7985133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi ClosureHandler_generic, 8085133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi void *cntxt1, void *cntxt2, int param1, int param2); 81d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern Closure *ThreadPool_remove(ThreadPool *tp); 82cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kastenextern SLresult ThreadPool_add_ppi(ThreadPool *tp, ClosureHandler_ppi handler, 8385133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi void *cntxt1, void *cntxt2, int param1); 84cf3a6383a9bc9a94ca5b424ea97313293ee0dcb0Glenn Kastenextern SLresult ThreadPool_add_ppii(ThreadPool *tp, ClosureHandler_ppii handler, 8585133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi void *cntxt1, void *cntxt2, int param1, int param2); 8685133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Triviextern SLresult ThreadPool_add_piipp(ThreadPool *tp, ClosureHandler_piipp handler, 8785133c817f6f387cd7d072988a8818f18bb53702Jean-Michel Trivi void *cntxt1, int param1, int param2, void *cntxt2, void *cntxt3); 88