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