1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef THREAD_H
17 #define THREAD_H
18 
19 #include <thread>
20 
21 #include "platform/threadpool/include/aie_thread_unix.h"
22 #include "utils/aie_macros.h"
23 #include "utils/constants/constants.h"
24 
25 namespace OHOS {
26 namespace AI {
27 const size_t THREAD_MIN_STACK_SIZE = (1024 * 64);
28 const size_t THREAD_MAX_STACK_SIZE = (1024 * 1024 * 64);
29 const int THREAD_SLEEP_MS = 1;
30 class Thread;
31 
32 class IWorker {
33 public:
34     IWorker();
35 
36     virtual ~IWorker();
37 
38     /**
39      * attention sub class need to realize this, and cannot return null
40      *
41      * @return Worker name
42      */
43     virtual const char *GetName() const = 0;
44 
45     /**
46      * attention thread will call OneAction loop, until the thread is stopped. or return false
47      *
48      * @return true thread is running, false thread is stop
49      */
50     virtual bool OneAction() = 0;
51 
52     /**
53      * attention this method is called in "thread" first, if return false, thread stop auto.
54      *
55      * @return true success, false failure and the thread stop
56      */
Initialize()57     virtual bool Initialize()
58     {
59         return true;
60     }
61 
62     /**
63      * attention this method is called when thread stop, it is still run in thread.
64      */
Uninitialize()65     virtual void Uninitialize() {}
66 
67     /**
68      * judge if the thread is Hung
69      *
70      * @return true is Hung, false is not Hung
71      */
isHung(const time_t)72     virtual bool isHung(const time_t) const
73     {
74         return false;
75     }
76 
77     /**
78      * get the stack size
79      *
80      * @return 0 no request on size(default), greater than 0 means the size of stack size
81      */
GetStackSize()82     virtual size_t GetStackSize()
83     {
84         return THREAD_DEFAULT_STACK_SIZE;
85     }
86 
87     enum WorkerStatus {
88         IDLE,
89         BUSY
90     };
91 
92     /**
93      * get worker status
94      *
95      * @return the status on thread
96      */
Status()97     WorkerStatus Status()
98     {
99         return status_;
100     }
101 
102     /**
103      * attention set status
104      *
105      * @param [in] IDLE or BUSY
106      */
Status(WorkerStatus status)107     void Status(WorkerStatus status)
108     {
109         status_ = status;
110     }
111 
SetThread(Thread * thread)112     void SetThread(Thread *thread)
113     {
114         thread_ = thread;
115     }
116 
117     volatile int counter_;
118 
119     unsigned long GetThreadId();
120 
121 protected:
122     Thread *thread_;
123 
124 private:
125     WorkerStatus status_;
126 };
127 
128 class ThreadPool;
129 class Thread {
130     friend class ThreadPool;
131 
132 public:
133 
134     Thread();
135     virtual ~Thread();
136 
137     /**
138      * set stack size, attention: must be set before StartThread
139      *
140      * @param [in] >64k is valid
141      * @return A pointer to the singleton instance.
142      */
143     void SetStackSize(const size_t size);
144 
145     /**
146      * attention: need to make sure run() method is not overloaded before
147      *
148      * @return true success , false failure
149      */
150     bool StartThread(IWorker *pWorker);
151 
152     void StopThread();
153 
154     bool StopThread(int timeOut);
155 
156     // wait until thread is stop
157     void WaitForEnd();
158 
159     enum ThreadStatus {
160         PREPARED,
161         RUNNING,
162         STOPPED
163     };
164 
165     /**
166      * attention: get thread status
167      *
168      * @return PREPARED, RUNNING, STOPPED
169      */
170     ThreadStatus Status() const;
171 
172     const IWorker *GetWorker() const;
173 
174     void SetWorker(IWorker *pWorker);
175 
176     bool IsActive() const;
177 
178     bool IsHung(time_t now) const;
179 
180     unsigned long GetThreadId() const;
181 
182     bool IsRunning() const;
183 
184 private:
185     bool StartThread();
186     void Execute();
187     virtual void Run();
188 
189     static void *ThreadProc(void*);
190 
191 private:
192     volatile bool running_;
193     volatile ThreadStatus status_;
194 
195     size_t stackSize_;
196     PthreadData thread_;
197     IWorker *worker_;
198 };
199 } // namespace AI
200 } // namespace OHOS
201 
202 #endif // THREAD_H
203