ThreadPool.h revision 369f3138f19f7102bf0f98b890ab84c8df633a93
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
19369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief Closure represents a deferred computation */
20369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten
21369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kastentypedef struct {
22510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    void (*mHandler)(void *, int);
23d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    void *mContext;
24510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    int mParameter;
25d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} Closure;
26d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten
27369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten/** \brief ThreadPool manages a pool of worker threads that execute Closures */
28369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten
29d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastentypedef struct {
30369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    unsigned mInitialized; ///< Indicates which of the following 3 fields are initialized
31d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    pthread_mutex_t mMutex;
32369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    pthread_cond_t mCondNotFull;    ///< Signalled when a client thread could be unblocked
33369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    pthread_cond_t mCondNotEmpty;   ///< Signalled when a worker thread could be unblocked
34369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    SLboolean mShutdown;   ///< Whether shutdown of thread pool has been requested
35369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    unsigned mWaitingNotFull;   ///< Number of client threads waiting to enqueue
36369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    unsigned mWaitingNotEmpty;  ///< Number of worker threads waiting to dequeue
37369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    unsigned mMaxClosures;  ///< Number of slots in circular buffer for closures, not counting spare
38369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    unsigned mMaxThreads;   ///< Number of worker threads
39369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    Closure **mClosureArray;    ///< The circular buffer of closures
40d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    Closure **mClosureFront, **mClosureRear;
41369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    /// Saves a malloc in the typical case
42d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten#define CLOSURE_TYPICAL 15
43d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    Closure *mClosureTypical[CLOSURE_TYPICAL+1];
44369f3138f19f7102bf0f98b890ab84c8df633a93Glenn Kasten    pthread_t *mThreadArray;    ///< The worker threads
45d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten#define THREAD_TYPICAL 4
46d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    pthread_t mThreadTypical[THREAD_TYPICAL];
47d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten} ThreadPool;
48d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten
49d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern SLresult ThreadPool_init(ThreadPool *tp, unsigned maxClosures, unsigned maxThreads);
50d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern void ThreadPool_deinit(ThreadPool *tp);
51510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kastenextern SLresult ThreadPool_add(ThreadPool *tp, void (*handler)(void *, int), void *context,
52510f3671f716f6835282e4b0fd0275c20e9dadd8Glenn Kasten    int parameter);
53d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenextern Closure *ThreadPool_remove(ThreadPool *tp);
54