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