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