xref: /aosp_15_r20/frameworks/base/tools/aapt/WorkQueue.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*]
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2012 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #ifndef AAPT_WORK_QUEUE_H
18*d57664e9SAndroid Build Coastguard Worker #define AAPT_WORK_QUEUE_H
19*d57664e9SAndroid Build Coastguard Worker 
20*d57664e9SAndroid Build Coastguard Worker #include <utils/Errors.h>
21*d57664e9SAndroid Build Coastguard Worker #include <utils/Vector.h>
22*d57664e9SAndroid Build Coastguard Worker #include <utils/threads.h>
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker namespace android {
25*d57664e9SAndroid Build Coastguard Worker 
26*d57664e9SAndroid Build Coastguard Worker /*
27*d57664e9SAndroid Build Coastguard Worker  * A threaded work queue.
28*d57664e9SAndroid Build Coastguard Worker  *
29*d57664e9SAndroid Build Coastguard Worker  * This class is designed to make it easy to run a bunch of isolated work
30*d57664e9SAndroid Build Coastguard Worker  * units in parallel, using up to the specified number of threads.
31*d57664e9SAndroid Build Coastguard Worker  * To use it, write a loop to post work units to the work queue, then synchronize
32*d57664e9SAndroid Build Coastguard Worker  * on the queue at the end.
33*d57664e9SAndroid Build Coastguard Worker  */
34*d57664e9SAndroid Build Coastguard Worker class WorkQueue {
35*d57664e9SAndroid Build Coastguard Worker public:
36*d57664e9SAndroid Build Coastguard Worker     class WorkUnit {
37*d57664e9SAndroid Build Coastguard Worker     public:
WorkUnit()38*d57664e9SAndroid Build Coastguard Worker         WorkUnit() { }
~WorkUnit()39*d57664e9SAndroid Build Coastguard Worker         virtual ~WorkUnit() { }
40*d57664e9SAndroid Build Coastguard Worker 
41*d57664e9SAndroid Build Coastguard Worker         /*
42*d57664e9SAndroid Build Coastguard Worker          * Runs the work unit.
43*d57664e9SAndroid Build Coastguard Worker          * If the result is 'true' then the work queue continues scheduling work as usual.
44*d57664e9SAndroid Build Coastguard Worker          * If the result is 'false' then the work queue is canceled.
45*d57664e9SAndroid Build Coastguard Worker          */
46*d57664e9SAndroid Build Coastguard Worker         virtual bool run() = 0;
47*d57664e9SAndroid Build Coastguard Worker     };
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker     /* Creates a work queue with the specified maximum number of work threads. */
50*d57664e9SAndroid Build Coastguard Worker     explicit WorkQueue(size_t maxThreads, bool canCallJava = true);
51*d57664e9SAndroid Build Coastguard Worker 
52*d57664e9SAndroid Build Coastguard Worker     /* Destroys the work queue.
53*d57664e9SAndroid Build Coastguard Worker      * Cancels pending work and waits for all remaining threads to complete.
54*d57664e9SAndroid Build Coastguard Worker      */
55*d57664e9SAndroid Build Coastguard Worker     ~WorkQueue();
56*d57664e9SAndroid Build Coastguard Worker 
57*d57664e9SAndroid Build Coastguard Worker     /* Posts a work unit to run later.
58*d57664e9SAndroid Build Coastguard Worker      * If the work queue has been canceled or is already finished, returns INVALID_OPERATION
59*d57664e9SAndroid Build Coastguard Worker      * and does not take ownership of the work unit (caller must destroy it itself).
60*d57664e9SAndroid Build Coastguard Worker      * Otherwise, returns OK and takes ownership of the work unit (the work queue will
61*d57664e9SAndroid Build Coastguard Worker      * destroy it automatically).
62*d57664e9SAndroid Build Coastguard Worker      *
63*d57664e9SAndroid Build Coastguard Worker      * For flow control, this method blocks when the size of the pending work queue is more
64*d57664e9SAndroid Build Coastguard Worker      * 'backlog' times the number of threads.  This condition reduces the rate of entry into
65*d57664e9SAndroid Build Coastguard Worker      * the pending work queue and prevents it from growing much more rapidly than the
66*d57664e9SAndroid Build Coastguard Worker      * work threads can actually handle.
67*d57664e9SAndroid Build Coastguard Worker      *
68*d57664e9SAndroid Build Coastguard Worker      * If 'backlog' is 0, then no throttle is applied.
69*d57664e9SAndroid Build Coastguard Worker      */
70*d57664e9SAndroid Build Coastguard Worker     status_t schedule(WorkUnit* workUnit, size_t backlog = 2);
71*d57664e9SAndroid Build Coastguard Worker 
72*d57664e9SAndroid Build Coastguard Worker     /* Cancels all pending work.
73*d57664e9SAndroid Build Coastguard Worker      * If the work queue is already finished, returns INVALID_OPERATION.
74*d57664e9SAndroid Build Coastguard Worker      * If the work queue is already canceled, returns OK and does nothing else.
75*d57664e9SAndroid Build Coastguard Worker      * Otherwise, returns OK, discards all pending work units and prevents additional
76*d57664e9SAndroid Build Coastguard Worker      * work units from being scheduled.
77*d57664e9SAndroid Build Coastguard Worker      *
78*d57664e9SAndroid Build Coastguard Worker      * Call finish() after cancel() to wait for all remaining work to complete.
79*d57664e9SAndroid Build Coastguard Worker      */
80*d57664e9SAndroid Build Coastguard Worker     status_t cancel();
81*d57664e9SAndroid Build Coastguard Worker 
82*d57664e9SAndroid Build Coastguard Worker     /* Waits for all work to complete.
83*d57664e9SAndroid Build Coastguard Worker      * If the work queue is already finished, returns INVALID_OPERATION.
84*d57664e9SAndroid Build Coastguard Worker      * Otherwise, waits for all work to complete and returns OK.
85*d57664e9SAndroid Build Coastguard Worker      */
86*d57664e9SAndroid Build Coastguard Worker     status_t finish();
87*d57664e9SAndroid Build Coastguard Worker 
88*d57664e9SAndroid Build Coastguard Worker private:
89*d57664e9SAndroid Build Coastguard Worker     class WorkThread : public Thread {
90*d57664e9SAndroid Build Coastguard Worker     public:
91*d57664e9SAndroid Build Coastguard Worker         WorkThread(WorkQueue* workQueue, bool canCallJava);
92*d57664e9SAndroid Build Coastguard Worker         virtual ~WorkThread();
93*d57664e9SAndroid Build Coastguard Worker 
94*d57664e9SAndroid Build Coastguard Worker     private:
95*d57664e9SAndroid Build Coastguard Worker         virtual bool threadLoop();
96*d57664e9SAndroid Build Coastguard Worker 
97*d57664e9SAndroid Build Coastguard Worker         WorkQueue* const mWorkQueue;
98*d57664e9SAndroid Build Coastguard Worker     };
99*d57664e9SAndroid Build Coastguard Worker 
100*d57664e9SAndroid Build Coastguard Worker     status_t cancelLocked();
101*d57664e9SAndroid Build Coastguard Worker     bool threadLoop(); // called from each work thread
102*d57664e9SAndroid Build Coastguard Worker 
103*d57664e9SAndroid Build Coastguard Worker     const size_t mMaxThreads;
104*d57664e9SAndroid Build Coastguard Worker     const bool mCanCallJava;
105*d57664e9SAndroid Build Coastguard Worker 
106*d57664e9SAndroid Build Coastguard Worker     Mutex mLock;
107*d57664e9SAndroid Build Coastguard Worker     Condition mWorkChangedCondition;
108*d57664e9SAndroid Build Coastguard Worker     Condition mWorkDequeuedCondition;
109*d57664e9SAndroid Build Coastguard Worker 
110*d57664e9SAndroid Build Coastguard Worker     bool mCanceled;
111*d57664e9SAndroid Build Coastguard Worker     bool mFinished;
112*d57664e9SAndroid Build Coastguard Worker     size_t mIdleThreads;
113*d57664e9SAndroid Build Coastguard Worker     Vector<sp<WorkThread> > mWorkThreads;
114*d57664e9SAndroid Build Coastguard Worker     Vector<WorkUnit*> mWorkUnits;
115*d57664e9SAndroid Build Coastguard Worker };
116*d57664e9SAndroid Build Coastguard Worker 
117*d57664e9SAndroid Build Coastguard Worker }; // namespace android
118*d57664e9SAndroid Build Coastguard Worker 
119*d57664e9SAndroid Build Coastguard Worker #endif // AAPT_WORK_QUEUE_H
120