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