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> 43a9643ea8Slogwang 44a9643ea8Slogwang #include <set> 45a9643ea8Slogwang #include <vector> 46a9643ea8Slogwang #include <queue> 47a9643ea8Slogwang #include "heap.h" 48a9643ea8Slogwang #include "kqueue_proxy.h" 49a9643ea8Slogwang #include "heap_timer.h" 50a9643ea8Slogwang 51a9643ea8Slogwang using std::vector; 52a9643ea8Slogwang using std::set; 53a9643ea8Slogwang using std::queue; 54a9643ea8Slogwang 55a9643ea8Slogwang namespace NS_MICRO_THREAD { 56a9643ea8Slogwang 57*5ac59bc4Slogwang #define STACK_PAD_SIZE 128 58*5ac59bc4Slogwang #define MEM_PAGE_SIZE 4096 59*5ac59bc4Slogwang #define DEFAULT_STACK_SIZE 128*1024 60*5ac59bc4Slogwang #define DEFAULT_THREAD_NUM 2000 61a9643ea8Slogwang 62*5ac59bc4Slogwang typedef unsigned long long utime64_t; 63*5ac59bc4Slogwang typedef void (*ThreadStart)(void*); 64a9643ea8Slogwang 65a9643ea8Slogwang class ScheduleObj 66a9643ea8Slogwang { 67a9643ea8Slogwang public: 68a9643ea8Slogwang 69a9643ea8Slogwang static ScheduleObj* Instance (void); 70a9643ea8Slogwang 71a9643ea8Slogwang utime64_t ScheduleGetTime(void); 72a9643ea8Slogwang 73a9643ea8Slogwang void ScheduleThread(void); 74a9643ea8Slogwang 75a9643ea8Slogwang void ScheduleSleep(void); 76a9643ea8Slogwang 77a9643ea8Slogwang void SchedulePend(void); 78a9643ea8Slogwang 79a9643ea8Slogwang void ScheduleUnpend(void* thread); 80a9643ea8Slogwang 81a9643ea8Slogwang void ScheduleReclaim(void); 82a9643ea8Slogwang 83a9643ea8Slogwang void ScheduleStartRun(void); 84a9643ea8Slogwang 85a9643ea8Slogwang private: 86*5ac59bc4Slogwang static ScheduleObj* _instance; 87a9643ea8Slogwang }; 88a9643ea8Slogwang 89a9643ea8Slogwang struct MtStack 90a9643ea8Slogwang { 91*5ac59bc4Slogwang int _stk_size; 92*5ac59bc4Slogwang int _vaddr_size; 93*5ac59bc4Slogwang char *_vaddr; 94*5ac59bc4Slogwang void *_esp; 95*5ac59bc4Slogwang char *_stk_bottom; 96*5ac59bc4Slogwang char *_stk_top; 97*5ac59bc4Slogwang void *_private; 98*5ac59bc4Slogwang int valgrind_id; 99a9643ea8Slogwang }; 100a9643ea8Slogwang 101a9643ea8Slogwang class Thread : public HeapEntry 102a9643ea8Slogwang { 103a9643ea8Slogwang public: 104a9643ea8Slogwang 105a9643ea8Slogwang explicit Thread(int stack_size = 0); 106a9643ea8Slogwang virtual ~Thread(){}; 107a9643ea8Slogwang 108a9643ea8Slogwang virtual void Run(void){}; 109a9643ea8Slogwang 110a9643ea8Slogwang bool Initial(void); 111a9643ea8Slogwang 112a9643ea8Slogwang void Destroy(void); 113a9643ea8Slogwang 114a9643ea8Slogwang void Reset(void); 115a9643ea8Slogwang 116a9643ea8Slogwang void sleep(int ms); 117a9643ea8Slogwang 118a9643ea8Slogwang void Wait(); 119a9643ea8Slogwang 120a9643ea8Slogwang void SwitchContext(void); 121a9643ea8Slogwang 122a9643ea8Slogwang void RestoreContext(void); 123a9643ea8Slogwang 124a9643ea8Slogwang utime64_t GetWakeupTime(void) { 125a9643ea8Slogwang return _wakeup_time; 126a9643ea8Slogwang }; 127a9643ea8Slogwang 128a9643ea8Slogwang void SetWakeupTime(utime64_t waketime) { 129a9643ea8Slogwang _wakeup_time = waketime; 130a9643ea8Slogwang }; 131a9643ea8Slogwang 132a9643ea8Slogwang void SetPrivate(void *data) 133a9643ea8Slogwang { 134a9643ea8Slogwang _stack->_private = data; 135a9643ea8Slogwang } 136a9643ea8Slogwang 137a9643ea8Slogwang void* GetPrivate() 138a9643ea8Slogwang { 139a9643ea8Slogwang return _stack->_private; 140a9643ea8Slogwang } 141a9643ea8Slogwang 142a9643ea8Slogwang bool CheckStackHealth(char *esp); 143a9643ea8Slogwang 144a9643ea8Slogwang protected: 145a9643ea8Slogwang 146a9643ea8Slogwang virtual void CleanState(void){}; 147a9643ea8Slogwang 148a9643ea8Slogwang virtual bool InitStack(void); 149a9643ea8Slogwang 150a9643ea8Slogwang virtual void FreeStack(void); 151a9643ea8Slogwang 152a9643ea8Slogwang virtual void InitContext(void); 153a9643ea8Slogwang 154a9643ea8Slogwang private: 155*5ac59bc4Slogwang MtStack* _stack; 156*5ac59bc4Slogwang jmp_buf _jmpbuf; 157*5ac59bc4Slogwang int _stack_size; 158*5ac59bc4Slogwang utime64_t _wakeup_time; 159a9643ea8Slogwang }; 160a9643ea8Slogwang 161a9643ea8Slogwang class MicroThread : public Thread 162a9643ea8Slogwang { 163a9643ea8Slogwang public: 164a9643ea8Slogwang enum ThreadType 165a9643ea8Slogwang { 166*5ac59bc4Slogwang NORMAL = 0, ///< normal thread, no dynamic allocated stack infomations. 167*5ac59bc4Slogwang PRIMORDIAL = 1, ///< primordial thread, created when frame initialized. 168*5ac59bc4Slogwang DAEMON = 2, ///< daemon thread, IO event management and scheduling trigger. 169*5ac59bc4Slogwang SUB_THREAD = 3, ///< sub thread, run simple task. 170a9643ea8Slogwang }; 171a9643ea8Slogwang 172a9643ea8Slogwang enum ThreadFlag 173a9643ea8Slogwang { 174*5ac59bc4Slogwang NOT_INLIST = 0x0, 175*5ac59bc4Slogwang FREE_LIST = 0x1, 176*5ac59bc4Slogwang IO_LIST = 0x2, 177*5ac59bc4Slogwang SLEEP_LIST = 0x4, 178*5ac59bc4Slogwang RUN_LIST = 0x8, 179*5ac59bc4Slogwang PEND_LIST = 0x10, 180*5ac59bc4Slogwang SUB_LIST = 0x20, 181a9643ea8Slogwang 182a9643ea8Slogwang }; 183a9643ea8Slogwang 184a9643ea8Slogwang enum ThreadState 185a9643ea8Slogwang { 186*5ac59bc4Slogwang INITIAL = 0, 187*5ac59bc4Slogwang RUNABLE = 1, 188*5ac59bc4Slogwang RUNNING = 2, 189*5ac59bc4Slogwang SLEEPING = 3, 190*5ac59bc4Slogwang PENDING = 4, 191a9643ea8Slogwang }; 192a9643ea8Slogwang 193*5ac59bc4Slogwang typedef TAILQ_ENTRY(MicroThread) ThreadLink; 194*5ac59bc4Slogwang typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList; 195a9643ea8Slogwang 196a9643ea8Slogwang public: 197a9643ea8Slogwang 198a9643ea8Slogwang MicroThread(ThreadType type = NORMAL); 199a9643ea8Slogwang ~MicroThread(){}; 200a9643ea8Slogwang 201*5ac59bc4Slogwang ThreadLink _entry; 202*5ac59bc4Slogwang ThreadLink _sub_entry; 203a9643ea8Slogwang 204a9643ea8Slogwang virtual utime64_t HeapValue() { 205a9643ea8Slogwang return GetWakeupTime(); 206a9643ea8Slogwang }; 207a9643ea8Slogwang 208a9643ea8Slogwang virtual void Run(void); 209a9643ea8Slogwang 210a9643ea8Slogwang void ClearAllFd(void) { 211a9643ea8Slogwang TAILQ_INIT(&_fdset); 212a9643ea8Slogwang }; 213a9643ea8Slogwang void AddFd(KqueuerObj* efpd) { 214a9643ea8Slogwang TAILQ_INSERT_TAIL(&_fdset, efpd, _entry); 215a9643ea8Slogwang }; 216a9643ea8Slogwang void AddFdList(KqObjList* fdset) { 217a9643ea8Slogwang TAILQ_CONCAT(&_fdset, fdset, _entry); 218a9643ea8Slogwang }; 219a9643ea8Slogwang KqObjList& GetFdSet(void) { 220a9643ea8Slogwang return _fdset; 221a9643ea8Slogwang }; 222a9643ea8Slogwang 223a9643ea8Slogwang void SetType(ThreadType type) { 224a9643ea8Slogwang _type = type; 225a9643ea8Slogwang }; 226a9643ea8Slogwang ThreadType GetType(void) { 227a9643ea8Slogwang return _type; 228a9643ea8Slogwang }; 229a9643ea8Slogwang 230a9643ea8Slogwang bool IsDaemon(void) { 231a9643ea8Slogwang return (DAEMON == _type); 232a9643ea8Slogwang }; 233a9643ea8Slogwang bool IsPrimo(void) { 234a9643ea8Slogwang return (PRIMORDIAL == _type); 235a9643ea8Slogwang }; 236a9643ea8Slogwang bool IsSubThread(void) { 237a9643ea8Slogwang return (SUB_THREAD == _type); 238a9643ea8Slogwang }; 239a9643ea8Slogwang 240a9643ea8Slogwang void SetParent(MicroThread* parent) { 241a9643ea8Slogwang _parent = parent; 242a9643ea8Slogwang }; 243a9643ea8Slogwang MicroThread* GetParent() { 244a9643ea8Slogwang return _parent; 245a9643ea8Slogwang }; 246a9643ea8Slogwang void WakeupParent(); 247a9643ea8Slogwang 248a9643ea8Slogwang void AddSubThread(MicroThread* sub); 249a9643ea8Slogwang void RemoveSubThread(MicroThread* sub); 250a9643ea8Slogwang bool HasNoSubThread(); 251a9643ea8Slogwang 252a9643ea8Slogwang void SetState(ThreadState state) { 253a9643ea8Slogwang _state = state; 254a9643ea8Slogwang }; 255a9643ea8Slogwang ThreadState GetState(void) { 256a9643ea8Slogwang return _state; 257a9643ea8Slogwang } 258a9643ea8Slogwang 259a9643ea8Slogwang void SetFlag(ThreadFlag flag) { 260a9643ea8Slogwang _flag = (ThreadFlag)(_flag | flag); 261a9643ea8Slogwang }; 262a9643ea8Slogwang void UnsetFlag(ThreadFlag flag) { 263a9643ea8Slogwang _flag = (ThreadFlag)(_flag & ~flag); 264a9643ea8Slogwang }; 265a9643ea8Slogwang bool HasFlag(ThreadFlag flag) { 266a9643ea8Slogwang return _flag & flag; 267a9643ea8Slogwang }; 268a9643ea8Slogwang ThreadFlag GetFlag() { 269a9643ea8Slogwang return _flag; 270a9643ea8Slogwang }; 271a9643ea8Slogwang 272a9643ea8Slogwang void SetSartFunc(ThreadStart func, void* args) { 273a9643ea8Slogwang _start = func; 274a9643ea8Slogwang _args = args; 275a9643ea8Slogwang }; 276a9643ea8Slogwang 277a9643ea8Slogwang void* GetThreadArgs() { 278a9643ea8Slogwang return _args; 279a9643ea8Slogwang } 280a9643ea8Slogwang 281a9643ea8Slogwang protected: 282a9643ea8Slogwang 283a9643ea8Slogwang virtual void CleanState(void); 284a9643ea8Slogwang 285a9643ea8Slogwang private: 286*5ac59bc4Slogwang ThreadState _state; 287*5ac59bc4Slogwang ThreadType _type; 288*5ac59bc4Slogwang ThreadFlag _flag; 289*5ac59bc4Slogwang KqObjList _fdset; 290*5ac59bc4Slogwang SubThreadList _sub_list; 291*5ac59bc4Slogwang MicroThread* _parent; 292*5ac59bc4Slogwang ThreadStart _start; 293*5ac59bc4Slogwang void* _args; 294a9643ea8Slogwang 295a9643ea8Slogwang }; 296*5ac59bc4Slogwang typedef std::set<MicroThread*> ThreadSet; 297*5ac59bc4Slogwang typedef std::queue<MicroThread*> ThreadList; 298a9643ea8Slogwang 299a9643ea8Slogwang 300a9643ea8Slogwang class LogAdapter 301a9643ea8Slogwang { 302a9643ea8Slogwang public: 303a9643ea8Slogwang 304a9643ea8Slogwang LogAdapter(){}; 305a9643ea8Slogwang virtual ~LogAdapter(){}; 306a9643ea8Slogwang 307a9643ea8Slogwang virtual bool CheckDebug(){ return true;}; 308a9643ea8Slogwang virtual bool CheckTrace(){ return true;}; 309a9643ea8Slogwang virtual bool CheckError(){ return true;}; 310a9643ea8Slogwang 311a9643ea8Slogwang virtual void LogDebug(char* fmt, ...){}; 312a9643ea8Slogwang virtual void LogTrace(char* fmt, ...){}; 313a9643ea8Slogwang virtual void LogError(char* fmt, ...){}; 314a9643ea8Slogwang 315a9643ea8Slogwang virtual void AttrReportAdd(int attr, int iValue){}; 316a9643ea8Slogwang virtual void AttrReportSet(int attr, int iValue){}; 317a9643ea8Slogwang 318a9643ea8Slogwang }; 319a9643ea8Slogwang 320a9643ea8Slogwang 321a9643ea8Slogwang class ThreadPool 322a9643ea8Slogwang { 323a9643ea8Slogwang public: 324a9643ea8Slogwang 325*5ac59bc4Slogwang static unsigned int default_thread_num; 326*5ac59bc4Slogwang static unsigned int default_stack_size; 327a9643ea8Slogwang 328a9643ea8Slogwang static void SetDefaultThreadNum(unsigned int num) { 329a9643ea8Slogwang default_thread_num = num; 330a9643ea8Slogwang }; 331a9643ea8Slogwang 332a9643ea8Slogwang static void SetDefaultStackSize(unsigned int size) { 333a9643ea8Slogwang default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE; 334a9643ea8Slogwang }; 335a9643ea8Slogwang 336a9643ea8Slogwang bool InitialPool(int max_num); 337a9643ea8Slogwang 338a9643ea8Slogwang void DestroyPool (void); 339a9643ea8Slogwang 340a9643ea8Slogwang MicroThread* AllocThread(void); 341a9643ea8Slogwang 342a9643ea8Slogwang void FreeThread(MicroThread* thread); 343a9643ea8Slogwang 344a9643ea8Slogwang int GetUsedNum(void); 345a9643ea8Slogwang 346a9643ea8Slogwang private: 347*5ac59bc4Slogwang ThreadList _freelist; 348*5ac59bc4Slogwang int _total_num; 349*5ac59bc4Slogwang int _use_num; 350*5ac59bc4Slogwang int _max_num; 351a9643ea8Slogwang }; 352a9643ea8Slogwang 353*5ac59bc4Slogwang typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq; 354a9643ea8Slogwang 355a9643ea8Slogwang class MtFrame : public KqueueProxy, public ThreadPool 356a9643ea8Slogwang { 357a9643ea8Slogwang private: 358*5ac59bc4Slogwang static MtFrame* _instance; 359*5ac59bc4Slogwang LogAdapter* _log_adpt; 360*5ac59bc4Slogwang ThreadList _runlist; 361*5ac59bc4Slogwang ThreadTailq _iolist; 362*5ac59bc4Slogwang ThreadTailq _pend_list; 363*5ac59bc4Slogwang HeapList _sleeplist; 364*5ac59bc4Slogwang MicroThread* _daemon; 365*5ac59bc4Slogwang MicroThread* _primo; 366*5ac59bc4Slogwang MicroThread* _curr_thread; 367*5ac59bc4Slogwang utime64_t _last_clock; 368*5ac59bc4Slogwang int _waitnum; 369*5ac59bc4Slogwang CTimerMng* _timer; 370*5ac59bc4Slogwang int _realtime; 371a9643ea8Slogwang 372a9643ea8Slogwang public: 373*5ac59bc4Slogwang friend class ScheduleObj; 374a9643ea8Slogwang 375a9643ea8Slogwang public: 376a9643ea8Slogwang 377a9643ea8Slogwang static MtFrame* Instance (void); 378a9643ea8Slogwang 379a9643ea8Slogwang static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout); 380a9643ea8Slogwang 381a9643ea8Slogwang static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout); 382a9643ea8Slogwang 383a9643ea8Slogwang static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout); 384a9643ea8Slogwang 385a9643ea8Slogwang static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout); 386a9643ea8Slogwang 387a9643ea8Slogwang static ssize_t read(int fd, void *buf, size_t nbyte, int timeout); 388a9643ea8Slogwang 389a9643ea8Slogwang static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout); 390a9643ea8Slogwang 391a9643ea8Slogwang static int recv(int fd, void *buf, int len, int flags, int timeout); 392a9643ea8Slogwang 393a9643ea8Slogwang static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout); 394a9643ea8Slogwang 395a9643ea8Slogwang static void sleep(int ms); 396a9643ea8Slogwang 397a9643ea8Slogwang static int WaitEvents(int fd, int events, int timeout); 398a9643ea8Slogwang 399a9643ea8Slogwang static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true); 400a9643ea8Slogwang 401a9643ea8Slogwang static void DaemonRun(void* args); 402a9643ea8Slogwang static int Loop(void* args); 403a9643ea8Slogwang 404a9643ea8Slogwang MicroThread *GetRootThread(); 405a9643ea8Slogwang 406a9643ea8Slogwang bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = 50000); 407a9643ea8Slogwang 408a9643ea8Slogwang void SetHookFlag(); 409a9643ea8Slogwang 410a9643ea8Slogwang void Destroy (void); 411a9643ea8Slogwang 412a9643ea8Slogwang char* Version(void); 413a9643ea8Slogwang 414a9643ea8Slogwang utime64_t GetLastClock(void) { 415a9643ea8Slogwang if(_realtime) 416a9643ea8Slogwang { 417a9643ea8Slogwang return GetSystemMS(); 418a9643ea8Slogwang } 419a9643ea8Slogwang return _last_clock; 420a9643ea8Slogwang }; 421a9643ea8Slogwang 422a9643ea8Slogwang MicroThread* GetActiveThread(void) { 423a9643ea8Slogwang return _curr_thread; 424a9643ea8Slogwang }; 425a9643ea8Slogwang 426a9643ea8Slogwang int RunWaitNum(void) { 427a9643ea8Slogwang return _waitnum; 428a9643ea8Slogwang }; 429a9643ea8Slogwang 430a9643ea8Slogwang LogAdapter* GetLogAdpt(void) { 431a9643ea8Slogwang return _log_adpt; 432a9643ea8Slogwang }; 433a9643ea8Slogwang 434a9643ea8Slogwang CTimerMng* GetTimerMng(void) { 435a9643ea8Slogwang return _timer; 436a9643ea8Slogwang }; 437a9643ea8Slogwang 438a9643ea8Slogwang virtual int KqueueGetTimeout(void); 439a9643ea8Slogwang 440a9643ea8Slogwang virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout); 441a9643ea8Slogwang 442a9643ea8Slogwang void WaitNotify(utime64_t timeout); 443a9643ea8Slogwang 444a9643ea8Slogwang void RemoveIoWait(MicroThread* thread); 445a9643ea8Slogwang 446a9643ea8Slogwang void InsertRunable(MicroThread* thread); 447a9643ea8Slogwang 448a9643ea8Slogwang void InsertPend(MicroThread* thread); 449a9643ea8Slogwang 450a9643ea8Slogwang void RemovePend(MicroThread* thread); 451a9643ea8Slogwang 452a9643ea8Slogwang void SetRealTime(int realtime_) 453a9643ea8Slogwang { 454a9643ea8Slogwang _realtime =realtime_; 455a9643ea8Slogwang } 456a9643ea8Slogwang private: 457a9643ea8Slogwang 458a9643ea8Slogwang MtFrame():_realtime(1){ _curr_thread = NULL; }; 459a9643ea8Slogwang 460a9643ea8Slogwang MicroThread* DaemonThread(void){ 461a9643ea8Slogwang return _daemon; 462a9643ea8Slogwang }; 463a9643ea8Slogwang 464a9643ea8Slogwang void ThreadSchdule(void); 465a9643ea8Slogwang 466a9643ea8Slogwang void CheckExpired(); 467a9643ea8Slogwang 468a9643ea8Slogwang void WakeupTimeout(void); 469a9643ea8Slogwang 470a9643ea8Slogwang void SetLastClock(utime64_t clock) { 471a9643ea8Slogwang _last_clock = clock; 472a9643ea8Slogwang }; 473a9643ea8Slogwang 474a9643ea8Slogwang void SetActiveThread(MicroThread* thread) { 475a9643ea8Slogwang _curr_thread = thread; 476a9643ea8Slogwang }; 477a9643ea8Slogwang 478a9643ea8Slogwang utime64_t GetSystemMS(void) { 479a9643ea8Slogwang struct timeval tv; 480a9643ea8Slogwang gettimeofday(&tv, NULL); 481a9643ea8Slogwang return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL); 482a9643ea8Slogwang }; 483a9643ea8Slogwang 484a9643ea8Slogwang void InsertSleep(MicroThread* thread); 485a9643ea8Slogwang 486a9643ea8Slogwang void RemoveSleep(MicroThread* thread); 487a9643ea8Slogwang 488a9643ea8Slogwang void InsertIoWait(MicroThread* thread); 489a9643ea8Slogwang 490a9643ea8Slogwang void RemoveRunable(MicroThread* thread); 491a9643ea8Slogwang 492a9643ea8Slogwang }; 493a9643ea8Slogwang 494a9643ea8Slogwang #define MTLOG_DEBUG(fmt, args...) \ 495a9643ea8Slogwang do { \ 496a9643ea8Slogwang register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \ 497a9643ea8Slogwang if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckDebug()) \ 498a9643ea8Slogwang { \ 499a9643ea8Slogwang fm->GetLogAdpt()->LogDebug((char*)"[%-10s][%-4d][%-10s]"fmt, \ 500a9643ea8Slogwang __FILE__, __LINE__, __FUNCTION__, ##args); \ 501a9643ea8Slogwang } \ 502a9643ea8Slogwang } while (0) 503a9643ea8Slogwang 504a9643ea8Slogwang #define MTLOG_TRACE(fmt, args...) \ 505a9643ea8Slogwang do { \ 506a9643ea8Slogwang register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \ 507a9643ea8Slogwang if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckTrace()) \ 508a9643ea8Slogwang { \ 509a9643ea8Slogwang fm->GetLogAdpt()->LogTrace((char*)"[%-10s][%-4d][%-10s]"fmt, \ 510a9643ea8Slogwang __FILE__, __LINE__, __FUNCTION__, ##args); \ 511a9643ea8Slogwang } \ 512a9643ea8Slogwang } while (0) 513a9643ea8Slogwang 514a9643ea8Slogwang #define MTLOG_ERROR(fmt, args...) \ 515a9643ea8Slogwang do { \ 516a9643ea8Slogwang register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \ 517a9643ea8Slogwang if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckError()) \ 518a9643ea8Slogwang { \ 519a9643ea8Slogwang fm->GetLogAdpt()->LogError((char*)"[%-10s][%-4d][%-10s]"fmt, \ 520a9643ea8Slogwang __FILE__, __LINE__, __FUNCTION__, ##args); \ 521a9643ea8Slogwang } \ 522a9643ea8Slogwang } while (0) 523a9643ea8Slogwang 524a9643ea8Slogwang #define MT_ATTR_API(ATTR, VALUE) \ 525a9643ea8Slogwang do { \ 526a9643ea8Slogwang register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \ 527a9643ea8Slogwang if (fm && fm->GetLogAdpt()) \ 528a9643ea8Slogwang { \ 529a9643ea8Slogwang fm->GetLogAdpt()->AttrReportAdd(ATTR, VALUE); \ 530a9643ea8Slogwang } \ 531a9643ea8Slogwang } while (0) 532a9643ea8Slogwang 533a9643ea8Slogwang #define MT_ATTR_API_SET(ATTR, VALUE) \ 534a9643ea8Slogwang do { \ 535a9643ea8Slogwang register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \ 536a9643ea8Slogwang if (fm && fm->GetLogAdpt()) \ 537a9643ea8Slogwang { \ 538a9643ea8Slogwang fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE); \ 539a9643ea8Slogwang } \ 540a9643ea8Slogwang } while (0) 541a9643ea8Slogwang 542a9643ea8Slogwang 543a9643ea8Slogwang 544a9643ea8Slogwang }// NAMESPACE NS_MICRO_THREAD 545a9643ea8Slogwang 546a9643ea8Slogwang #endif 547a9643ea8Slogwang 548