f-stack/app/micro_thread/micro_thread.h

926 lines
23 KiB
C
Raw Normal View History

2017-04-21 13:43:26 +03:00
/**
* Tencent is pleased to support the open source community by making MSEC available.
*
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the GNU General Public License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* https://opensource.org/licenses/GPL-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
/**
* @filename micro_thread.h
* @info micro thread manager
*/
#ifndef ___MICRO_THREAD_H__
#define ___MICRO_THREAD_H__
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/queue.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <setjmp.h>
#include <set>
#include <vector>
#include <queue>
#include "heap.h"
#include "kqueue_proxy.h"
#include "heap_timer.h"
using std::vector;
using std::set;
using std::queue;
namespace NS_MICRO_THREAD {
#define STACK_PAD_SIZE 128 ///< ջ<><D5BB><EFBFBD>¸<EFBFBD><C2B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С
#define MEM_PAGE_SIZE 4096 ///< <20>ڴ<EFBFBD>ҳĬ<D2B3>ϴ<EFBFBD>С
#define DEFAULT_STACK_SIZE 128*1024 ///< Ĭ<><C4AC>ջ<EFBFBD><D5BB>С128K
#define DEFAULT_THREAD_NUM 2000 ///< Ĭ<><C4AC>2000<30><30><EFBFBD><EFBFBD>ʼ<EFBFBD>߳<EFBFBD>
typedef unsigned long long utime64_t; ///< 64λ<34><CEBB>ʱ<EFBFBD><EFBFBD><E4B6A8>
typedef void (*ThreadStart)(void*); ///< ΢<>߳<EFBFBD><DFB3><EFBFBD><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief <EFBFBD>̵߳<EFBFBD><EFBFBD>ȵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ӿڷ<EFBFBD>װ
*/
class ScheduleObj
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static ScheduleObj* Instance (void);
/**
* @brief <EFBFBD><EFBFBD>ȡȫ<EFBFBD>ֵ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>λ
*/
utime64_t ScheduleGetTime(void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void ScheduleThread(void);
/**
* @brief <EFBFBD>̵߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sleep״̬
*/
void ScheduleSleep(void);
/**
* @brief <EFBFBD>̵߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pend״̬
*/
void SchedulePend(void);
/**
* @brief <EFBFBD>̵߳<EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>pend״̬, <EFBFBD>ⲿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>
*/
void ScheduleUnpend(void* thread);
/**
* @brief <EFBFBD>߳<EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD>
*/
void ScheduleReclaim(void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȳ<EFBFBD>ʼִ<EFBFBD><EFBFBD>
*/
void ScheduleStartRun(void);
private:
static ScheduleObj* _instance; // ˽<>о<EFBFBD><D0BE><EFBFBD>
};
/**
* @brief <EFBFBD>߳<EFBFBD>ͨ<EFBFBD>õ<EFBFBD>ջ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
struct MtStack
{
int _stk_size; ///< ջ<>Ĵ<EFBFBD>С, <20><>Чʹ<D0A7>ÿռ<C3BF>
int _vaddr_size; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>buff<66>ܴ<EFBFBD>С
char *_vaddr; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ַ
void *_esp; ///< ջ<><D5BB>esp<73>Ĵ<EFBFBD><C4B4><EFBFBD>
char *_stk_bottom; ///< ջ<><D5BB><EFBFBD>͵ĵ<CDB5>ַ<EFBFBD>ռ<EFBFBD>
char *_stk_top; ///< ջ<><D5BB><EFBFBD>ߵĵ<DFB5>ַ<EFBFBD>ռ<EFBFBD>
void *_private; ///< <20>߳<EFBFBD>˽<EFBFBD><CBBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int valgrind_id; ///< valgrind id
};
/**
* @brief ͨ<EFBFBD>õ<EFBFBD><EFBFBD>߳<EFBFBD>ģ<EFBFBD>Ͷ<EFBFBD><EFBFBD><EFBFBD>
*/
class Thread : public HeapEntry
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
explicit Thread(int stack_size = 0);
virtual ~Thread(){};
/**
* @brief <EFBFBD>̵߳<EFBFBD>ʵ<EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void Run(void){};
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD>ʼ<EFBFBD><EFBFBD>
*/
bool Initial(void);
/**
* @brief <EFBFBD><EFBFBD>ֹ<EFBFBD>߳<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>
*/
void Destroy(void);
/**
* @brief <EFBFBD>߳<EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>ɸ<EFBFBD><EFBFBD><EFBFBD>״̬
*/
void Reset(void);
/**
* @brief <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˯<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param ms ˯<EFBFBD>ߺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void sleep(int ms);
/**
* @brief <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>, <EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void Wait();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SwitchContext(void);
/**
* @brief <EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void RestoreContext(void);
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
* @return <EFBFBD>̵߳Ļ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
utime64_t GetWakeupTime(void) {
return _wakeup_time;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
* @param waketime <EFBFBD>̵߳Ļ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetWakeupTime(utime64_t waketime) {
_wakeup_time = waketime;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>˽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param data <EFBFBD>߳<EFBFBD>˽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
void SetPrivate(void *data)
{
_stack->_private = data;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD>߳<EFBFBD>˽<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void* GetPrivate()
{
return _stack->_private;
}
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>üĴ<EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD>ջ
*/
bool CheckStackHealth(char *esp);
protected:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴߳<EFBFBD><EFBFBD><EFBFBD>״̬, ׼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void CleanState(void){};
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>Ϣ
*/
virtual bool InitStack(void);
/**
* @brief <EFBFBD>ͷŶ<EFBFBD>ջ<EFBFBD><EFBFBD>Ϣ
*/
virtual void FreeStack(void);
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>üĴ<EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD>ջ
*/
virtual void InitContext(void);
private:
MtStack* _stack; ///< ˽<><CBBD>ջָ<D5BB><D6B8>
jmp_buf _jmpbuf; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>jmpbuff
int _stack_size; ///< ջ<><D5BB>С<EFBFBD>ֶ<EFBFBD>
utime64_t _wakeup_time; ///< ˯<>߻<EFBFBD><DFBB><EFBFBD>ʱ<EFBFBD><CAB1>
};
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class MicroThread : public Thread
{
public:
enum ThreadType
{
NORMAL = 0, ///< Ĭ<><C4AC><EFBFBD><EFBFBD>ͨ<EFBFBD>߳<EFBFBD>, û<>ж<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB>Ϣ
PRIMORDIAL = 1, ///< ԭ<><D4AD><EFBFBD>߳<EFBFBD>, main<69><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DAEMON = 2, ///< <20>ػ<EFBFBD><D8BB>߳<EFBFBD>, <20>ײ<EFBFBD>IO EPOLL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>
SUB_THREAD = 3, ///< <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>, <20><>ִ<EFBFBD>м򵥹<D0BC><F2B5A5B9><EFBFBD>
};
enum ThreadFlag
{
NOT_INLIST = 0x0, ///< <20>޶<EFBFBD><DEB6><EFBFBD>״̬
FREE_LIST = 0x1, ///< <20><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
IO_LIST = 0x2, ///< IO<49>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SLEEP_LIST = 0x4, ///< <20><><EFBFBD><EFBFBD>SLEEP<45><50>
RUN_LIST = 0x8, ///< <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
PEND_LIST = 0x10, ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SUB_LIST = 0x20, ///< <20><><EFBFBD><EFBFBD><EFBFBD>̶߳<DFB3><CCB6><EFBFBD><EFBFBD><EFBFBD>
};
enum ThreadState
{
INITIAL = 0, ///< <20><>ʼ<EFBFBD><CABC>״̬
RUNABLE = 1, ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
RUNNING = 2, ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SLEEPING = 3, ///< IO<49>ȴ<EFBFBD><C8B4><EFBFBD>SLEEP<45><50>
PENDING = 4, ///< <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC>, <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>߳<EFBFBD>OK<4F><4B>
};
typedef TAILQ_ENTRY(MicroThread) ThreadLink; ///< ΢<>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList; ///< ΢<>̶߳<DFB3><CCB6>ж<EFBFBD><D0B6><EFBFBD>
public:
/**
* @brief ΢<EFBFBD>̹߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
MicroThread(ThreadType type = NORMAL);
~MicroThread(){};
ThreadLink _entry; ///< ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ThreadLink _sub_entry; ///< <20><><EFBFBD>̶߳<DFB3><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <EFBFBD>̵߳<EFBFBD>ʵ<EFBFBD>ʻ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
*/
virtual utime64_t HeapValue() {
return GetWakeupTime();
};
/**
* @brief <EFBFBD>̵߳<EFBFBD>ʵ<EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void Run(void);
/**
* @breif fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD><EFBFBD>
*/
void ClearAllFd(void) {
TAILQ_INIT(&_fdset);
};
void AddFd(KqueuerObj* efpd) {
TAILQ_INSERT_TAIL(&_fdset, efpd, _entry);
};
void AddFdList(KqObjList* fdset) {
TAILQ_CONCAT(&_fdset, fdset, _entry);
};
KqObjList& GetFdSet(void) {
return _fdset;
};
/**
* @breif ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetType(ThreadType type) {
_type = type;
};
ThreadType GetType(void) {
return _type;
};
/**
* @breif ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
bool IsDaemon(void) {
return (DAEMON == _type);
};
bool IsPrimo(void) {
return (PRIMORDIAL == _type);
};
bool IsSubThread(void) {
return (SUB_THREAD == _type);
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetParent(MicroThread* parent) {
_parent = parent;
};
MicroThread* GetParent() {
return _parent;
};
void WakeupParent();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>̵߳Ĺ<EFBFBD><EFBFBD><EFBFBD>
*/
void AddSubThread(MicroThread* sub);
void RemoveSubThread(MicroThread* sub);
bool HasNoSubThread();
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetState(ThreadState state) {
_state = state;
};
ThreadState GetState(void) {
return _state;
}
/**
* @breif ΢<EFBFBD>̱߳<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetFlag(ThreadFlag flag) {
_flag = (ThreadFlag)(_flag | flag);
};
void UnsetFlag(ThreadFlag flag) {
_flag = (ThreadFlag)(_flag & ~flag);
};
bool HasFlag(ThreadFlag flag) {
return _flag & flag;
};
ThreadFlag GetFlag() {
return _flag;
};
/**
* @breif ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>
*/
void SetSartFunc(ThreadStart func, void* args) {
_start = func;
_args = args;
};
void* GetThreadArgs() {
return _args;
}
protected:
/**
* @breif ΢<EFBFBD≯߳<EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
virtual void CleanState(void);
private:
ThreadState _state; ///< ΢<>̵߳<DFB3>ǰ״̬
ThreadType _type; ///< ΢<>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
ThreadFlag _flag; ///< ΢<>̱߳<DFB3><CCB1><EFBFBD>λ
KqObjList _fdset; ///< ΢<>̹߳<DFB3>ע<EFBFBD><D7A2>socket<65>б<EFBFBD>
SubThreadList _sub_list; ///< <20><><EFBFBD><EFBFBD><EFBFBD>̵߳Ķ<CCB5><C4B6><EFBFBD>
MicroThread* _parent; ///< <20><><EFBFBD><EFBFBD><EFBFBD>̵߳ĸ<CCB5><C4B8>߳<EFBFBD>
ThreadStart _start; ///< ΢<>߳<EFBFBD>ע<EFBFBD><EFBFBD><E1BAAF>
void* _args; ///< ΢<>߳<EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
typedef std::set<MicroThread*> ThreadSet; ///< ΢<>߳<EFBFBD>set<65><74><EFBFBD><EFBFBD><EFBFBD>
typedef std::queue<MicroThread*> ThreadList; ///< ΢<>߳<EFBFBD>queue<75><65><EFBFBD><EFBFBD><EFBFBD>
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ӿ<EFBFBD>, <EFBFBD>ײ<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD>־<EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>
*/
class LogAdapter
{
public:
/**
* @brief <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
LogAdapter(){};
virtual ~LogAdapter(){};
/**
* @brief <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD>Ȱ<EFBFBD><EFBFBD>ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>ٽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD>
* @return true <EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>ӡ<EFBFBD>ü<EFBFBD><EFBFBD><EFBFBD>, false <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡ<EFBFBD>ü<EFBFBD><EFBFBD><EFBFBD>
*/
virtual bool CheckDebug(){ return true;};
virtual bool CheckTrace(){ return true;};
virtual bool CheckError(){ return true;};
/**
* @brief <EFBFBD><EFBFBD>־<EFBFBD>ּ<EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ӿ<EFBFBD>
*/
virtual void LogDebug(char* fmt, ...){};
virtual void LogTrace(char* fmt, ...){};
virtual void LogError(char* fmt, ...){};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD>ӿ<EFBFBD>
*/
virtual void AttrReportAdd(int attr, int iValue){};
virtual void AttrReportSet(int attr, int iValue){};
};
/**
* @brief ΢<EFBFBD>̳߳ؼ<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD>
*/
class ThreadPool
{
public:
static unsigned int default_thread_num; ///< Ĭ<><C4AC>2000΢<30>̴߳<DFB3><CCB4><EFBFBD>
static unsigned int default_stack_size; ///< Ĭ<><C4AC>128Kջ<4B><D5BB>С
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD>̵߳<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
*/
static void SetDefaultThreadNum(unsigned int num) {
default_thread_num = num;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD>̵߳<EFBFBD>Ĭ<EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>С, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void SetDefaultStackSize(unsigned int size) {
default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE;
};
/**
* @brief ΢<EFBFBD>̳߳س<EFBFBD>ʼ<EFBFBD><EFBFBD>
*/
bool InitialPool(int max_num);
/**
* @brief ΢<EFBFBD>̳߳ط<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
*/
void DestroyPool (void);
/**
* @brief ΢<EFBFBD>̷߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
* @return ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
MicroThread* AllocThread(void);
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD>ͷŽӿ<EFBFBD>
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void FreeThread(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
int GetUsedNum(void);
private:
ThreadList _freelist; ///< <20><><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>΢<EFBFBD>̶߳<DFB3><CCB6><EFBFBD>
int _total_num; ///< Ŀǰ<C4BF>ܵ<EFBFBD>΢<EFBFBD>߳<EFBFBD><DFB3><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int _use_num; ///< <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>΢<EFBFBD>߳<EFBFBD><DFB3><EFBFBD>Ŀ
int _max_num; ///< <20><><EFBFBD>󲢷<EFBFBD><F3B2A2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
};
typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq; ///< ΢<>̶߳<DFB3><CCB6>ж<EFBFBD><D0B6><EFBFBD>
/**
* @brief ΢<EFBFBD>߳̿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ȫ<EFBFBD>ֵĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class MtFrame : public KqueueProxy, public ThreadPool
{
private:
static MtFrame* _instance; ///< <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
LogAdapter* _log_adpt; ///< <20><>־<EFBFBD>ӿ<EFBFBD>
ThreadList _runlist; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>queue, <20><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
ThreadTailq _iolist; ///< <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ThreadTailq _pend_list; ///< <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
HeapList _sleeplist; ///< <20>ȴ<EFBFBD><C8B4><EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ȡ<EFBFBD><C8A1>С<EFBFBD><D0A1><EFBFBD><EFBFBD>
MicroThread* _daemon; ///< <20>ػ<EFBFBD><D8BB>߳<EFBFBD>, ִ<><D6B4>epoll wait, <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
MicroThread* _primo; ///< ԭ<><D4AD><EFBFBD>߳<EFBFBD>, ʹ<>õ<EFBFBD><C3B5><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>ջ
MicroThread* _curr_thread; ///< <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
utime64_t _last_clock; ///< ȫ<><C8AB>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>, ÿ<><C3BF>idle<6C><65>ȡһ<C8A1><D2BB>
int _waitnum; ///< <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD>߳<EFBFBD><DFB3><EFBFBD>, <20>ɵ<EFBFBD><C9B5>ڵ<EFBFBD><DAB5>ȵĽ<C8B5><C4BD><EFBFBD>
CTimerMng* _timer; ///< TCP<43><50><EFBFBD><EFBFBD>ר<EFBFBD>õ<EFBFBD>timer<65><72>ʱ<EFBFBD><CAB1>
int _realtime; /// < ʹ<><CAB9>ʵʱʱ<CAB1><CAB1>0, δ<><CEB4><EFBFBD><EFBFBD>
public:
friend class ScheduleObj; ///< <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ, <20><>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD>
public:
/**
* @brief ΢<EFBFBD>߳̿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ȫ<EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ
*/
static MtFrame* Instance (void);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> sendto
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param msg <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Ϣָ<EFBFBD><EFBFBD>
* @param len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param to Ŀ<EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param tolen Ŀ<EFBFBD>ĵ<EFBFBD>ַ<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> recvfrom
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param buf <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param from <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param fromlen <EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>ַ<EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> connect
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param addr ָ<EFBFBD><EFBFBD>server<EFBFBD><EFBFBD>Ŀ<EFBFBD>ĵ<EFBFBD>ַ
* @param addrlen <EFBFBD><EFBFBD>ַ<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> accept
* @param fd <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׽<EFBFBD><EFBFBD><EFBFBD>
* @param addr <EFBFBD>ͻ<EFBFBD><EFBFBD>˵<EFBFBD>ַ
* @param addrlen <EFBFBD><EFBFBD>ַ<EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >=0 accept<EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> read
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param buf <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param nbyte <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static ssize_t read(int fd, void *buf, size_t nbyte, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> write
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param buf <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param nbyte <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> recv
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param buf <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* @param len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int recv(int fd, void *buf, int len, int flags, int timeout);
/**
* @brief ΢<EFBFBD>̰߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳIO<EFBFBD><EFBFBD><EFBFBD><EFBFBD> send
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param buf <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Ϣָ<EFBFBD><EFBFBD>
* @param nbyte <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>sleep<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD>λms
*/
static void sleep(int ms);
/**
* @brief ΢<EFBFBD>߳̽<EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD>¼<EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD>
* @param fd ϵͳsocket<EFBFBD><EFBFBD>Ϣ
* @param events <EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> EPOLLIN or EPOLLOUT
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return >0 <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>, <0 ʧ<EFBFBD><EFBFBD>
*/
static int WaitEvents(int fd, int events, int timeout);
/**
* @brief ΢<EFBFBD>̴߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>
* @param entry <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD>
* @param args <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD>
* @return ΢<EFBFBD>߳<EFBFBD>ָ<EFBFBD><EFBFBD>, NULL<EFBFBD><EFBFBD>ʾʧ<EFBFBD><EFBFBD>
*/
static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true);
/**
* @brief <EFBFBD>ػ<EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>static<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param args <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD>
*/
static void DaemonRun(void* args);
static int Loop(void* args);
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD>̵߳ĸ<EFBFBD><EFBFBD>߳<EFBFBD>
*/
MicroThread *GetRootThread();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD>ʼ<EFBFBD><EFBFBD>, Ĭ<EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = 50000);
/**
* @brief HOOKϵͳapi<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetHookFlag();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
*/
void Destroy (void);
/**
* @brief ΢<EFBFBD>߳̿<EFBFBD><EFBFBD>ܰ<EFBFBD><EFBFBD>ȡ
*/
char* Version(void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD>ȡȫ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
utime64_t GetLastClock(void) {
if(_realtime)
{
return GetSystemMS();
}
return _last_clock;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD>߳<EFBFBD>
*/
MicroThread* GetActiveThread(void) {
return _curr_thread;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>, ֱ<EFBFBD>Ӽ<EFBFBD><EFBFBD><EFBFBD>, Ч<EFBFBD>ʸ<EFBFBD>
* @return <EFBFBD>ȴ<EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD>
*/
int RunWaitNum(void) {
return _waitnum;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܱ<EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
LogAdapter* GetLogAdpt(void) {
return _log_adpt;
};
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ܱ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
*/
CTimerMng* GetTimerMng(void) {
return _timer;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD>epoll waitǰ, <EFBFBD>ж<EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
*/
virtual int KqueueGetTimeout(void);
/**
* @brief ΢<EFBFBD>̴߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>óɹ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>cpu, <EFBFBD>ڲ<EFBFBD><EFBFBD>ӿ<EFBFBD>
* @param fdlist <EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD>б<EFBFBD>
* @param fd <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD>Ϣ
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return true <EFBFBD>ɹ<EFBFBD>, false ʧ<EFBFBD><EFBFBD>
*/
virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout);
/**
* @brief ΢<EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>, <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳Ļ<EFBFBD><EFBFBD><EFBFBD>
* @param timeout <EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void WaitNotify(utime64_t timeout);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, <EFBFBD>Ƴ<EFBFBD>IO<EFBFBD>ȴ<EFBFBD>״̬, <EFBFBD>ڲ<EFBFBD><EFBFBD>ӿ<EFBFBD>
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void RemoveIoWait(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD>ڲ<EFBFBD><EFBFBD>ӿ<EFBFBD>
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void InsertRunable(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, ִ<EFBFBD><EFBFBD>pend<EFBFBD>ȴ<EFBFBD>״̬
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void InsertPend(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, <EFBFBD>Ƴ<EFBFBD>PEND<EFBFBD>ȴ<EFBFBD>״̬
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void RemovePend(MicroThread* thread);
void SetRealTime(int realtime_)
{
_realtime =realtime_;
}
private:
/**
* @brief ΢<EFBFBD>߳<EFBFBD>˽<EFBFBD>й<EFBFBD><EFBFBD><EFBFBD>
*/
MtFrame():_realtime(1){ _curr_thread = NULL; };
/**
* @brief ΢<EFBFBD>߳<EFBFBD>˽<EFBFBD>л<EFBFBD>ȡ<EFBFBD>ػ<EFBFBD><EFBFBD>߳<EFBFBD>
*/
MicroThread* DaemonThread(void){
return _daemon;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void ThreadSchdule(void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void CheckExpired();
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еij<EFBFBD>ʱ<EFBFBD>߳<EFBFBD>
*/
void WakeupTimeout(void);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void SetLastClock(utime64_t clock) {
_last_clock = clock;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ǰ<EFBFBD>߳<EFBFBD>
*/
void SetActiveThread(MicroThread* thread) {
_curr_thread = thread;
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD>ʱ<EFBFBD><EFBFBD>Դ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>غ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
*/
utime64_t GetSystemMS(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL);
};
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, ִ<EFBFBD><EFBFBD>IO<EFBFBD>ȴ<EFBFBD>״̬
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void InsertSleep(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, <EFBFBD>Ƴ<EFBFBD>IO<EFBFBD>ȴ<EFBFBD>״̬
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void RemoveSleep(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, ִ<EFBFBD><EFBFBD>IO<EFBFBD>ȴ<EFBFBD>״̬
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void InsertIoWait(MicroThread* thread);
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵߳<EFBFBD>Ԫ, <EFBFBD>Ƴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>
* @param thread ΢<EFBFBD>̶߳<EFBFBD><EFBFBD><EFBFBD>
*/
void RemoveRunable(MicroThread* thread);
};
/**
* @brief <EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD>岿<EFBFBD><EFBFBD>
*/
#define MTLOG_DEBUG(fmt, args...) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckDebug()) \
{ \
fm->GetLogAdpt()->LogDebug((char*)"[%-10s][%-4d][%-10s]"fmt, \
__FILE__, __LINE__, __FUNCTION__, ##args); \
} \
} while (0)
#define MTLOG_TRACE(fmt, args...) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckTrace()) \
{ \
fm->GetLogAdpt()->LogTrace((char*)"[%-10s][%-4d][%-10s]"fmt, \
__FILE__, __LINE__, __FUNCTION__, ##args); \
} \
} while (0)
#define MTLOG_ERROR(fmt, args...) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt() && fm->GetLogAdpt()->CheckError()) \
{ \
fm->GetLogAdpt()->LogError((char*)"[%-10s][%-4d][%-10s]"fmt, \
__FILE__, __LINE__, __FUNCTION__, ##args); \
} \
} while (0)
#define MT_ATTR_API(ATTR, VALUE) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt()) \
{ \
fm->GetLogAdpt()->AttrReportAdd(ATTR, VALUE); \
} \
} while (0)
#define MT_ATTR_API_SET(ATTR, VALUE) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt()) \
{ \
fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE); \
} \
} while (0)
}// NAMESPACE NS_MICRO_THREAD
#endif