xref: /f-stack/app/micro_thread/micro_thread.h (revision a9643ea8)
1*a9643ea8Slogwang 
2*a9643ea8Slogwang /**
3*a9643ea8Slogwang  * Tencent is pleased to support the open source community by making MSEC available.
4*a9643ea8Slogwang  *
5*a9643ea8Slogwang  * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
6*a9643ea8Slogwang  *
7*a9643ea8Slogwang  * Licensed under the GNU General Public License, Version 2.0 (the "License");
8*a9643ea8Slogwang  * you may not use this file except in compliance with the License. You may
9*a9643ea8Slogwang  * obtain a copy of the License at
10*a9643ea8Slogwang  *
11*a9643ea8Slogwang  *     https://opensource.org/licenses/GPL-2.0
12*a9643ea8Slogwang  *
13*a9643ea8Slogwang  * Unless required by applicable law or agreed to in writing, software distributed under the
14*a9643ea8Slogwang  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15*a9643ea8Slogwang  * either express or implied. See the License for the specific language governing permissions
16*a9643ea8Slogwang  * and limitations under the License.
17*a9643ea8Slogwang  */
18*a9643ea8Slogwang 
19*a9643ea8Slogwang 
20*a9643ea8Slogwang /**
21*a9643ea8Slogwang  *  @filename micro_thread.h
22*a9643ea8Slogwang  *  @info  micro thread manager
23*a9643ea8Slogwang  */
24*a9643ea8Slogwang 
25*a9643ea8Slogwang #ifndef ___MICRO_THREAD_H__
26*a9643ea8Slogwang #define ___MICRO_THREAD_H__
27*a9643ea8Slogwang 
28*a9643ea8Slogwang #include <stdlib.h>
29*a9643ea8Slogwang #include <stdio.h>
30*a9643ea8Slogwang #include <unistd.h>
31*a9643ea8Slogwang #include <sys/types.h>
32*a9643ea8Slogwang #include <sys/socket.h>
33*a9643ea8Slogwang #include <sys/ioctl.h>
34*a9643ea8Slogwang #include <sys/uio.h>
35*a9643ea8Slogwang #include <sys/time.h>
36*a9643ea8Slogwang #include <sys/mman.h>
37*a9643ea8Slogwang #include <sys/resource.h>
38*a9643ea8Slogwang #include <sys/queue.h>
39*a9643ea8Slogwang #include <fcntl.h>
40*a9643ea8Slogwang #include <signal.h>
41*a9643ea8Slogwang #include <errno.h>
42*a9643ea8Slogwang #include <setjmp.h>
43*a9643ea8Slogwang 
44*a9643ea8Slogwang #include <set>
45*a9643ea8Slogwang #include <vector>
46*a9643ea8Slogwang #include <queue>
47*a9643ea8Slogwang #include "heap.h"
48*a9643ea8Slogwang #include "kqueue_proxy.h"
49*a9643ea8Slogwang #include "heap_timer.h"
50*a9643ea8Slogwang 
51*a9643ea8Slogwang using std::vector;
52*a9643ea8Slogwang using std::set;
53*a9643ea8Slogwang using std::queue;
54*a9643ea8Slogwang 
55*a9643ea8Slogwang namespace NS_MICRO_THREAD {
56*a9643ea8Slogwang 
57*a9643ea8Slogwang #define STACK_PAD_SIZE      128         ///< ջ���¸�������Ĵ�С
58*a9643ea8Slogwang #define MEM_PAGE_SIZE       4096        ///< �ڴ�ҳĬ�ϴ�С
59*a9643ea8Slogwang #define DEFAULT_STACK_SIZE  128*1024    ///< Ĭ��ջ��С128K
60*a9643ea8Slogwang #define DEFAULT_THREAD_NUM  2000        ///< Ĭ��2000����ʼ�߳�
61*a9643ea8Slogwang 
62*a9643ea8Slogwang typedef unsigned long long  utime64_t;  ///< 64λ��ʱ�䶨��
63*a9643ea8Slogwang typedef void (*ThreadStart)(void*);      ///< ΢�߳���ں�������
64*a9643ea8Slogwang 
65*a9643ea8Slogwang /**
66*a9643ea8Slogwang  * @brief �̵߳��ȵ����������, �������С�ӿڷ�װ
67*a9643ea8Slogwang  */
68*a9643ea8Slogwang class ScheduleObj
69*a9643ea8Slogwang {
70*a9643ea8Slogwang public:
71*a9643ea8Slogwang 
72*a9643ea8Slogwang     /**
73*a9643ea8Slogwang      * @brief ��������ʾ�����
74*a9643ea8Slogwang      */
75*a9643ea8Slogwang     static ScheduleObj* Instance (void);
76*a9643ea8Slogwang 
77*a9643ea8Slogwang     /**
78*a9643ea8Slogwang      * @brief ��ȡȫ�ֵ�ʱ���, ���뵥λ
79*a9643ea8Slogwang      */
80*a9643ea8Slogwang     utime64_t ScheduleGetTime(void);
81*a9643ea8Slogwang 
82*a9643ea8Slogwang     /**
83*a9643ea8Slogwang      * @brief ��������΢�߳�������
84*a9643ea8Slogwang      */
85*a9643ea8Slogwang     void ScheduleThread(void);
86*a9643ea8Slogwang 
87*a9643ea8Slogwang     /**
88*a9643ea8Slogwang      * @brief �̵߳�����������sleep״̬
89*a9643ea8Slogwang      */
90*a9643ea8Slogwang     void ScheduleSleep(void);
91*a9643ea8Slogwang 
92*a9643ea8Slogwang     /**
93*a9643ea8Slogwang      * @brief �̵߳�����������pend״̬
94*a9643ea8Slogwang      */
95*a9643ea8Slogwang     void SchedulePend(void);
96*a9643ea8Slogwang 
97*a9643ea8Slogwang     /**
98*a9643ea8Slogwang      * @brief �̵߳���ȡ��pend״̬, �ⲿ����ȡ��
99*a9643ea8Slogwang      */
100*a9643ea8Slogwang     void ScheduleUnpend(void* thread);
101*a9643ea8Slogwang 
102*a9643ea8Slogwang     /**
103*a9643ea8Slogwang      * @brief �߳�ִ����Ϻ�, ���մ���
104*a9643ea8Slogwang      */
105*a9643ea8Slogwang     void ScheduleReclaim(void);
106*a9643ea8Slogwang 
107*a9643ea8Slogwang     /**
108*a9643ea8Slogwang      * @brief ���������ȳ�ʼִ��
109*a9643ea8Slogwang      */
110*a9643ea8Slogwang     void ScheduleStartRun(void);
111*a9643ea8Slogwang 
112*a9643ea8Slogwang private:
113*a9643ea8Slogwang     static ScheduleObj* _instance;   // ˽�о��
114*a9643ea8Slogwang };
115*a9643ea8Slogwang 
116*a9643ea8Slogwang 
117*a9643ea8Slogwang /**
118*a9643ea8Slogwang  * @brief �߳�ͨ�õ�ջ֡�ṹ����
119*a9643ea8Slogwang  */
120*a9643ea8Slogwang struct MtStack
121*a9643ea8Slogwang {
122*a9643ea8Slogwang     int  _stk_size;              ///< ջ�Ĵ�С, ��Чʹ�ÿռ�
123*a9643ea8Slogwang     int  _vaddr_size;            ///< �����buff�ܴ�С
124*a9643ea8Slogwang     char *_vaddr;                ///< ������ڴ����ַ
125*a9643ea8Slogwang     void *_esp;                  ///< ջ��esp�Ĵ���
126*a9643ea8Slogwang     char *_stk_bottom;           ///< ջ��͵ĵ�ַ�ռ�
127*a9643ea8Slogwang     char *_stk_top;              ///< ջ��ߵĵ�ַ�ռ�
128*a9643ea8Slogwang     void *_private;              ///< �߳�˽������
129*a9643ea8Slogwang 	int valgrind_id;			 ///< valgrind id
130*a9643ea8Slogwang };
131*a9643ea8Slogwang 
132*a9643ea8Slogwang 
133*a9643ea8Slogwang /**
134*a9643ea8Slogwang  * @brief ͨ�õ��߳�ģ�Ͷ���
135*a9643ea8Slogwang  */
136*a9643ea8Slogwang class Thread : public  HeapEntry
137*a9643ea8Slogwang {
138*a9643ea8Slogwang public:
139*a9643ea8Slogwang 
140*a9643ea8Slogwang     /**
141*a9643ea8Slogwang      * @brief ��������������
142*a9643ea8Slogwang      */
143*a9643ea8Slogwang     explicit Thread(int stack_size = 0);
144*a9643ea8Slogwang     virtual ~Thread(){};
145*a9643ea8Slogwang 
146*a9643ea8Slogwang     /**
147*a9643ea8Slogwang      * @brief �̵߳�ʵ�ʹ�������
148*a9643ea8Slogwang      */
149*a9643ea8Slogwang     virtual void Run(void){};
150*a9643ea8Slogwang 
151*a9643ea8Slogwang     /**
152*a9643ea8Slogwang      * @brief ��ʼ���߳�,���ջ�������ij�ʼ��
153*a9643ea8Slogwang      */
154*a9643ea8Slogwang     bool Initial(void);
155*a9643ea8Slogwang 
156*a9643ea8Slogwang     /**
157*a9643ea8Slogwang      * @brief ��ֹ�߳�,���ջ���������ͷ�
158*a9643ea8Slogwang      */
159*a9643ea8Slogwang     void Destroy(void);
160*a9643ea8Slogwang 
161*a9643ea8Slogwang     /**
162*a9643ea8Slogwang      * @brief �߳�״̬����, �ɸ���״̬
163*a9643ea8Slogwang      */
164*a9643ea8Slogwang     void Reset(void);
165*a9643ea8Slogwang 
166*a9643ea8Slogwang     /**
167*a9643ea8Slogwang      * @brief �߳���������˯��, ��λ����
168*a9643ea8Slogwang      * @param ms ˯�ߺ�����
169*a9643ea8Slogwang      */
170*a9643ea8Slogwang     void sleep(int ms);
171*a9643ea8Slogwang 
172*a9643ea8Slogwang     /**
173*a9643ea8Slogwang      * @brief �߳���������ȴ�, �ö����߳�������
174*a9643ea8Slogwang      */
175*a9643ea8Slogwang     void Wait();
176*a9643ea8Slogwang 
177*a9643ea8Slogwang     /**
178*a9643ea8Slogwang      * @brief �����л�, ����״̬, ��������
179*a9643ea8Slogwang      */
180*a9643ea8Slogwang     void SwitchContext(void);
181*a9643ea8Slogwang 
182*a9643ea8Slogwang     /**
183*a9643ea8Slogwang      * @brief �ָ�������, �л�����
184*a9643ea8Slogwang      */
185*a9643ea8Slogwang     void RestoreContext(void);
186*a9643ea8Slogwang 
187*a9643ea8Slogwang     /**
188*a9643ea8Slogwang      * @brief ��ȡ�����ʱ��
189*a9643ea8Slogwang      * @return �̵߳Ļ���ʱ���
190*a9643ea8Slogwang      */
191*a9643ea8Slogwang     utime64_t GetWakeupTime(void) {
192*a9643ea8Slogwang         return _wakeup_time;
193*a9643ea8Slogwang     };
194*a9643ea8Slogwang 
195*a9643ea8Slogwang     /**
196*a9643ea8Slogwang      * @brief ���������ʱ��
197*a9643ea8Slogwang      * @param waketime �̵߳Ļ���ʱ���
198*a9643ea8Slogwang      */
199*a9643ea8Slogwang     void SetWakeupTime(utime64_t waketime) {
200*a9643ea8Slogwang         _wakeup_time = waketime;
201*a9643ea8Slogwang     };
202*a9643ea8Slogwang 
203*a9643ea8Slogwang     /**
204*a9643ea8Slogwang      * @brief �����߳�˽������
205*a9643ea8Slogwang      * @param data �߳�˽������ָ�룬ʹ�������Լ������ڴ棬����ֻ����ָ��
206*a9643ea8Slogwang      */
207*a9643ea8Slogwang     void SetPrivate(void *data)
208*a9643ea8Slogwang     {
209*a9643ea8Slogwang         _stack->_private = data;
210*a9643ea8Slogwang     }
211*a9643ea8Slogwang 
212*a9643ea8Slogwang     /**
213*a9643ea8Slogwang      * @brief ��ȡ�߳�˽������
214*a9643ea8Slogwang      */
215*a9643ea8Slogwang     void* GetPrivate()
216*a9643ea8Slogwang     {
217*a9643ea8Slogwang         return _stack->_private;
218*a9643ea8Slogwang     }
219*a9643ea8Slogwang 
220*a9643ea8Slogwang 	/**
221*a9643ea8Slogwang      * @brief ��ʼ��������,���üĴ���,��ջ
222*a9643ea8Slogwang      */
223*a9643ea8Slogwang     bool CheckStackHealth(char *esp);
224*a9643ea8Slogwang 
225*a9643ea8Slogwang protected:
226*a9643ea8Slogwang 
227*a9643ea8Slogwang     /**
228*a9643ea8Slogwang      * @brief �����̴߳���״̬, ׼������
229*a9643ea8Slogwang      */
230*a9643ea8Slogwang     virtual void CleanState(void){};
231*a9643ea8Slogwang 
232*a9643ea8Slogwang     /**
233*a9643ea8Slogwang      * @brief ��ʼ����ջ��Ϣ
234*a9643ea8Slogwang      */
235*a9643ea8Slogwang     virtual bool InitStack(void);
236*a9643ea8Slogwang 
237*a9643ea8Slogwang     /**
238*a9643ea8Slogwang      * @brief �ͷŶ�ջ��Ϣ
239*a9643ea8Slogwang      */
240*a9643ea8Slogwang     virtual void FreeStack(void);
241*a9643ea8Slogwang 
242*a9643ea8Slogwang     /**
243*a9643ea8Slogwang      * @brief ��ʼ��������,���üĴ���,��ջ
244*a9643ea8Slogwang      */
245*a9643ea8Slogwang     virtual void InitContext(void);
246*a9643ea8Slogwang 
247*a9643ea8Slogwang private:
248*a9643ea8Slogwang     MtStack* _stack;        ///< ˽��ջָ��
249*a9643ea8Slogwang     jmp_buf _jmpbuf;        ///< ������jmpbuff
250*a9643ea8Slogwang     int _stack_size;        ///< ջ��С�ֶ�
251*a9643ea8Slogwang     utime64_t _wakeup_time; ///< ˯�߻���ʱ��
252*a9643ea8Slogwang };
253*a9643ea8Slogwang 
254*a9643ea8Slogwang 
255*a9643ea8Slogwang /**
256*a9643ea8Slogwang  * @brief ΢�߳����ݽṹ����
257*a9643ea8Slogwang  */
258*a9643ea8Slogwang class MicroThread : public Thread
259*a9643ea8Slogwang {
260*a9643ea8Slogwang public:
261*a9643ea8Slogwang     enum ThreadType
262*a9643ea8Slogwang     {
263*a9643ea8Slogwang         NORMAL          =   0,   ///< Ĭ����ͨ�߳�, û�ж�̬�����ջ��Ϣ
264*a9643ea8Slogwang         PRIMORDIAL      =   1,   ///< ԭ���߳�, main��������
265*a9643ea8Slogwang         DAEMON          =   2,   ///< �ػ��߳�, �ײ�IO EPOLL��������ȴ���
266*a9643ea8Slogwang         SUB_THREAD      =   3,   ///< �����߳�, ��ִ�м�����
267*a9643ea8Slogwang     };
268*a9643ea8Slogwang 
269*a9643ea8Slogwang     enum ThreadFlag
270*a9643ea8Slogwang     {
271*a9643ea8Slogwang         NOT_INLIST	=  0x0,     ///< �޶���״̬
272*a9643ea8Slogwang         FREE_LIST	=  0x1,     ///< ���ж�����
273*a9643ea8Slogwang         IO_LIST		=  0x2,     ///< IO�ȴ�������
274*a9643ea8Slogwang         SLEEP_LIST	=  0x4,     ///< ����SLEEP��
275*a9643ea8Slogwang         RUN_LIST	=  0x8,     ///< �����ж�����
276*a9643ea8Slogwang         PEND_LIST   =  0x10,    ///< ����������
277*a9643ea8Slogwang         SUB_LIST    =  0x20,    ///< �����̶߳�����
278*a9643ea8Slogwang 
279*a9643ea8Slogwang     };
280*a9643ea8Slogwang 
281*a9643ea8Slogwang     enum ThreadState
282*a9643ea8Slogwang     {
283*a9643ea8Slogwang         INITIAL         =  0,   ///< ��ʼ��״̬
284*a9643ea8Slogwang         RUNABLE         =  1,   ///< ������״̬
285*a9643ea8Slogwang         RUNNING         =  2,   ///< ����������
286*a9643ea8Slogwang         SLEEPING        =  3,   ///< IO�ȴ���SLEEP��
287*a9643ea8Slogwang         PENDING         =  4,   ///< ����״̬��, �ȴ����߳�OK��
288*a9643ea8Slogwang     };
289*a9643ea8Slogwang 
290*a9643ea8Slogwang     typedef TAILQ_ENTRY(MicroThread) ThreadLink;        ///< ΢�߳�����
291*a9643ea8Slogwang     typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList;  ///< ΢�̶߳��ж���
292*a9643ea8Slogwang 
293*a9643ea8Slogwang public:
294*a9643ea8Slogwang 
295*a9643ea8Slogwang     /**
296*a9643ea8Slogwang      * @brief ΢�̹߳���������
297*a9643ea8Slogwang      */
298*a9643ea8Slogwang     MicroThread(ThreadType type = NORMAL);
299*a9643ea8Slogwang     ~MicroThread(){};
300*a9643ea8Slogwang 
301*a9643ea8Slogwang     ThreadLink _entry;          ///<  ״̬�������
302*a9643ea8Slogwang     ThreadLink _sub_entry;      ///<  ���̶߳������
303*a9643ea8Slogwang 
304*a9643ea8Slogwang     /**
305*a9643ea8Slogwang      * @brief ΢�̶߳�������ʵ��,������ʱ����絽������
306*a9643ea8Slogwang      * @return �̵߳�ʵ�ʻ���ʱ��
307*a9643ea8Slogwang      */
308*a9643ea8Slogwang     virtual utime64_t HeapValue() {
309*a9643ea8Slogwang         return GetWakeupTime();
310*a9643ea8Slogwang     };
311*a9643ea8Slogwang 
312*a9643ea8Slogwang     /**
313*a9643ea8Slogwang      * @brief �̵߳�ʵ�ʹ�������
314*a9643ea8Slogwang      */
315*a9643ea8Slogwang     virtual void Run(void);
316*a9643ea8Slogwang 
317*a9643ea8Slogwang     /**
318*a9643ea8Slogwang      * @breif fd����������в���
319*a9643ea8Slogwang      */
320*a9643ea8Slogwang     void ClearAllFd(void) {
321*a9643ea8Slogwang         TAILQ_INIT(&_fdset);
322*a9643ea8Slogwang     };
323*a9643ea8Slogwang     void AddFd(KqueuerObj* efpd) {
324*a9643ea8Slogwang         TAILQ_INSERT_TAIL(&_fdset, efpd, _entry);
325*a9643ea8Slogwang     };
326*a9643ea8Slogwang     void AddFdList(KqObjList* fdset) {
327*a9643ea8Slogwang         TAILQ_CONCAT(&_fdset, fdset, _entry);
328*a9643ea8Slogwang     };
329*a9643ea8Slogwang     KqObjList& GetFdSet(void) {
330*a9643ea8Slogwang         return _fdset;
331*a9643ea8Slogwang     };
332*a9643ea8Slogwang 
333*a9643ea8Slogwang     /**
334*a9643ea8Slogwang      * @breif ΢�߳����͹������
335*a9643ea8Slogwang      */
336*a9643ea8Slogwang     void SetType(ThreadType type) {
337*a9643ea8Slogwang         _type = type;
338*a9643ea8Slogwang     };
339*a9643ea8Slogwang     ThreadType GetType(void) {
340*a9643ea8Slogwang         return _type;
341*a9643ea8Slogwang     };
342*a9643ea8Slogwang 
343*a9643ea8Slogwang     /**
344*a9643ea8Slogwang      * @breif ΢�߳����ͼ��ӿ�
345*a9643ea8Slogwang      */
346*a9643ea8Slogwang     bool IsDaemon(void) {
347*a9643ea8Slogwang         return (DAEMON == _type);
348*a9643ea8Slogwang     };
349*a9643ea8Slogwang     bool IsPrimo(void) {
350*a9643ea8Slogwang         return (PRIMORDIAL == _type);
351*a9643ea8Slogwang     };
352*a9643ea8Slogwang     bool IsSubThread(void) {
353*a9643ea8Slogwang         return (SUB_THREAD == _type);
354*a9643ea8Slogwang     };
355*a9643ea8Slogwang 
356*a9643ea8Slogwang     /**
357*a9643ea8Slogwang      * @brief  ���߳����������
358*a9643ea8Slogwang      */
359*a9643ea8Slogwang     void SetParent(MicroThread* parent) {
360*a9643ea8Slogwang         _parent = parent;
361*a9643ea8Slogwang     };
362*a9643ea8Slogwang     MicroThread* GetParent() {
363*a9643ea8Slogwang         return _parent;
364*a9643ea8Slogwang     };
365*a9643ea8Slogwang     void WakeupParent();
366*a9643ea8Slogwang 
367*a9643ea8Slogwang     /**
368*a9643ea8Slogwang      * @brief  ���̵߳Ĺ���
369*a9643ea8Slogwang      */
370*a9643ea8Slogwang     void AddSubThread(MicroThread* sub);
371*a9643ea8Slogwang     void RemoveSubThread(MicroThread* sub);
372*a9643ea8Slogwang     bool HasNoSubThread();
373*a9643ea8Slogwang 
374*a9643ea8Slogwang     /**
375*a9643ea8Slogwang      * @brief ΢�߳�����״̬����
376*a9643ea8Slogwang      */
377*a9643ea8Slogwang     void SetState(ThreadState state) {
378*a9643ea8Slogwang         _state = state;
379*a9643ea8Slogwang     };
380*a9643ea8Slogwang     ThreadState GetState(void) {
381*a9643ea8Slogwang         return _state;
382*a9643ea8Slogwang     }
383*a9643ea8Slogwang 
384*a9643ea8Slogwang     /**
385*a9643ea8Slogwang      * @breif ΢�̱߳��λ����
386*a9643ea8Slogwang      */
387*a9643ea8Slogwang     void SetFlag(ThreadFlag flag) {
388*a9643ea8Slogwang 	_flag = (ThreadFlag)(_flag | flag);
389*a9643ea8Slogwang     };
390*a9643ea8Slogwang     void UnsetFlag(ThreadFlag flag) {
391*a9643ea8Slogwang         _flag = (ThreadFlag)(_flag & ~flag);
392*a9643ea8Slogwang     };
393*a9643ea8Slogwang     bool HasFlag(ThreadFlag flag) {
394*a9643ea8Slogwang 	return _flag & flag;
395*a9643ea8Slogwang     };
396*a9643ea8Slogwang     ThreadFlag GetFlag() {
397*a9643ea8Slogwang         return _flag;
398*a9643ea8Slogwang     };
399*a9643ea8Slogwang 
400*a9643ea8Slogwang     /**
401*a9643ea8Slogwang      * @breif ΢�߳���ں�������ע��
402*a9643ea8Slogwang      */
403*a9643ea8Slogwang     void SetSartFunc(ThreadStart func, void* args) {
404*a9643ea8Slogwang         _start = func;
405*a9643ea8Slogwang         _args  = args;
406*a9643ea8Slogwang     };
407*a9643ea8Slogwang 
408*a9643ea8Slogwang     void* GetThreadArgs() {
409*a9643ea8Slogwang         return _args;
410*a9643ea8Slogwang     }
411*a9643ea8Slogwang 
412*a9643ea8Slogwang protected:
413*a9643ea8Slogwang 
414*a9643ea8Slogwang     /**
415*a9643ea8Slogwang      * @breif ΢�̸߳���״̬����
416*a9643ea8Slogwang      */
417*a9643ea8Slogwang     virtual void CleanState(void);
418*a9643ea8Slogwang 
419*a9643ea8Slogwang private:
420*a9643ea8Slogwang     ThreadState _state;         ///< ΢�̵߳�ǰ״̬
421*a9643ea8Slogwang     ThreadType _type;           ///< ΢�߳�����
422*a9643ea8Slogwang     ThreadFlag _flag;           ///< ΢�̱߳��λ
423*a9643ea8Slogwang     KqObjList _fdset;           ///< ΢�̹߳�ע��socket�б�
424*a9643ea8Slogwang     SubThreadList _sub_list;    ///< �����̵߳Ķ���
425*a9643ea8Slogwang     MicroThread* _parent;       ///< �����̵߳ĸ��߳�
426*a9643ea8Slogwang     ThreadStart _start;         ///< ΢�߳�ע�ắ��
427*a9643ea8Slogwang     void* _args;                ///< ΢�߳�ע�����
428*a9643ea8Slogwang 
429*a9643ea8Slogwang };
430*a9643ea8Slogwang typedef std::set<MicroThread*> ThreadSet;       ///< ΢�߳�set����ṹ
431*a9643ea8Slogwang typedef std::queue<MicroThread*> ThreadList;    ///< ΢�߳�queue����ṹ
432*a9643ea8Slogwang 
433*a9643ea8Slogwang 
434*a9643ea8Slogwang /**
435*a9643ea8Slogwang  * @brief ΢�߳���־�ӿ�, �ײ��, ��־�ɵ�����ע��
436*a9643ea8Slogwang  */
437*a9643ea8Slogwang class LogAdapter
438*a9643ea8Slogwang {
439*a9643ea8Slogwang public:
440*a9643ea8Slogwang 
441*a9643ea8Slogwang     /**
442*a9643ea8Slogwang      * @brief ��־����������
443*a9643ea8Slogwang      */
444*a9643ea8Slogwang     LogAdapter(){};
445*a9643ea8Slogwang     virtual ~LogAdapter(){};
446*a9643ea8Slogwang 
447*a9643ea8Slogwang     /**
448*a9643ea8Slogwang      * @brief ��־���Ȱ��ȼ�����, ���ٽ��������Ŀ���
449*a9643ea8Slogwang      * @return true ���Դ�ӡ�ü���, false ��������ӡ�ü���
450*a9643ea8Slogwang      */
451*a9643ea8Slogwang     virtual bool CheckDebug(){ return true;};
452*a9643ea8Slogwang     virtual bool CheckTrace(){ return true;};
453*a9643ea8Slogwang     virtual bool CheckError(){ return true;};
454*a9643ea8Slogwang 
455*a9643ea8Slogwang     /**
456*a9643ea8Slogwang      * @brief ��־�ּ���¼�ӿ�
457*a9643ea8Slogwang      */
458*a9643ea8Slogwang     virtual void LogDebug(char* fmt, ...){};
459*a9643ea8Slogwang     virtual void LogTrace(char* fmt, ...){};
460*a9643ea8Slogwang     virtual void LogError(char* fmt, ...){};
461*a9643ea8Slogwang 
462*a9643ea8Slogwang     /**
463*a9643ea8Slogwang      * @brief �����ϱ��ӿ�
464*a9643ea8Slogwang      */
465*a9643ea8Slogwang     virtual void AttrReportAdd(int attr, int iValue){};
466*a9643ea8Slogwang     virtual void AttrReportSet(int attr, int iValue){};
467*a9643ea8Slogwang 
468*a9643ea8Slogwang };
469*a9643ea8Slogwang 
470*a9643ea8Slogwang 
471*a9643ea8Slogwang /**
472*a9643ea8Slogwang  * @brief ΢�̳߳ؼ�ʵ��
473*a9643ea8Slogwang  */
474*a9643ea8Slogwang class ThreadPool
475*a9643ea8Slogwang {
476*a9643ea8Slogwang public:
477*a9643ea8Slogwang 
478*a9643ea8Slogwang     static unsigned int default_thread_num;   ///< Ĭ��2000΢�̴߳���
479*a9643ea8Slogwang     static unsigned int default_stack_size;   ///< Ĭ��128Kջ��С
480*a9643ea8Slogwang 
481*a9643ea8Slogwang     /**
482*a9643ea8Slogwang      * @brief ����΢�̵߳���С������Ŀ
483*a9643ea8Slogwang      */
484*a9643ea8Slogwang     static void SetDefaultThreadNum(unsigned int num) {
485*a9643ea8Slogwang         default_thread_num = num;
486*a9643ea8Slogwang     };
487*a9643ea8Slogwang 
488*a9643ea8Slogwang     /**
489*a9643ea8Slogwang      * @brief ����΢�̵߳�Ĭ��ջ��С, ���ʼ��ǰ����
490*a9643ea8Slogwang      */
491*a9643ea8Slogwang     static void SetDefaultStackSize(unsigned int size) {
492*a9643ea8Slogwang         default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE;
493*a9643ea8Slogwang     };
494*a9643ea8Slogwang 
495*a9643ea8Slogwang     /**
496*a9643ea8Slogwang      * @brief ΢�̳߳س�ʼ��
497*a9643ea8Slogwang      */
498*a9643ea8Slogwang     bool InitialPool(int max_num);
499*a9643ea8Slogwang 
500*a9643ea8Slogwang     /**
501*a9643ea8Slogwang      * @brief ΢�̳߳ط���ʼ��
502*a9643ea8Slogwang      */
503*a9643ea8Slogwang     void DestroyPool (void);
504*a9643ea8Slogwang 
505*a9643ea8Slogwang     /**
506*a9643ea8Slogwang      * @brief ΢�̷߳���ӿ�
507*a9643ea8Slogwang      * @return ΢�̶߳���
508*a9643ea8Slogwang      */
509*a9643ea8Slogwang     MicroThread* AllocThread(void);
510*a9643ea8Slogwang 
511*a9643ea8Slogwang     /**
512*a9643ea8Slogwang      * @brief ΢�߳��ͷŽӿ�
513*a9643ea8Slogwang      * @param thread ΢�̶߳���
514*a9643ea8Slogwang      */
515*a9643ea8Slogwang     void FreeThread(MicroThread* thread);
516*a9643ea8Slogwang 
517*a9643ea8Slogwang 	/**
518*a9643ea8Slogwang      * @brief ��ȡ��ǰ΢�߳�����
519*a9643ea8Slogwang      * @param thread ΢�̶߳���
520*a9643ea8Slogwang      */
521*a9643ea8Slogwang     int GetUsedNum(void);
522*a9643ea8Slogwang 
523*a9643ea8Slogwang private:
524*a9643ea8Slogwang     ThreadList      _freelist;      ///< ���д�����΢�̶߳���
525*a9643ea8Slogwang     int             _total_num;     ///< Ŀǰ�ܵ�΢�߳���Ŀ�����������������
526*a9643ea8Slogwang     int             _use_num;       ///< ��ǰ����ʹ�õ�΢�߳���Ŀ
527*a9643ea8Slogwang     int             _max_num;       ///< �����������, �����ڴ����ʹ��
528*a9643ea8Slogwang };
529*a9643ea8Slogwang 
530*a9643ea8Slogwang typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq;  ///< ΢�̶߳��ж���
531*a9643ea8Slogwang 
532*a9643ea8Slogwang /**
533*a9643ea8Slogwang  * @brief ΢�߳̿����, ȫ�ֵĵ�����
534*a9643ea8Slogwang  */
535*a9643ea8Slogwang class MtFrame : public KqueueProxy, public ThreadPool
536*a9643ea8Slogwang {
537*a9643ea8Slogwang private:
538*a9643ea8Slogwang     static MtFrame* _instance;          ///< ����ָ��
539*a9643ea8Slogwang     LogAdapter*     _log_adpt;          ///< ��־�ӿ�
540*a9643ea8Slogwang 	ThreadList      _runlist;           ///< ������queue, �����ȼ�
541*a9643ea8Slogwang 	ThreadTailq     _iolist;            ///< �ȴ����У�������������
542*a9643ea8Slogwang 	ThreadTailq     _pend_list;         ///< �ȴ����У�������������
543*a9643ea8Slogwang 	HeapList        _sleeplist;         ///< �ȴ���ʱ�Ķ�, ���������, ����ʱ��ȡ��С����
544*a9643ea8Slogwang 	MicroThread*    _daemon;            ///< �ػ��߳�, ִ��epoll wait, ��ʱ���
545*a9643ea8Slogwang 	MicroThread*    _primo;             ///< ԭ���߳�, ʹ�õ���ԭ����ջ
546*a9643ea8Slogwang 	MicroThread*    _curr_thread;       ///< ��ǰ�����߳�
547*a9643ea8Slogwang 	utime64_t       _last_clock;        ///< ȫ��ʱ���, ÿ��idle��ȡһ��
548*a9643ea8Slogwang     int             _waitnum;           ///< �ȴ����е����߳���, �ɵ��ڵ��ȵĽ���
549*a9643ea8Slogwang     CTimerMng*      _timer;             ///< TCP����ר�õ�timer��ʱ��
550*a9643ea8Slogwang     int             _realtime;  /// < ʹ��ʵʱʱ��0, δ����
551*a9643ea8Slogwang 
552*a9643ea8Slogwang public:
553*a9643ea8Slogwang     friend class ScheduleObj;           ///< ����������, �ǿ���������ģʽ, ��Ԫ����
554*a9643ea8Slogwang 
555*a9643ea8Slogwang public:
556*a9643ea8Slogwang 
557*a9643ea8Slogwang     /**
558*a9643ea8Slogwang      * @brief ΢�߳̿����, ȫ��ʵ����ȡ
559*a9643ea8Slogwang      */
560*a9643ea8Slogwang     static MtFrame* Instance (void);
561*a9643ea8Slogwang 
562*a9643ea8Slogwang     /**
563*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� sendto
564*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
565*a9643ea8Slogwang      * @param msg �����͵���Ϣָ��
566*a9643ea8Slogwang      * @param len �����͵���Ϣ����
567*a9643ea8Slogwang      * @param to Ŀ�ĵ�ַ��ָ��
568*a9643ea8Slogwang      * @param tolen Ŀ�ĵ�ַ�Ľṹ����
569*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
570*a9643ea8Slogwang      * @return >0 �ɹ����ͳ���, <0 ʧ��
571*a9643ea8Slogwang      */
572*a9643ea8Slogwang     static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
573*a9643ea8Slogwang 
574*a9643ea8Slogwang     /**
575*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� recvfrom
576*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
577*a9643ea8Slogwang      * @param buf ������Ϣ������ָ��
578*a9643ea8Slogwang      * @param len ������Ϣ����������
579*a9643ea8Slogwang      * @param from ��Դ��ַ��ָ��
580*a9643ea8Slogwang      * @param fromlen ��Դ��ַ�Ľṹ����
581*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
582*a9643ea8Slogwang      * @return >0 �ɹ����ճ���, <0 ʧ��
583*a9643ea8Slogwang      */
584*a9643ea8Slogwang     static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
585*a9643ea8Slogwang 
586*a9643ea8Slogwang     /**
587*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� connect
588*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
589*a9643ea8Slogwang      * @param addr ָ��server��Ŀ�ĵ�ַ
590*a9643ea8Slogwang      * @param addrlen ��ַ�ij���
591*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
592*a9643ea8Slogwang      * @return >0 �ɹ����ͳ���, <0 ʧ��
593*a9643ea8Slogwang      */
594*a9643ea8Slogwang     static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
595*a9643ea8Slogwang 
596*a9643ea8Slogwang     /**
597*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� accept
598*a9643ea8Slogwang      * @param fd �����׽���
599*a9643ea8Slogwang      * @param addr �ͻ��˵�ַ
600*a9643ea8Slogwang      * @param addrlen ��ַ�ij���
601*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
602*a9643ea8Slogwang      * @return >=0 accept��socket������, <0 ʧ��
603*a9643ea8Slogwang      */
604*a9643ea8Slogwang     static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
605*a9643ea8Slogwang 
606*a9643ea8Slogwang     /**
607*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� read
608*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
609*a9643ea8Slogwang      * @param buf ������Ϣ������ָ��
610*a9643ea8Slogwang      * @param nbyte ������Ϣ����������
611*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
612*a9643ea8Slogwang      * @return >0 �ɹ����ճ���, <0 ʧ��
613*a9643ea8Slogwang      */
614*a9643ea8Slogwang     static ssize_t read(int fd, void *buf, size_t nbyte, int timeout);
615*a9643ea8Slogwang 
616*a9643ea8Slogwang     /**
617*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� write
618*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
619*a9643ea8Slogwang      * @param buf ������Ϣ������ָ��
620*a9643ea8Slogwang      * @param nbyte ������Ϣ����������
621*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
622*a9643ea8Slogwang      * @return >0 �ɹ����ͳ���, <0 ʧ��
623*a9643ea8Slogwang      */
624*a9643ea8Slogwang     static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout);
625*a9643ea8Slogwang 
626*a9643ea8Slogwang     /**
627*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� recv
628*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
629*a9643ea8Slogwang      * @param buf ������Ϣ������ָ��
630*a9643ea8Slogwang      * @param len ������Ϣ����������
631*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
632*a9643ea8Slogwang      * @return >0 �ɹ����ճ���, <0 ʧ��
633*a9643ea8Slogwang      */
634*a9643ea8Slogwang     static int recv(int fd, void *buf, int len, int flags, int timeout);
635*a9643ea8Slogwang 
636*a9643ea8Slogwang     /**
637*a9643ea8Slogwang      * @brief ΢�̰߳�����ϵͳIO���� send
638*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
639*a9643ea8Slogwang      * @param buf �����͵���Ϣָ��
640*a9643ea8Slogwang      * @param nbyte �����͵���Ϣ����
641*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
642*a9643ea8Slogwang      * @return >0 �ɹ����ͳ���, <0 ʧ��
643*a9643ea8Slogwang      */
644*a9643ea8Slogwang     static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
645*a9643ea8Slogwang 
646*a9643ea8Slogwang 
647*a9643ea8Slogwang     /**
648*a9643ea8Slogwang      * @brief ΢�߳�����sleep�ӿ�, ��λms
649*a9643ea8Slogwang      */
650*a9643ea8Slogwang     static void sleep(int ms);
651*a9643ea8Slogwang 
652*a9643ea8Slogwang     /**
653*a9643ea8Slogwang      * @brief ΢�߳̽��ȴ��¼�,��������IJ���
654*a9643ea8Slogwang      * @param fd ϵͳsocket��Ϣ
655*a9643ea8Slogwang      * @param events �¼�����  EPOLLIN or EPOLLOUT
656*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
657*a9643ea8Slogwang      * @return >0 �ɹ����ճ���, <0 ʧ��
658*a9643ea8Slogwang      */
659*a9643ea8Slogwang     static int WaitEvents(int fd, int events, int timeout);
660*a9643ea8Slogwang 
661*a9643ea8Slogwang     /**
662*a9643ea8Slogwang      * @brief ΢�̴߳����ӿ�
663*a9643ea8Slogwang      * @param entry �߳���ں���
664*a9643ea8Slogwang      * @param args  �߳���ڲ���
665*a9643ea8Slogwang      * @return ΢�߳�ָ��, NULL��ʾʧ��
666*a9643ea8Slogwang      */
667*a9643ea8Slogwang     static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true);
668*a9643ea8Slogwang 
669*a9643ea8Slogwang     /**
670*a9643ea8Slogwang      * @brief �ػ��߳���ں���, ����ָ��Ҫ��static����
671*a9643ea8Slogwang      * @param args  �߳���ڲ���
672*a9643ea8Slogwang      */
673*a9643ea8Slogwang     static void DaemonRun(void* args);
674*a9643ea8Slogwang 	static int Loop(void* args);
675*a9643ea8Slogwang 
676*a9643ea8Slogwang     /**
677*a9643ea8Slogwang      * @brief ��ȡ��ǰ�̵߳ĸ��߳�
678*a9643ea8Slogwang      */
679*a9643ea8Slogwang     MicroThread *GetRootThread();
680*a9643ea8Slogwang 
681*a9643ea8Slogwang     /**
682*a9643ea8Slogwang      * @brief ��ܳ�ʼ��, Ĭ�ϲ�����־����
683*a9643ea8Slogwang      */
684*a9643ea8Slogwang     bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = 50000);
685*a9643ea8Slogwang 
686*a9643ea8Slogwang     /**
687*a9643ea8Slogwang      * @brief HOOKϵͳapi������
688*a9643ea8Slogwang      */
689*a9643ea8Slogwang     void SetHookFlag();
690*a9643ea8Slogwang 
691*a9643ea8Slogwang     /**
692*a9643ea8Slogwang      * @brief ��ܷ���ʼ��
693*a9643ea8Slogwang      */
694*a9643ea8Slogwang     void Destroy (void);
695*a9643ea8Slogwang 
696*a9643ea8Slogwang     /**
697*a9643ea8Slogwang      * @brief ΢�߳̿�ܰ汾��ȡ
698*a9643ea8Slogwang      */
699*a9643ea8Slogwang     char* Version(void);
700*a9643ea8Slogwang 
701*a9643ea8Slogwang     /**
702*a9643ea8Slogwang      * @brief ��ܻ�ȡȫ��ʱ���
703*a9643ea8Slogwang      */
704*a9643ea8Slogwang     utime64_t GetLastClock(void) {
705*a9643ea8Slogwang     	if(_realtime)
706*a9643ea8Slogwang     	{
707*a9643ea8Slogwang         	return GetSystemMS();
708*a9643ea8Slogwang         }
709*a9643ea8Slogwang         return _last_clock;
710*a9643ea8Slogwang     };
711*a9643ea8Slogwang 
712*a9643ea8Slogwang 
713*a9643ea8Slogwang     /**
714*a9643ea8Slogwang      * @brief ��ܻ�ȡ��ǰ�߳�
715*a9643ea8Slogwang      */
716*a9643ea8Slogwang     MicroThread* GetActiveThread(void) {
717*a9643ea8Slogwang         return _curr_thread;
718*a9643ea8Slogwang     };
719*a9643ea8Slogwang 
720*a9643ea8Slogwang     /**
721*a9643ea8Slogwang      * @brief ���ص�ǰ�����е��߳���, ֱ�Ӽ���, Ч�ʸ�
722*a9643ea8Slogwang      * @return �ȴ��߳���
723*a9643ea8Slogwang      */
724*a9643ea8Slogwang     int RunWaitNum(void) {
725*a9643ea8Slogwang         return _waitnum;
726*a9643ea8Slogwang     };
727*a9643ea8Slogwang 
728*a9643ea8Slogwang     /**
729*a9643ea8Slogwang      * @brief ��ܱ�ע�����־�������
730*a9643ea8Slogwang      */
731*a9643ea8Slogwang     LogAdapter* GetLogAdpt(void) {
732*a9643ea8Slogwang         return _log_adpt;
733*a9643ea8Slogwang     };
734*a9643ea8Slogwang 
735*a9643ea8Slogwang     /**
736*a9643ea8Slogwang      * @brief ��ȡ��ܱ��ʱ��ָ��
737*a9643ea8Slogwang      */
738*a9643ea8Slogwang     CTimerMng* GetTimerMng(void) {
739*a9643ea8Slogwang         return _timer;
740*a9643ea8Slogwang     };
741*a9643ea8Slogwang 
742*a9643ea8Slogwang     /**
743*a9643ea8Slogwang      * @brief ��ܵ���epoll waitǰ, �ж��ȴ�ʱ����Ϣ
744*a9643ea8Slogwang      */
745*a9643ea8Slogwang     virtual int KqueueGetTimeout(void);
746*a9643ea8Slogwang 
747*a9643ea8Slogwang     /**
748*a9643ea8Slogwang      * @brief ΢�̴߳����л�����,���óɹ� ���ó�cpu, �ڲ��ӿ�
749*a9643ea8Slogwang      * @param fdlist ��·������socket�б�
750*a9643ea8Slogwang      * @param fd ���������fd��Ϣ
751*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
752*a9643ea8Slogwang      * @return true �ɹ�, false ʧ��
753*a9643ea8Slogwang      */
754*a9643ea8Slogwang     virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout);
755*a9643ea8Slogwang 
756*a9643ea8Slogwang 
757*a9643ea8Slogwang     /**
758*a9643ea8Slogwang      * @brief ΢�߳������л�, �ȴ������̵߳Ļ���
759*a9643ea8Slogwang      * @param timeout ��ȴ�ʱ��, ����
760*a9643ea8Slogwang      */
761*a9643ea8Slogwang     void WaitNotify(utime64_t timeout);
762*a9643ea8Slogwang 
763*a9643ea8Slogwang     /**
764*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, �Ƴ�IO�ȴ�״̬, �ڲ��ӿ�
765*a9643ea8Slogwang      * @param thread ΢�̶߳���
766*a9643ea8Slogwang      */
767*a9643ea8Slogwang     void RemoveIoWait(MicroThread* thread);
768*a9643ea8Slogwang 
769*a9643ea8Slogwang     /**
770*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, ��������ж���, �ڲ��ӿ�
771*a9643ea8Slogwang      * @param thread ΢�̶߳���
772*a9643ea8Slogwang      */
773*a9643ea8Slogwang     void InsertRunable(MicroThread* thread);
774*a9643ea8Slogwang 
775*a9643ea8Slogwang     /**
776*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, ִ��pend�ȴ�״̬
777*a9643ea8Slogwang      * @param thread ΢�̶߳���
778*a9643ea8Slogwang      */
779*a9643ea8Slogwang     void InsertPend(MicroThread* thread);
780*a9643ea8Slogwang 
781*a9643ea8Slogwang     /**
782*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, �Ƴ�PEND�ȴ�״̬
783*a9643ea8Slogwang      * @param thread ΢�̶߳���
784*a9643ea8Slogwang      */
785*a9643ea8Slogwang     void RemovePend(MicroThread* thread);
786*a9643ea8Slogwang 
787*a9643ea8Slogwang 	void SetRealTime(int realtime_)
788*a9643ea8Slogwang 	{
789*a9643ea8Slogwang 		_realtime =realtime_;
790*a9643ea8Slogwang 	}
791*a9643ea8Slogwang private:
792*a9643ea8Slogwang 
793*a9643ea8Slogwang     /**
794*a9643ea8Slogwang      * @brief ΢�߳�˽�й���
795*a9643ea8Slogwang      */
796*a9643ea8Slogwang     MtFrame():_realtime(1){ _curr_thread = NULL; };
797*a9643ea8Slogwang 
798*a9643ea8Slogwang     /**
799*a9643ea8Slogwang      * @brief ΢�߳�˽�л�ȡ�ػ��߳�
800*a9643ea8Slogwang      */
801*a9643ea8Slogwang     MicroThread* DaemonThread(void){
802*a9643ea8Slogwang         return _daemon;
803*a9643ea8Slogwang     };
804*a9643ea8Slogwang 
805*a9643ea8Slogwang     /**
806*a9643ea8Slogwang      * @brief ��ܵ����߳�����
807*a9643ea8Slogwang      */
808*a9643ea8Slogwang     void ThreadSchdule(void);
809*a9643ea8Slogwang 
810*a9643ea8Slogwang     /**
811*a9643ea8Slogwang      * @brief ��ܴ���ʱ�ص�����
812*a9643ea8Slogwang      */
813*a9643ea8Slogwang     void CheckExpired();
814*a9643ea8Slogwang 
815*a9643ea8Slogwang     /**
816*a9643ea8Slogwang      * @brief ��ܼ�⵽��ʱ, �������еij�ʱ�߳�
817*a9643ea8Slogwang      */
818*a9643ea8Slogwang     void WakeupTimeout(void);
819*a9643ea8Slogwang 
820*a9643ea8Slogwang     /**
821*a9643ea8Slogwang      * @brief ��ܸ���ȫ��ʱ���
822*a9643ea8Slogwang      */
823*a9643ea8Slogwang     void SetLastClock(utime64_t clock) {
824*a9643ea8Slogwang         _last_clock = clock;
825*a9643ea8Slogwang     };
826*a9643ea8Slogwang 
827*a9643ea8Slogwang     /**
828*a9643ea8Slogwang      * @brief ������õ�ǰ�߳�
829*a9643ea8Slogwang      */
830*a9643ea8Slogwang     void SetActiveThread(MicroThread* thread) {
831*a9643ea8Slogwang         _curr_thread = thread;
832*a9643ea8Slogwang     };
833*a9643ea8Slogwang 
834*a9643ea8Slogwang     /**
835*a9643ea8Slogwang      * @brief ��ܵ�ʱ��Դ�ӿ�, ���غ��뼶��ʱ��
836*a9643ea8Slogwang      */
837*a9643ea8Slogwang     utime64_t GetSystemMS(void) {
838*a9643ea8Slogwang         struct timeval tv;
839*a9643ea8Slogwang         gettimeofday(&tv, NULL);
840*a9643ea8Slogwang         return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL);
841*a9643ea8Slogwang     };
842*a9643ea8Slogwang 
843*a9643ea8Slogwang     /**
844*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, ִ��IO�ȴ�״̬
845*a9643ea8Slogwang      * @param thread ΢�̶߳���
846*a9643ea8Slogwang      */
847*a9643ea8Slogwang     void InsertSleep(MicroThread* thread);
848*a9643ea8Slogwang 
849*a9643ea8Slogwang     /**
850*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, �Ƴ�IO�ȴ�״̬
851*a9643ea8Slogwang      * @param thread ΢�̶߳���
852*a9643ea8Slogwang      */
853*a9643ea8Slogwang     void RemoveSleep(MicroThread* thread);
854*a9643ea8Slogwang 
855*a9643ea8Slogwang     /**
856*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, ִ��IO�ȴ�״̬
857*a9643ea8Slogwang      * @param thread ΢�̶߳���
858*a9643ea8Slogwang      */
859*a9643ea8Slogwang     void InsertIoWait(MicroThread* thread);
860*a9643ea8Slogwang 
861*a9643ea8Slogwang     /**
862*a9643ea8Slogwang      * @brief ��ܹ����̵߳�Ԫ, �Ƴ������ж���
863*a9643ea8Slogwang      * @param thread ΢�̶߳���
864*a9643ea8Slogwang      */
865*a9643ea8Slogwang     void RemoveRunable(MicroThread* thread);
866*a9643ea8Slogwang 
867*a9643ea8Slogwang };
868*a9643ea8Slogwang 
869*a9643ea8Slogwang /**
870*a9643ea8Slogwang  * @brief ��־��Ķ��岿��
871*a9643ea8Slogwang  */
872*a9643ea8Slogwang #define MTLOG_DEBUG(fmt, args...)                                              \
873*a9643ea8Slogwang do {                                                                           \
874*a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
875*a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckDebug())           \
876*a9643ea8Slogwang        {                                                                       \
877*a9643ea8Slogwang           fm->GetLogAdpt()->LogDebug((char*)"[%-10s][%-4d][%-10s]"fmt,         \
878*a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
879*a9643ea8Slogwang        }                                                                       \
880*a9643ea8Slogwang } while (0)
881*a9643ea8Slogwang 
882*a9643ea8Slogwang #define MTLOG_TRACE(fmt, args...)                                              \
883*a9643ea8Slogwang do {                                                                           \
884*a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
885*a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckTrace())           \
886*a9643ea8Slogwang        {                                                                       \
887*a9643ea8Slogwang           fm->GetLogAdpt()->LogTrace((char*)"[%-10s][%-4d][%-10s]"fmt,         \
888*a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
889*a9643ea8Slogwang        }                                                                       \
890*a9643ea8Slogwang } while (0)
891*a9643ea8Slogwang 
892*a9643ea8Slogwang #define MTLOG_ERROR(fmt, args...)                                              \
893*a9643ea8Slogwang do {                                                                           \
894*a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
895*a9643ea8Slogwang        if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckError())           \
896*a9643ea8Slogwang        {                                                                       \
897*a9643ea8Slogwang           fm->GetLogAdpt()->LogError((char*)"[%-10s][%-4d][%-10s]"fmt,         \
898*a9643ea8Slogwang                 __FILE__, __LINE__, __FUNCTION__, ##args);                     \
899*a9643ea8Slogwang        }                                                                       \
900*a9643ea8Slogwang } while (0)
901*a9643ea8Slogwang 
902*a9643ea8Slogwang #define MT_ATTR_API(ATTR, VALUE)                                               \
903*a9643ea8Slogwang do {                                                                           \
904*a9643ea8Slogwang        register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
905*a9643ea8Slogwang        if (fm && fm->GetLogAdpt())                                             \
906*a9643ea8Slogwang        {                                                                       \
907*a9643ea8Slogwang           fm->GetLogAdpt()->AttrReportAdd(ATTR, VALUE);                        \
908*a9643ea8Slogwang        }                                                                       \
909*a9643ea8Slogwang } while (0)
910*a9643ea8Slogwang 
911*a9643ea8Slogwang #define MT_ATTR_API_SET(ATTR, VALUE)                                               \
912*a9643ea8Slogwang 	   do { 																		  \
913*a9643ea8Slogwang 			  register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
914*a9643ea8Slogwang 			  if (fm && fm->GetLogAdpt())											  \
915*a9643ea8Slogwang 			  { 																	  \
916*a9643ea8Slogwang 				 fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE);						  \
917*a9643ea8Slogwang 			  } 																	  \
918*a9643ea8Slogwang 	   } while (0)
919*a9643ea8Slogwang 
920*a9643ea8Slogwang 
921*a9643ea8Slogwang 
922*a9643ea8Slogwang }// NAMESPACE NS_MICRO_THREAD
923*a9643ea8Slogwang 
924*a9643ea8Slogwang #endif
925*a9643ea8Slogwang 
926