xref: /f-stack/app/micro_thread/micro_thread.h (revision 7cdf410c)
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>
43*84bcae25Swoolen #include <stdarg.h>
44a9643ea8Slogwang 
45a9643ea8Slogwang #include <set>
46a9643ea8Slogwang #include <vector>
47a9643ea8Slogwang #include <queue>
48a9643ea8Slogwang #include "heap.h"
49a9643ea8Slogwang #include "kqueue_proxy.h"
50a9643ea8Slogwang #include "heap_timer.h"
51a9643ea8Slogwang 
52a9643ea8Slogwang using std::vector;
53a9643ea8Slogwang using std::set;
54a9643ea8Slogwang using std::queue;
55a9643ea8Slogwang 
56a9643ea8Slogwang namespace NS_MICRO_THREAD {
57a9643ea8Slogwang 
585ac59bc4Slogwang #define STACK_PAD_SIZE      128
595ac59bc4Slogwang #define MEM_PAGE_SIZE       4096
60*84bcae25Swoolen #define DEFAULT_STACK_SIZE  STACK_PAD_SIZE * 1024
61*84bcae25Swoolen #define DEFAULT_THREAD_NUM  5000
62*84bcae25Swoolen #define MAX_THREAD_NUM  800000
63a9643ea8Slogwang 
645ac59bc4Slogwang typedef unsigned long long  utime64_t;
655ac59bc4Slogwang typedef void (*ThreadStart)(void*);
66a9643ea8Slogwang 
67a9643ea8Slogwang class ScheduleObj
68a9643ea8Slogwang {
69a9643ea8Slogwang public:
70a9643ea8Slogwang 
71a9643ea8Slogwang     static ScheduleObj* Instance (void);
72a9643ea8Slogwang 
73a9643ea8Slogwang     utime64_t ScheduleGetTime(void);
74a9643ea8Slogwang 
75a9643ea8Slogwang     void ScheduleThread(void);
76a9643ea8Slogwang 
77a9643ea8Slogwang     void ScheduleSleep(void);
78a9643ea8Slogwang 
79a9643ea8Slogwang     void SchedulePend(void);
80a9643ea8Slogwang 
81a9643ea8Slogwang     void ScheduleUnpend(void* thread);
82a9643ea8Slogwang 
83a9643ea8Slogwang     void ScheduleReclaim(void);
84a9643ea8Slogwang 
85a9643ea8Slogwang     void ScheduleStartRun(void);
86a9643ea8Slogwang 
87a9643ea8Slogwang private:
885ac59bc4Slogwang     static ScheduleObj* _instance;
89a9643ea8Slogwang };
90a9643ea8Slogwang 
91a9643ea8Slogwang struct MtStack
92a9643ea8Slogwang {
935ac59bc4Slogwang     int  _stk_size;
945ac59bc4Slogwang     int  _vaddr_size;
955ac59bc4Slogwang     char *_vaddr;
965ac59bc4Slogwang     void *_esp;
975ac59bc4Slogwang     char *_stk_bottom;
985ac59bc4Slogwang     char *_stk_top;
995ac59bc4Slogwang     void *_private;
1005ac59bc4Slogwang     int valgrind_id;
101a9643ea8Slogwang };
102a9643ea8Slogwang 
103a9643ea8Slogwang class Thread : public  HeapEntry
104a9643ea8Slogwang {
105a9643ea8Slogwang public:
106a9643ea8Slogwang 
107a9643ea8Slogwang     explicit Thread(int stack_size = 0);
~Thread()108a9643ea8Slogwang     virtual ~Thread(){};
109a9643ea8Slogwang 
Run(void)110a9643ea8Slogwang     virtual void Run(void){};
111a9643ea8Slogwang 
112a9643ea8Slogwang     bool Initial(void);
113a9643ea8Slogwang 
114a9643ea8Slogwang     void Destroy(void);
115a9643ea8Slogwang 
116a9643ea8Slogwang     void Reset(void);
117a9643ea8Slogwang 
118a9643ea8Slogwang     void sleep(int ms);
119a9643ea8Slogwang 
120a9643ea8Slogwang     void Wait();
121a9643ea8Slogwang 
122a9643ea8Slogwang     void SwitchContext(void);
123a9643ea8Slogwang 
124*84bcae25Swoolen     int SaveContext(void);
125*84bcae25Swoolen 
126a9643ea8Slogwang     void RestoreContext(void);
127a9643ea8Slogwang 
GetWakeupTime(void)128a9643ea8Slogwang     utime64_t GetWakeupTime(void) {
129a9643ea8Slogwang         return _wakeup_time;
130a9643ea8Slogwang     };
131a9643ea8Slogwang 
SetWakeupTime(utime64_t waketime)132a9643ea8Slogwang     void SetWakeupTime(utime64_t waketime) {
133a9643ea8Slogwang         _wakeup_time = waketime;
134a9643ea8Slogwang     };
135a9643ea8Slogwang 
SetPrivate(void * data)136a9643ea8Slogwang     void SetPrivate(void *data)
137a9643ea8Slogwang     {
138a9643ea8Slogwang         _stack->_private = data;
139a9643ea8Slogwang     }
140a9643ea8Slogwang 
GetPrivate()141a9643ea8Slogwang     void* GetPrivate()
142a9643ea8Slogwang     {
143a9643ea8Slogwang         return _stack->_private;
144a9643ea8Slogwang     }
145a9643ea8Slogwang 
146a9643ea8Slogwang     bool CheckStackHealth(char *esp);
147a9643ea8Slogwang 
148a9643ea8Slogwang protected:
149a9643ea8Slogwang 
CleanState(void)150a9643ea8Slogwang     virtual void CleanState(void){};
151a9643ea8Slogwang 
152a9643ea8Slogwang     virtual bool InitStack(void);
153a9643ea8Slogwang 
154a9643ea8Slogwang     virtual void FreeStack(void);
155a9643ea8Slogwang 
156a9643ea8Slogwang     virtual void InitContext(void);
157a9643ea8Slogwang 
158a9643ea8Slogwang private:
1595ac59bc4Slogwang     MtStack* _stack;
1605ac59bc4Slogwang     jmp_buf _jmpbuf;
1615ac59bc4Slogwang     int _stack_size;
1625ac59bc4Slogwang     utime64_t _wakeup_time;
163a9643ea8Slogwang };
164a9643ea8Slogwang 
165a9643ea8Slogwang class MicroThread : public Thread
166a9643ea8Slogwang {
167a9643ea8Slogwang public:
168a9643ea8Slogwang     enum ThreadType
169a9643ea8Slogwang     {
1705ac59bc4Slogwang         NORMAL          =   0,   ///< normal thread, no dynamic allocated stack infomations.
1715ac59bc4Slogwang         PRIMORDIAL      =   1,   ///< primordial thread, created when frame initialized.
1725ac59bc4Slogwang         DAEMON          =   2,   ///< daemon thread, IO event management and scheduling trigger.
1735ac59bc4Slogwang         SUB_THREAD      =   3,   ///< sub thread, run simple task.
174a9643ea8Slogwang     };
175a9643ea8Slogwang 
176a9643ea8Slogwang     enum ThreadFlag
177a9643ea8Slogwang     {
1785ac59bc4Slogwang         NOT_INLIST    =  0x0,
1795ac59bc4Slogwang         FREE_LIST    =  0x1,
1805ac59bc4Slogwang         IO_LIST        =  0x2,
1815ac59bc4Slogwang         SLEEP_LIST    =  0x4,
1825ac59bc4Slogwang         RUN_LIST    =  0x8,
1835ac59bc4Slogwang         PEND_LIST   =  0x10,
1845ac59bc4Slogwang         SUB_LIST    =  0x20,
185a9643ea8Slogwang 
186a9643ea8Slogwang     };
187a9643ea8Slogwang 
188a9643ea8Slogwang     enum ThreadState
189a9643ea8Slogwang     {
1905ac59bc4Slogwang         INITIAL         =  0,
1915ac59bc4Slogwang         RUNABLE         =  1,
1925ac59bc4Slogwang         RUNNING         =  2,
1935ac59bc4Slogwang         SLEEPING        =  3,
1945ac59bc4Slogwang         PENDING         =  4,
195a9643ea8Slogwang     };
196a9643ea8Slogwang 
1975ac59bc4Slogwang     typedef TAILQ_ENTRY(MicroThread) ThreadLink;
1985ac59bc4Slogwang     typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList;
199a9643ea8Slogwang 
200a9643ea8Slogwang public:
201a9643ea8Slogwang 
202a9643ea8Slogwang     MicroThread(ThreadType type = NORMAL);
~MicroThread()203a9643ea8Slogwang     ~MicroThread(){};
204a9643ea8Slogwang 
2055ac59bc4Slogwang     ThreadLink _entry;
2065ac59bc4Slogwang     ThreadLink _sub_entry;
207a9643ea8Slogwang 
HeapValue()208a9643ea8Slogwang     virtual utime64_t HeapValue() {
209a9643ea8Slogwang         return GetWakeupTime();
210a9643ea8Slogwang     };
211a9643ea8Slogwang 
212a9643ea8Slogwang     virtual void Run(void);
213a9643ea8Slogwang 
ClearAllFd(void)214a9643ea8Slogwang     void ClearAllFd(void) {
215a9643ea8Slogwang         TAILQ_INIT(&_fdset);
216a9643ea8Slogwang     };
AddFd(KqueuerObj * efpd)217a9643ea8Slogwang     void AddFd(KqueuerObj* efpd) {
218a9643ea8Slogwang         TAILQ_INSERT_TAIL(&_fdset, efpd, _entry);
219a9643ea8Slogwang     };
AddFdList(KqObjList * fdset)220a9643ea8Slogwang     void AddFdList(KqObjList* fdset) {
221a9643ea8Slogwang         TAILQ_CONCAT(&_fdset, fdset, _entry);
222a9643ea8Slogwang     };
GetFdSet(void)223a9643ea8Slogwang     KqObjList& GetFdSet(void) {
224a9643ea8Slogwang         return _fdset;
225a9643ea8Slogwang     };
226a9643ea8Slogwang 
SetType(ThreadType type)227a9643ea8Slogwang     void SetType(ThreadType type) {
228a9643ea8Slogwang         _type = type;
229a9643ea8Slogwang     };
GetType(void)230a9643ea8Slogwang     ThreadType GetType(void) {
231a9643ea8Slogwang         return _type;
232a9643ea8Slogwang     };
233a9643ea8Slogwang 
IsDaemon(void)234a9643ea8Slogwang     bool IsDaemon(void) {
235a9643ea8Slogwang         return (DAEMON == _type);
236a9643ea8Slogwang     };
IsPrimo(void)237a9643ea8Slogwang     bool IsPrimo(void) {
238a9643ea8Slogwang         return (PRIMORDIAL == _type);
239a9643ea8Slogwang     };
IsSubThread(void)240a9643ea8Slogwang     bool IsSubThread(void) {
241a9643ea8Slogwang         return (SUB_THREAD == _type);
242a9643ea8Slogwang     };
243a9643ea8Slogwang 
SetParent(MicroThread * parent)244a9643ea8Slogwang     void SetParent(MicroThread* parent) {
245a9643ea8Slogwang         _parent = parent;
246a9643ea8Slogwang     };
GetParent()247a9643ea8Slogwang     MicroThread* GetParent() {
248a9643ea8Slogwang         return _parent;
249a9643ea8Slogwang     };
250a9643ea8Slogwang     void WakeupParent();
251a9643ea8Slogwang 
252a9643ea8Slogwang     void AddSubThread(MicroThread* sub);
253a9643ea8Slogwang     void RemoveSubThread(MicroThread* sub);
254a9643ea8Slogwang     bool HasNoSubThread();
255a9643ea8Slogwang 
SetState(ThreadState state)256a9643ea8Slogwang     void SetState(ThreadState state) {
257a9643ea8Slogwang         _state = state;
258a9643ea8Slogwang     };
GetState(void)259a9643ea8Slogwang     ThreadState GetState(void) {
260a9643ea8Slogwang         return _state;
261a9643ea8Slogwang     }
262a9643ea8Slogwang 
SetFlag(ThreadFlag flag)263a9643ea8Slogwang     void SetFlag(ThreadFlag flag) {
264a9643ea8Slogwang     _flag = (ThreadFlag)(_flag | flag);
265a9643ea8Slogwang     };
UnsetFlag(ThreadFlag flag)266a9643ea8Slogwang     void UnsetFlag(ThreadFlag flag) {
267a9643ea8Slogwang         _flag = (ThreadFlag)(_flag & ~flag);
268a9643ea8Slogwang     };
HasFlag(ThreadFlag flag)269a9643ea8Slogwang     bool HasFlag(ThreadFlag flag) {
270a9643ea8Slogwang     return _flag & flag;
271a9643ea8Slogwang     };
GetFlag()272a9643ea8Slogwang     ThreadFlag GetFlag() {
273a9643ea8Slogwang         return _flag;
274a9643ea8Slogwang     };
275a9643ea8Slogwang 
SetSartFunc(ThreadStart func,void * args)276a9643ea8Slogwang     void SetSartFunc(ThreadStart func, void* args) {
277a9643ea8Slogwang         _start = func;
278a9643ea8Slogwang         _args  = args;
279a9643ea8Slogwang     };
280a9643ea8Slogwang 
GetThreadArgs()281a9643ea8Slogwang     void* GetThreadArgs() {
282a9643ea8Slogwang         return _args;
283a9643ea8Slogwang     }
284a9643ea8Slogwang 
285a9643ea8Slogwang protected:
286a9643ea8Slogwang 
287a9643ea8Slogwang     virtual void CleanState(void);
288a9643ea8Slogwang 
289a9643ea8Slogwang private:
2905ac59bc4Slogwang     ThreadState _state;
2915ac59bc4Slogwang     ThreadType _type;
2925ac59bc4Slogwang     ThreadFlag _flag;
2935ac59bc4Slogwang     KqObjList _fdset;
2945ac59bc4Slogwang     SubThreadList _sub_list;
2955ac59bc4Slogwang     MicroThread* _parent;
2965ac59bc4Slogwang     ThreadStart _start;
2975ac59bc4Slogwang     void* _args;
298a9643ea8Slogwang 
299a9643ea8Slogwang };
3005ac59bc4Slogwang typedef std::set<MicroThread*> ThreadSet;
3015ac59bc4Slogwang typedef std::queue<MicroThread*> ThreadList;
302a9643ea8Slogwang 
303a9643ea8Slogwang 
304a9643ea8Slogwang class LogAdapter
305a9643ea8Slogwang {
306a9643ea8Slogwang public:
307a9643ea8Slogwang 
LogAdapter()308a9643ea8Slogwang     LogAdapter(){};
~LogAdapter()309a9643ea8Slogwang     virtual ~LogAdapter(){};
310a9643ea8Slogwang 
CheckDebug()311a9643ea8Slogwang     virtual bool CheckDebug(){ return true;};
CheckTrace()312a9643ea8Slogwang     virtual bool CheckTrace(){ return true;};
CheckError()313a9643ea8Slogwang     virtual bool CheckError(){ return true;};
314a9643ea8Slogwang 
LogDebug(char * fmt,...)315a9643ea8Slogwang     virtual void LogDebug(char* fmt, ...){};
LogTrace(char * fmt,...)316a9643ea8Slogwang     virtual void LogTrace(char* fmt, ...){};
LogError(char * fmt,...)317a9643ea8Slogwang     virtual void LogError(char* fmt, ...){};
318a9643ea8Slogwang 
AttrReportAdd(int attr,int iValue)319a9643ea8Slogwang     virtual void AttrReportAdd(int attr, int iValue){};
AttrReportSet(int attr,int iValue)320a9643ea8Slogwang     virtual void AttrReportSet(int attr, int iValue){};
321a9643ea8Slogwang 
322a9643ea8Slogwang };
323a9643ea8Slogwang 
324*84bcae25Swoolen class DefaultLogAdapter :public LogAdapter
325*84bcae25Swoolen {
326*84bcae25Swoolen public:
327*84bcae25Swoolen 
328*84bcae25Swoolen 
CheckDebug()329*84bcae25Swoolen     bool CheckDebug(){ return false;};
CheckTrace()330*84bcae25Swoolen     bool CheckTrace(){ return false;};
CheckError()331*84bcae25Swoolen     bool CheckError(){ return false;};
332*84bcae25Swoolen 
LogDebug(char * fmt,...)333*84bcae25Swoolen     inline void LogDebug(char* fmt, ...){
334*84bcae25Swoolen         va_list args;
335*84bcae25Swoolen         char szBuff[1024];
336*84bcae25Swoolen         va_start(args, fmt);
337*84bcae25Swoolen         memset(szBuff, 0, sizeof(szBuff));
338*84bcae25Swoolen         vsprintf(szBuff, fmt, args);
339*84bcae25Swoolen         va_end(args);
340*84bcae25Swoolen         printf("%s\n",szBuff);
341*84bcae25Swoolen     };
LogTrace(char * fmt,...)342*84bcae25Swoolen     inline void LogTrace(char* fmt, ...){
343*84bcae25Swoolen         va_list args;
344*84bcae25Swoolen         char szBuff[1024];
345*84bcae25Swoolen         va_start(args, fmt);
346*84bcae25Swoolen         memset(szBuff, 0, sizeof(szBuff));
347*84bcae25Swoolen         vsprintf(szBuff, fmt, args);
348*84bcae25Swoolen         va_end(args);
349*84bcae25Swoolen         printf("%s\n",szBuff);
350*84bcae25Swoolen     };
LogError(char * fmt,...)351*84bcae25Swoolen     inline void LogError(char* fmt, ...){
352*84bcae25Swoolen         va_list args;
353*84bcae25Swoolen         char szBuff[1024];
354*84bcae25Swoolen         va_start(args, fmt);
355*84bcae25Swoolen         memset(szBuff, 0, sizeof(szBuff));
356*84bcae25Swoolen         vsprintf(szBuff, fmt, args);
357*84bcae25Swoolen         va_end(args);
358*84bcae25Swoolen         printf("%s\n",szBuff);
359*84bcae25Swoolen     };
360*84bcae25Swoolen 
361*84bcae25Swoolen };
362a9643ea8Slogwang 
363a9643ea8Slogwang class ThreadPool
364a9643ea8Slogwang {
365a9643ea8Slogwang public:
366a9643ea8Slogwang 
3675ac59bc4Slogwang     static unsigned int default_thread_num;
368*84bcae25Swoolen     static unsigned int last_default_thread_num;
3695ac59bc4Slogwang     static unsigned int default_stack_size;
370a9643ea8Slogwang 
SetDefaultThreadNum(unsigned int num)371a9643ea8Slogwang     static void SetDefaultThreadNum(unsigned int num) {
372a9643ea8Slogwang         default_thread_num = num;
373a9643ea8Slogwang     };
374a9643ea8Slogwang 
SetDefaultStackSize(unsigned int size)375a9643ea8Slogwang     static void SetDefaultStackSize(unsigned int size) {
376a9643ea8Slogwang         default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE;
377a9643ea8Slogwang     };
378a9643ea8Slogwang 
379a9643ea8Slogwang     bool InitialPool(int max_num);
380a9643ea8Slogwang 
381a9643ea8Slogwang     void DestroyPool (void);
382a9643ea8Slogwang 
383a9643ea8Slogwang     MicroThread* AllocThread(void);
384a9643ea8Slogwang 
385a9643ea8Slogwang     void FreeThread(MicroThread* thread);
386a9643ea8Slogwang 
387a9643ea8Slogwang     int GetUsedNum(void);
388a9643ea8Slogwang 
389a9643ea8Slogwang private:
3905ac59bc4Slogwang     ThreadList      _freelist;
3915ac59bc4Slogwang     int             _total_num;
3925ac59bc4Slogwang     int             _use_num;
3935ac59bc4Slogwang     int             _max_num;
394a9643ea8Slogwang };
395a9643ea8Slogwang 
3965ac59bc4Slogwang typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq;
397a9643ea8Slogwang 
398a9643ea8Slogwang class MtFrame : public KqueueProxy, public ThreadPool
399a9643ea8Slogwang {
400a9643ea8Slogwang private:
4015ac59bc4Slogwang     static MtFrame* _instance;
4025ac59bc4Slogwang     LogAdapter*     _log_adpt;
4035ac59bc4Slogwang     ThreadList      _runlist;
4045ac59bc4Slogwang     ThreadTailq     _iolist;
4055ac59bc4Slogwang     ThreadTailq     _pend_list;
4065ac59bc4Slogwang     HeapList        _sleeplist;
4075ac59bc4Slogwang     MicroThread*    _daemon;
4085ac59bc4Slogwang     MicroThread*    _primo;
4095ac59bc4Slogwang     MicroThread*    _curr_thread;
4105ac59bc4Slogwang     utime64_t       _last_clock;
4115ac59bc4Slogwang     int             _waitnum;
4125ac59bc4Slogwang     CTimerMng*      _timer;
4135ac59bc4Slogwang     int             _realtime;
414a9643ea8Slogwang 
415a9643ea8Slogwang public:
4165ac59bc4Slogwang     friend class ScheduleObj;
417a9643ea8Slogwang 
418a9643ea8Slogwang public:
419a9643ea8Slogwang 
420a9643ea8Slogwang     static MtFrame* Instance (void);
421a9643ea8Slogwang 
422a9643ea8Slogwang     static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
423a9643ea8Slogwang 
424a9643ea8Slogwang     static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
425a9643ea8Slogwang 
426a9643ea8Slogwang     static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
427a9643ea8Slogwang 
428a9643ea8Slogwang     static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
429a9643ea8Slogwang 
430a9643ea8Slogwang     static ssize_t read(int fd, void *buf, size_t nbyte, int timeout);
431a9643ea8Slogwang 
432a9643ea8Slogwang     static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout);
433a9643ea8Slogwang 
434a9643ea8Slogwang     static int recv(int fd, void *buf, int len, int flags, int timeout);
435a9643ea8Slogwang 
436a9643ea8Slogwang     static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
437a9643ea8Slogwang 
438a9643ea8Slogwang     static void sleep(int ms);
439a9643ea8Slogwang 
440a9643ea8Slogwang     static int WaitEvents(int fd, int events, int timeout);
441a9643ea8Slogwang 
442a9643ea8Slogwang     static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true);
443a9643ea8Slogwang 
444a9643ea8Slogwang     static void DaemonRun(void* args);
445a9643ea8Slogwang     static int Loop(void* args);
446a9643ea8Slogwang 
447a9643ea8Slogwang     MicroThread *GetRootThread();
448a9643ea8Slogwang 
449*84bcae25Swoolen     bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = MAX_THREAD_NUM);
450a9643ea8Slogwang 
451a9643ea8Slogwang     void SetHookFlag();
452a9643ea8Slogwang 
453a9643ea8Slogwang     void Destroy (void);
454a9643ea8Slogwang 
455a9643ea8Slogwang     char* Version(void);
456a9643ea8Slogwang 
GetLastClock(void)457a9643ea8Slogwang     utime64_t GetLastClock(void) {
458a9643ea8Slogwang         if(_realtime)
459a9643ea8Slogwang         {
460a9643ea8Slogwang             return GetSystemMS();
461a9643ea8Slogwang         }
462a9643ea8Slogwang         return _last_clock;
463a9643ea8Slogwang     };
464a9643ea8Slogwang 
GetActiveThread(void)465a9643ea8Slogwang     MicroThread* GetActiveThread(void) {
466a9643ea8Slogwang         return _curr_thread;
467a9643ea8Slogwang     };
468a9643ea8Slogwang 
RunWaitNum(void)469a9643ea8Slogwang     int RunWaitNum(void) {
470a9643ea8Slogwang         return _waitnum;
471a9643ea8Slogwang     };
472a9643ea8Slogwang 
GetLogAdpt(void)473a9643ea8Slogwang     LogAdapter* GetLogAdpt(void) {
474a9643ea8Slogwang         return _log_adpt;
475a9643ea8Slogwang     };
476a9643ea8Slogwang 
GetTimerMng(void)477a9643ea8Slogwang     CTimerMng* GetTimerMng(void) {
478a9643ea8Slogwang         return _timer;
479a9643ea8Slogwang     };
480a9643ea8Slogwang 
481a9643ea8Slogwang     virtual int KqueueGetTimeout(void);
482a9643ea8Slogwang 
483a9643ea8Slogwang     virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout);
484a9643ea8Slogwang 
485a9643ea8Slogwang     void WaitNotify(utime64_t timeout);
486a9643ea8Slogwang 
487*84bcae25Swoolen     void NotifyThread(MicroThread* thread);
488*84bcae25Swoolen 
489*84bcae25Swoolen     void SwapDaemonThread();
490*84bcae25Swoolen 
491a9643ea8Slogwang     void RemoveIoWait(MicroThread* thread);
492a9643ea8Slogwang 
493a9643ea8Slogwang     void InsertRunable(MicroThread* thread);
494a9643ea8Slogwang 
495a9643ea8Slogwang     void InsertPend(MicroThread* thread);
496a9643ea8Slogwang 
497a9643ea8Slogwang     void RemovePend(MicroThread* thread);
498a9643ea8Slogwang 
SetRealTime(int realtime_)499a9643ea8Slogwang     void SetRealTime(int realtime_)
500a9643ea8Slogwang     {
501a9643ea8Slogwang         _realtime =realtime_;
502a9643ea8Slogwang     }
503a9643ea8Slogwang private:
504a9643ea8Slogwang 
MtFrame()505a9643ea8Slogwang     MtFrame():_realtime(1){ _curr_thread = NULL; };
506a9643ea8Slogwang 
DaemonThread(void)507a9643ea8Slogwang     MicroThread* DaemonThread(void){
508a9643ea8Slogwang         return _daemon;
509a9643ea8Slogwang     };
510a9643ea8Slogwang 
511a9643ea8Slogwang     void ThreadSchdule(void);
512a9643ea8Slogwang 
513a9643ea8Slogwang     void CheckExpired();
514a9643ea8Slogwang 
515a9643ea8Slogwang     void WakeupTimeout(void);
516a9643ea8Slogwang 
SetLastClock(utime64_t clock)517a9643ea8Slogwang     void SetLastClock(utime64_t clock) {
518a9643ea8Slogwang         _last_clock = clock;
519a9643ea8Slogwang     };
520a9643ea8Slogwang 
SetActiveThread(MicroThread * thread)521a9643ea8Slogwang     void SetActiveThread(MicroThread* thread) {
522a9643ea8Slogwang         _curr_thread = thread;
523a9643ea8Slogwang     };
524a9643ea8Slogwang 
GetSystemMS(void)525a9643ea8Slogwang     utime64_t GetSystemMS(void) {
526a9643ea8Slogwang         struct timeval tv;
527a9643ea8Slogwang         gettimeofday(&tv, NULL);
528a9643ea8Slogwang         return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL);
529a9643ea8Slogwang     };
530a9643ea8Slogwang 
531a9643ea8Slogwang     void InsertSleep(MicroThread* thread);
532a9643ea8Slogwang 
533a9643ea8Slogwang     void RemoveSleep(MicroThread* thread);
534a9643ea8Slogwang 
535a9643ea8Slogwang     void InsertIoWait(MicroThread* thread);
536a9643ea8Slogwang 
537a9643ea8Slogwang     void RemoveRunable(MicroThread* thread);
538a9643ea8Slogwang 
539a9643ea8Slogwang };
540a9643ea8Slogwang 
541a9643ea8Slogwang #define MTLOG_DEBUG(fmt, args...)                                              \
542a9643ea8Slogwang do {                                                                           \
543a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
544a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckDebug())           \
545a9643ea8Slogwang        {                                                                       \
546a9643ea8Slogwang           fm->GetLogAdpt()->LogDebug((char*)"[%-10s][%-4d][%-10s]" fmt,        \
547a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
548a9643ea8Slogwang        }                                                                       \
549a9643ea8Slogwang } while (0)
550a9643ea8Slogwang 
551a9643ea8Slogwang #define MTLOG_TRACE(fmt, args...)                                              \
552a9643ea8Slogwang do {                                                                           \
553a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
554a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckTrace())           \
555a9643ea8Slogwang        {                                                                       \
556a9643ea8Slogwang           fm->GetLogAdpt()->LogTrace((char*)"[%-10s][%-4d][%-10s]" fmt,        \
557a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
558a9643ea8Slogwang        }                                                                       \
559a9643ea8Slogwang } while (0)
560a9643ea8Slogwang 
561a9643ea8Slogwang #define MTLOG_ERROR(fmt, args...)                                              \
562a9643ea8Slogwang do {                                                                           \
563a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
564a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckError())           \
565a9643ea8Slogwang        {                                                                       \
566a9643ea8Slogwang           fm->GetLogAdpt()->LogError((char*)"[%-10s][%-4d][%-10s]" fmt,        \
567a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
568a9643ea8Slogwang        }                                                                       \
569a9643ea8Slogwang } while (0)
570a9643ea8Slogwang 
571a9643ea8Slogwang #define MT_ATTR_API(ATTR, VALUE)                                               \
572a9643ea8Slogwang do {                                                                           \
573a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
574a9643ea8Slogwang        if (fm && fm->GetLogAdpt())                                             \
575a9643ea8Slogwang        {                                                                       \
576a9643ea8Slogwang           fm->GetLogAdpt()->AttrReportAdd(ATTR, VALUE);                        \
577a9643ea8Slogwang        }                                                                       \
578a9643ea8Slogwang } while (0)
579a9643ea8Slogwang 
580a9643ea8Slogwang #define MT_ATTR_API_SET(ATTR, VALUE)                                               \
581a9643ea8Slogwang        do {                                                                           \
582a9643ea8Slogwang               register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
583a9643ea8Slogwang               if (fm && fm->GetLogAdpt())                                              \
584a9643ea8Slogwang               {                                                                       \
585a9643ea8Slogwang                  fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE);                          \
586a9643ea8Slogwang               }                                                                       \
587a9643ea8Slogwang        } while (0)
588a9643ea8Slogwang 
589a9643ea8Slogwang 
590a9643ea8Slogwang 
591a9643ea8Slogwang }// NAMESPACE NS_MICRO_THREAD
592a9643ea8Slogwang 
593a9643ea8Slogwang #endif
594a9643ea8Slogwang 
595