xref: /f-stack/app/micro_thread/micro_thread.h (revision 5ac59bc4)
1a9643ea8Slogwang 
2a9643ea8Slogwang /**
3a9643ea8Slogwang  * Tencent is pleased to support the open source community by making MSEC available.
4a9643ea8Slogwang  *
5a9643ea8Slogwang  * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Licensed under the GNU General Public License, Version 2.0 (the "License");
8a9643ea8Slogwang  * you may not use this file except in compliance with the License. You may
9a9643ea8Slogwang  * obtain a copy of the License at
10a9643ea8Slogwang  *
11a9643ea8Slogwang  *     https://opensource.org/licenses/GPL-2.0
12a9643ea8Slogwang  *
13a9643ea8Slogwang  * Unless required by applicable law or agreed to in writing, software distributed under the
14a9643ea8Slogwang  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15a9643ea8Slogwang  * either express or implied. See the License for the specific language governing permissions
16a9643ea8Slogwang  * and limitations under the License.
17a9643ea8Slogwang  */
18a9643ea8Slogwang 
19a9643ea8Slogwang 
20a9643ea8Slogwang /**
21a9643ea8Slogwang  *  @filename micro_thread.h
22a9643ea8Slogwang  *  @info  micro thread manager
23a9643ea8Slogwang  */
24a9643ea8Slogwang 
25a9643ea8Slogwang #ifndef ___MICRO_THREAD_H__
26a9643ea8Slogwang #define ___MICRO_THREAD_H__
27a9643ea8Slogwang 
28a9643ea8Slogwang #include <stdlib.h>
29a9643ea8Slogwang #include <stdio.h>
30a9643ea8Slogwang #include <unistd.h>
31a9643ea8Slogwang #include <sys/types.h>
32a9643ea8Slogwang #include <sys/socket.h>
33a9643ea8Slogwang #include <sys/ioctl.h>
34a9643ea8Slogwang #include <sys/uio.h>
35a9643ea8Slogwang #include <sys/time.h>
36a9643ea8Slogwang #include <sys/mman.h>
37a9643ea8Slogwang #include <sys/resource.h>
38a9643ea8Slogwang #include <sys/queue.h>
39a9643ea8Slogwang #include <fcntl.h>
40a9643ea8Slogwang #include <signal.h>
41a9643ea8Slogwang #include <errno.h>
42a9643ea8Slogwang #include <setjmp.h>
43a9643ea8Slogwang 
44a9643ea8Slogwang #include <set>
45a9643ea8Slogwang #include <vector>
46a9643ea8Slogwang #include <queue>
47a9643ea8Slogwang #include "heap.h"
48a9643ea8Slogwang #include "kqueue_proxy.h"
49a9643ea8Slogwang #include "heap_timer.h"
50a9643ea8Slogwang 
51a9643ea8Slogwang using std::vector;
52a9643ea8Slogwang using std::set;
53a9643ea8Slogwang using std::queue;
54a9643ea8Slogwang 
55a9643ea8Slogwang namespace NS_MICRO_THREAD {
56a9643ea8Slogwang 
57*5ac59bc4Slogwang #define STACK_PAD_SIZE      128
58*5ac59bc4Slogwang #define MEM_PAGE_SIZE       4096
59*5ac59bc4Slogwang #define DEFAULT_STACK_SIZE  128*1024
60*5ac59bc4Slogwang #define DEFAULT_THREAD_NUM  2000
61a9643ea8Slogwang 
62*5ac59bc4Slogwang typedef unsigned long long  utime64_t;
63*5ac59bc4Slogwang typedef void (*ThreadStart)(void*);
64a9643ea8Slogwang 
65a9643ea8Slogwang class ScheduleObj
66a9643ea8Slogwang {
67a9643ea8Slogwang public:
68a9643ea8Slogwang 
69a9643ea8Slogwang     static ScheduleObj* Instance (void);
70a9643ea8Slogwang 
71a9643ea8Slogwang     utime64_t ScheduleGetTime(void);
72a9643ea8Slogwang 
73a9643ea8Slogwang     void ScheduleThread(void);
74a9643ea8Slogwang 
75a9643ea8Slogwang     void ScheduleSleep(void);
76a9643ea8Slogwang 
77a9643ea8Slogwang     void SchedulePend(void);
78a9643ea8Slogwang 
79a9643ea8Slogwang     void ScheduleUnpend(void* thread);
80a9643ea8Slogwang 
81a9643ea8Slogwang     void ScheduleReclaim(void);
82a9643ea8Slogwang 
83a9643ea8Slogwang     void ScheduleStartRun(void);
84a9643ea8Slogwang 
85a9643ea8Slogwang private:
86*5ac59bc4Slogwang     static ScheduleObj* _instance;
87a9643ea8Slogwang };
88a9643ea8Slogwang 
89a9643ea8Slogwang struct MtStack
90a9643ea8Slogwang {
91*5ac59bc4Slogwang     int  _stk_size;
92*5ac59bc4Slogwang     int  _vaddr_size;
93*5ac59bc4Slogwang     char *_vaddr;
94*5ac59bc4Slogwang     void *_esp;
95*5ac59bc4Slogwang     char *_stk_bottom;
96*5ac59bc4Slogwang     char *_stk_top;
97*5ac59bc4Slogwang     void *_private;
98*5ac59bc4Slogwang     int valgrind_id;
99a9643ea8Slogwang };
100a9643ea8Slogwang 
101a9643ea8Slogwang class Thread : public  HeapEntry
102a9643ea8Slogwang {
103a9643ea8Slogwang public:
104a9643ea8Slogwang 
105a9643ea8Slogwang     explicit Thread(int stack_size = 0);
106a9643ea8Slogwang     virtual ~Thread(){};
107a9643ea8Slogwang 
108a9643ea8Slogwang     virtual void Run(void){};
109a9643ea8Slogwang 
110a9643ea8Slogwang     bool Initial(void);
111a9643ea8Slogwang 
112a9643ea8Slogwang     void Destroy(void);
113a9643ea8Slogwang 
114a9643ea8Slogwang     void Reset(void);
115a9643ea8Slogwang 
116a9643ea8Slogwang     void sleep(int ms);
117a9643ea8Slogwang 
118a9643ea8Slogwang     void Wait();
119a9643ea8Slogwang 
120a9643ea8Slogwang     void SwitchContext(void);
121a9643ea8Slogwang 
122a9643ea8Slogwang     void RestoreContext(void);
123a9643ea8Slogwang 
124a9643ea8Slogwang     utime64_t GetWakeupTime(void) {
125a9643ea8Slogwang         return _wakeup_time;
126a9643ea8Slogwang     };
127a9643ea8Slogwang 
128a9643ea8Slogwang     void SetWakeupTime(utime64_t waketime) {
129a9643ea8Slogwang         _wakeup_time = waketime;
130a9643ea8Slogwang     };
131a9643ea8Slogwang 
132a9643ea8Slogwang     void SetPrivate(void *data)
133a9643ea8Slogwang     {
134a9643ea8Slogwang         _stack->_private = data;
135a9643ea8Slogwang     }
136a9643ea8Slogwang 
137a9643ea8Slogwang     void* GetPrivate()
138a9643ea8Slogwang     {
139a9643ea8Slogwang         return _stack->_private;
140a9643ea8Slogwang     }
141a9643ea8Slogwang 
142a9643ea8Slogwang     bool CheckStackHealth(char *esp);
143a9643ea8Slogwang 
144a9643ea8Slogwang protected:
145a9643ea8Slogwang 
146a9643ea8Slogwang     virtual void CleanState(void){};
147a9643ea8Slogwang 
148a9643ea8Slogwang     virtual bool InitStack(void);
149a9643ea8Slogwang 
150a9643ea8Slogwang     virtual void FreeStack(void);
151a9643ea8Slogwang 
152a9643ea8Slogwang     virtual void InitContext(void);
153a9643ea8Slogwang 
154a9643ea8Slogwang private:
155*5ac59bc4Slogwang     MtStack* _stack;
156*5ac59bc4Slogwang     jmp_buf _jmpbuf;
157*5ac59bc4Slogwang     int _stack_size;
158*5ac59bc4Slogwang     utime64_t _wakeup_time;
159a9643ea8Slogwang };
160a9643ea8Slogwang 
161a9643ea8Slogwang class MicroThread : public Thread
162a9643ea8Slogwang {
163a9643ea8Slogwang public:
164a9643ea8Slogwang     enum ThreadType
165a9643ea8Slogwang     {
166*5ac59bc4Slogwang         NORMAL          =   0,   ///< normal thread, no dynamic allocated stack infomations.
167*5ac59bc4Slogwang         PRIMORDIAL      =   1,   ///< primordial thread, created when frame initialized.
168*5ac59bc4Slogwang         DAEMON          =   2,   ///< daemon thread, IO event management and scheduling trigger.
169*5ac59bc4Slogwang         SUB_THREAD      =   3,   ///< sub thread, run simple task.
170a9643ea8Slogwang     };
171a9643ea8Slogwang 
172a9643ea8Slogwang     enum ThreadFlag
173a9643ea8Slogwang     {
174*5ac59bc4Slogwang         NOT_INLIST    =  0x0,
175*5ac59bc4Slogwang         FREE_LIST    =  0x1,
176*5ac59bc4Slogwang         IO_LIST        =  0x2,
177*5ac59bc4Slogwang         SLEEP_LIST    =  0x4,
178*5ac59bc4Slogwang         RUN_LIST    =  0x8,
179*5ac59bc4Slogwang         PEND_LIST   =  0x10,
180*5ac59bc4Slogwang         SUB_LIST    =  0x20,
181a9643ea8Slogwang 
182a9643ea8Slogwang     };
183a9643ea8Slogwang 
184a9643ea8Slogwang     enum ThreadState
185a9643ea8Slogwang     {
186*5ac59bc4Slogwang         INITIAL         =  0,
187*5ac59bc4Slogwang         RUNABLE         =  1,
188*5ac59bc4Slogwang         RUNNING         =  2,
189*5ac59bc4Slogwang         SLEEPING        =  3,
190*5ac59bc4Slogwang         PENDING         =  4,
191a9643ea8Slogwang     };
192a9643ea8Slogwang 
193*5ac59bc4Slogwang     typedef TAILQ_ENTRY(MicroThread) ThreadLink;
194*5ac59bc4Slogwang     typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList;
195a9643ea8Slogwang 
196a9643ea8Slogwang public:
197a9643ea8Slogwang 
198a9643ea8Slogwang     MicroThread(ThreadType type = NORMAL);
199a9643ea8Slogwang     ~MicroThread(){};
200a9643ea8Slogwang 
201*5ac59bc4Slogwang     ThreadLink _entry;
202*5ac59bc4Slogwang     ThreadLink _sub_entry;
203a9643ea8Slogwang 
204a9643ea8Slogwang     virtual utime64_t HeapValue() {
205a9643ea8Slogwang         return GetWakeupTime();
206a9643ea8Slogwang     };
207a9643ea8Slogwang 
208a9643ea8Slogwang     virtual void Run(void);
209a9643ea8Slogwang 
210a9643ea8Slogwang     void ClearAllFd(void) {
211a9643ea8Slogwang         TAILQ_INIT(&_fdset);
212a9643ea8Slogwang     };
213a9643ea8Slogwang     void AddFd(KqueuerObj* efpd) {
214a9643ea8Slogwang         TAILQ_INSERT_TAIL(&_fdset, efpd, _entry);
215a9643ea8Slogwang     };
216a9643ea8Slogwang     void AddFdList(KqObjList* fdset) {
217a9643ea8Slogwang         TAILQ_CONCAT(&_fdset, fdset, _entry);
218a9643ea8Slogwang     };
219a9643ea8Slogwang     KqObjList& GetFdSet(void) {
220a9643ea8Slogwang         return _fdset;
221a9643ea8Slogwang     };
222a9643ea8Slogwang 
223a9643ea8Slogwang     void SetType(ThreadType type) {
224a9643ea8Slogwang         _type = type;
225a9643ea8Slogwang     };
226a9643ea8Slogwang     ThreadType GetType(void) {
227a9643ea8Slogwang         return _type;
228a9643ea8Slogwang     };
229a9643ea8Slogwang 
230a9643ea8Slogwang     bool IsDaemon(void) {
231a9643ea8Slogwang         return (DAEMON == _type);
232a9643ea8Slogwang     };
233a9643ea8Slogwang     bool IsPrimo(void) {
234a9643ea8Slogwang         return (PRIMORDIAL == _type);
235a9643ea8Slogwang     };
236a9643ea8Slogwang     bool IsSubThread(void) {
237a9643ea8Slogwang         return (SUB_THREAD == _type);
238a9643ea8Slogwang     };
239a9643ea8Slogwang 
240a9643ea8Slogwang     void SetParent(MicroThread* parent) {
241a9643ea8Slogwang         _parent = parent;
242a9643ea8Slogwang     };
243a9643ea8Slogwang     MicroThread* GetParent() {
244a9643ea8Slogwang         return _parent;
245a9643ea8Slogwang     };
246a9643ea8Slogwang     void WakeupParent();
247a9643ea8Slogwang 
248a9643ea8Slogwang     void AddSubThread(MicroThread* sub);
249a9643ea8Slogwang     void RemoveSubThread(MicroThread* sub);
250a9643ea8Slogwang     bool HasNoSubThread();
251a9643ea8Slogwang 
252a9643ea8Slogwang     void SetState(ThreadState state) {
253a9643ea8Slogwang         _state = state;
254a9643ea8Slogwang     };
255a9643ea8Slogwang     ThreadState GetState(void) {
256a9643ea8Slogwang         return _state;
257a9643ea8Slogwang     }
258a9643ea8Slogwang 
259a9643ea8Slogwang     void SetFlag(ThreadFlag flag) {
260a9643ea8Slogwang     _flag = (ThreadFlag)(_flag | flag);
261a9643ea8Slogwang     };
262a9643ea8Slogwang     void UnsetFlag(ThreadFlag flag) {
263a9643ea8Slogwang         _flag = (ThreadFlag)(_flag & ~flag);
264a9643ea8Slogwang     };
265a9643ea8Slogwang     bool HasFlag(ThreadFlag flag) {
266a9643ea8Slogwang     return _flag & flag;
267a9643ea8Slogwang     };
268a9643ea8Slogwang     ThreadFlag GetFlag() {
269a9643ea8Slogwang         return _flag;
270a9643ea8Slogwang     };
271a9643ea8Slogwang 
272a9643ea8Slogwang     void SetSartFunc(ThreadStart func, void* args) {
273a9643ea8Slogwang         _start = func;
274a9643ea8Slogwang         _args  = args;
275a9643ea8Slogwang     };
276a9643ea8Slogwang 
277a9643ea8Slogwang     void* GetThreadArgs() {
278a9643ea8Slogwang         return _args;
279a9643ea8Slogwang     }
280a9643ea8Slogwang 
281a9643ea8Slogwang protected:
282a9643ea8Slogwang 
283a9643ea8Slogwang     virtual void CleanState(void);
284a9643ea8Slogwang 
285a9643ea8Slogwang private:
286*5ac59bc4Slogwang     ThreadState _state;
287*5ac59bc4Slogwang     ThreadType _type;
288*5ac59bc4Slogwang     ThreadFlag _flag;
289*5ac59bc4Slogwang     KqObjList _fdset;
290*5ac59bc4Slogwang     SubThreadList _sub_list;
291*5ac59bc4Slogwang     MicroThread* _parent;
292*5ac59bc4Slogwang     ThreadStart _start;
293*5ac59bc4Slogwang     void* _args;
294a9643ea8Slogwang 
295a9643ea8Slogwang };
296*5ac59bc4Slogwang typedef std::set<MicroThread*> ThreadSet;
297*5ac59bc4Slogwang typedef std::queue<MicroThread*> ThreadList;
298a9643ea8Slogwang 
299a9643ea8Slogwang 
300a9643ea8Slogwang class LogAdapter
301a9643ea8Slogwang {
302a9643ea8Slogwang public:
303a9643ea8Slogwang 
304a9643ea8Slogwang     LogAdapter(){};
305a9643ea8Slogwang     virtual ~LogAdapter(){};
306a9643ea8Slogwang 
307a9643ea8Slogwang     virtual bool CheckDebug(){ return true;};
308a9643ea8Slogwang     virtual bool CheckTrace(){ return true;};
309a9643ea8Slogwang     virtual bool CheckError(){ return true;};
310a9643ea8Slogwang 
311a9643ea8Slogwang     virtual void LogDebug(char* fmt, ...){};
312a9643ea8Slogwang     virtual void LogTrace(char* fmt, ...){};
313a9643ea8Slogwang     virtual void LogError(char* fmt, ...){};
314a9643ea8Slogwang 
315a9643ea8Slogwang     virtual void AttrReportAdd(int attr, int iValue){};
316a9643ea8Slogwang     virtual void AttrReportSet(int attr, int iValue){};
317a9643ea8Slogwang 
318a9643ea8Slogwang };
319a9643ea8Slogwang 
320a9643ea8Slogwang 
321a9643ea8Slogwang class ThreadPool
322a9643ea8Slogwang {
323a9643ea8Slogwang public:
324a9643ea8Slogwang 
325*5ac59bc4Slogwang     static unsigned int default_thread_num;
326*5ac59bc4Slogwang     static unsigned int default_stack_size;
327a9643ea8Slogwang 
328a9643ea8Slogwang     static void SetDefaultThreadNum(unsigned int num) {
329a9643ea8Slogwang         default_thread_num = num;
330a9643ea8Slogwang     };
331a9643ea8Slogwang 
332a9643ea8Slogwang     static void SetDefaultStackSize(unsigned int size) {
333a9643ea8Slogwang         default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE;
334a9643ea8Slogwang     };
335a9643ea8Slogwang 
336a9643ea8Slogwang     bool InitialPool(int max_num);
337a9643ea8Slogwang 
338a9643ea8Slogwang     void DestroyPool (void);
339a9643ea8Slogwang 
340a9643ea8Slogwang     MicroThread* AllocThread(void);
341a9643ea8Slogwang 
342a9643ea8Slogwang     void FreeThread(MicroThread* thread);
343a9643ea8Slogwang 
344a9643ea8Slogwang     int GetUsedNum(void);
345a9643ea8Slogwang 
346a9643ea8Slogwang private:
347*5ac59bc4Slogwang     ThreadList      _freelist;
348*5ac59bc4Slogwang     int             _total_num;
349*5ac59bc4Slogwang     int             _use_num;
350*5ac59bc4Slogwang     int             _max_num;
351a9643ea8Slogwang };
352a9643ea8Slogwang 
353*5ac59bc4Slogwang typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq;
354a9643ea8Slogwang 
355a9643ea8Slogwang class MtFrame : public KqueueProxy, public ThreadPool
356a9643ea8Slogwang {
357a9643ea8Slogwang private:
358*5ac59bc4Slogwang     static MtFrame* _instance;
359*5ac59bc4Slogwang     LogAdapter*     _log_adpt;
360*5ac59bc4Slogwang     ThreadList      _runlist;
361*5ac59bc4Slogwang     ThreadTailq     _iolist;
362*5ac59bc4Slogwang     ThreadTailq     _pend_list;
363*5ac59bc4Slogwang     HeapList        _sleeplist;
364*5ac59bc4Slogwang     MicroThread*    _daemon;
365*5ac59bc4Slogwang     MicroThread*    _primo;
366*5ac59bc4Slogwang     MicroThread*    _curr_thread;
367*5ac59bc4Slogwang     utime64_t       _last_clock;
368*5ac59bc4Slogwang     int             _waitnum;
369*5ac59bc4Slogwang     CTimerMng*      _timer;
370*5ac59bc4Slogwang     int             _realtime;
371a9643ea8Slogwang 
372a9643ea8Slogwang public:
373*5ac59bc4Slogwang     friend class ScheduleObj;
374a9643ea8Slogwang 
375a9643ea8Slogwang public:
376a9643ea8Slogwang 
377a9643ea8Slogwang     static MtFrame* Instance (void);
378a9643ea8Slogwang 
379a9643ea8Slogwang     static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
380a9643ea8Slogwang 
381a9643ea8Slogwang     static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
382a9643ea8Slogwang 
383a9643ea8Slogwang     static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
384a9643ea8Slogwang 
385a9643ea8Slogwang     static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
386a9643ea8Slogwang 
387a9643ea8Slogwang     static ssize_t read(int fd, void *buf, size_t nbyte, int timeout);
388a9643ea8Slogwang 
389a9643ea8Slogwang     static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout);
390a9643ea8Slogwang 
391a9643ea8Slogwang     static int recv(int fd, void *buf, int len, int flags, int timeout);
392a9643ea8Slogwang 
393a9643ea8Slogwang     static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
394a9643ea8Slogwang 
395a9643ea8Slogwang     static void sleep(int ms);
396a9643ea8Slogwang 
397a9643ea8Slogwang     static int WaitEvents(int fd, int events, int timeout);
398a9643ea8Slogwang 
399a9643ea8Slogwang     static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true);
400a9643ea8Slogwang 
401a9643ea8Slogwang     static void DaemonRun(void* args);
402a9643ea8Slogwang     static int Loop(void* args);
403a9643ea8Slogwang 
404a9643ea8Slogwang     MicroThread *GetRootThread();
405a9643ea8Slogwang 
406a9643ea8Slogwang     bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = 50000);
407a9643ea8Slogwang 
408a9643ea8Slogwang     void SetHookFlag();
409a9643ea8Slogwang 
410a9643ea8Slogwang     void Destroy (void);
411a9643ea8Slogwang 
412a9643ea8Slogwang     char* Version(void);
413a9643ea8Slogwang 
414a9643ea8Slogwang     utime64_t GetLastClock(void) {
415a9643ea8Slogwang         if(_realtime)
416a9643ea8Slogwang         {
417a9643ea8Slogwang             return GetSystemMS();
418a9643ea8Slogwang         }
419a9643ea8Slogwang         return _last_clock;
420a9643ea8Slogwang     };
421a9643ea8Slogwang 
422a9643ea8Slogwang     MicroThread* GetActiveThread(void) {
423a9643ea8Slogwang         return _curr_thread;
424a9643ea8Slogwang     };
425a9643ea8Slogwang 
426a9643ea8Slogwang     int RunWaitNum(void) {
427a9643ea8Slogwang         return _waitnum;
428a9643ea8Slogwang     };
429a9643ea8Slogwang 
430a9643ea8Slogwang     LogAdapter* GetLogAdpt(void) {
431a9643ea8Slogwang         return _log_adpt;
432a9643ea8Slogwang     };
433a9643ea8Slogwang 
434a9643ea8Slogwang     CTimerMng* GetTimerMng(void) {
435a9643ea8Slogwang         return _timer;
436a9643ea8Slogwang     };
437a9643ea8Slogwang 
438a9643ea8Slogwang     virtual int KqueueGetTimeout(void);
439a9643ea8Slogwang 
440a9643ea8Slogwang     virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout);
441a9643ea8Slogwang 
442a9643ea8Slogwang     void WaitNotify(utime64_t timeout);
443a9643ea8Slogwang 
444a9643ea8Slogwang     void RemoveIoWait(MicroThread* thread);
445a9643ea8Slogwang 
446a9643ea8Slogwang     void InsertRunable(MicroThread* thread);
447a9643ea8Slogwang 
448a9643ea8Slogwang     void InsertPend(MicroThread* thread);
449a9643ea8Slogwang 
450a9643ea8Slogwang     void RemovePend(MicroThread* thread);
451a9643ea8Slogwang 
452a9643ea8Slogwang     void SetRealTime(int realtime_)
453a9643ea8Slogwang     {
454a9643ea8Slogwang         _realtime =realtime_;
455a9643ea8Slogwang     }
456a9643ea8Slogwang private:
457a9643ea8Slogwang 
458a9643ea8Slogwang     MtFrame():_realtime(1){ _curr_thread = NULL; };
459a9643ea8Slogwang 
460a9643ea8Slogwang     MicroThread* DaemonThread(void){
461a9643ea8Slogwang         return _daemon;
462a9643ea8Slogwang     };
463a9643ea8Slogwang 
464a9643ea8Slogwang     void ThreadSchdule(void);
465a9643ea8Slogwang 
466a9643ea8Slogwang     void CheckExpired();
467a9643ea8Slogwang 
468a9643ea8Slogwang     void WakeupTimeout(void);
469a9643ea8Slogwang 
470a9643ea8Slogwang     void SetLastClock(utime64_t clock) {
471a9643ea8Slogwang         _last_clock = clock;
472a9643ea8Slogwang     };
473a9643ea8Slogwang 
474a9643ea8Slogwang     void SetActiveThread(MicroThread* thread) {
475a9643ea8Slogwang         _curr_thread = thread;
476a9643ea8Slogwang     };
477a9643ea8Slogwang 
478a9643ea8Slogwang     utime64_t GetSystemMS(void) {
479a9643ea8Slogwang         struct timeval tv;
480a9643ea8Slogwang         gettimeofday(&tv, NULL);
481a9643ea8Slogwang         return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL);
482a9643ea8Slogwang     };
483a9643ea8Slogwang 
484a9643ea8Slogwang     void InsertSleep(MicroThread* thread);
485a9643ea8Slogwang 
486a9643ea8Slogwang     void RemoveSleep(MicroThread* thread);
487a9643ea8Slogwang 
488a9643ea8Slogwang     void InsertIoWait(MicroThread* thread);
489a9643ea8Slogwang 
490a9643ea8Slogwang     void RemoveRunable(MicroThread* thread);
491a9643ea8Slogwang 
492a9643ea8Slogwang };
493a9643ea8Slogwang 
494a9643ea8Slogwang #define MTLOG_DEBUG(fmt, args...)                                              \
495a9643ea8Slogwang do {                                                                           \
496a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
497a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckDebug())           \
498a9643ea8Slogwang        {                                                                       \
499a9643ea8Slogwang           fm->GetLogAdpt()->LogDebug((char*)"[%-10s][%-4d][%-10s]"fmt,         \
500a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
501a9643ea8Slogwang        }                                                                       \
502a9643ea8Slogwang } while (0)
503a9643ea8Slogwang 
504a9643ea8Slogwang #define MTLOG_TRACE(fmt, args...)                                              \
505a9643ea8Slogwang do {                                                                           \
506a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
507a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckTrace())           \
508a9643ea8Slogwang        {                                                                       \
509a9643ea8Slogwang           fm->GetLogAdpt()->LogTrace((char*)"[%-10s][%-4d][%-10s]"fmt,         \
510a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
511a9643ea8Slogwang        }                                                                       \
512a9643ea8Slogwang } while (0)
513a9643ea8Slogwang 
514a9643ea8Slogwang #define MTLOG_ERROR(fmt, args...)                                              \
515a9643ea8Slogwang do {                                                                           \
516a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
517a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckError())           \
518a9643ea8Slogwang        {                                                                       \
519a9643ea8Slogwang           fm->GetLogAdpt()->LogError((char*)"[%-10s][%-4d][%-10s]"fmt,         \
520a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
521a9643ea8Slogwang        }                                                                       \
522a9643ea8Slogwang } while (0)
523a9643ea8Slogwang 
524a9643ea8Slogwang #define MT_ATTR_API(ATTR, VALUE)                                               \
525a9643ea8Slogwang do {                                                                           \
526a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
527a9643ea8Slogwang        if (fm && fm->GetLogAdpt())                                             \
528a9643ea8Slogwang        {                                                                       \
529a9643ea8Slogwang           fm->GetLogAdpt()->AttrReportAdd(ATTR, VALUE);                        \
530a9643ea8Slogwang        }                                                                       \
531a9643ea8Slogwang } while (0)
532a9643ea8Slogwang 
533a9643ea8Slogwang #define MT_ATTR_API_SET(ATTR, VALUE)                                               \
534a9643ea8Slogwang        do {                                                                           \
535a9643ea8Slogwang               register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
536a9643ea8Slogwang               if (fm && fm->GetLogAdpt())                                              \
537a9643ea8Slogwang               {                                                                       \
538a9643ea8Slogwang                  fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE);                          \
539a9643ea8Slogwang               }                                                                       \
540a9643ea8Slogwang        } while (0)
541a9643ea8Slogwang 
542a9643ea8Slogwang 
543a9643ea8Slogwang 
544a9643ea8Slogwang }// NAMESPACE NS_MICRO_THREAD
545a9643ea8Slogwang 
546a9643ea8Slogwang #endif
547a9643ea8Slogwang 
548