123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- #pragma once
- // 下列 ifdef 块是创建使从 DLL 导出更简单的
- // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 SHAREMEM_NODE_EXPORTS
- // 符号编译的。在使用此 DLL 的
- // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
- // SHAREMEM_NODE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
- // 符号视为是被导出的。
- //
- #ifndef _JUST_USE_API
- #ifndef SHAREMEM_NODE_EXPORTS
- #ifdef _WIN64
- #ifdef _DEBUG
- #pragma comment(lib, "ShareMem_NodeX64D.lib")
- #else
- #pragma comment(lib, "ShareMem_NodeX64.lib")
- #endif
- #else
- #ifdef _DEBUG
- #pragma comment(lib, "ShareMem_NodeD.lib")
- #else
- #pragma comment(lib, "ShareMem_Node.lib")
- #endif
- #endif
- #endif
- #ifdef SHAREMEM_NODE_EXPORTS
- #define SHAREMEM_NODE_API __declspec(dllexport)
- #define SHAREMEM_NODE_C_API extern "C" __declspec(dllexport)
- #else
- #define SHAREMEM_NODE_API __declspec(dllimport)
- #define SHAREMEM_NODE_C_API extern "C" __declspec(dllimport)
- #endif
- #else
- #define SHAREMEM_NODE_API
- #define SHAREMEM_NODE_C_API
- #endif
- /*
- 分2个操作方:输入方,输出方
- 输入输出的原子操作:
- One way 传输:InLock,DataLock,设置异步,写入,DirtyFlag,DataUnlock,InUnLock,通知IN.
- 输出方异步操作:OutLock,DataLock,读取,CleanFlag,DataUnlock,OutUnlock.
- Double Way 传输:InLock,DataLock,设置同步,写入,DirtyFlag,DataUnlock,通知IN,等待通知OUT.
- 输出方异步操作:OutLock,DataLock,读取&进行操作&写入,DataUnlock,OutUnlock,通知OUT.
- 输入方等待:通知OUT获取,DataLock,读取,CleanFlag,DataUnLock,InUnLock.
- 输入输出的管理操作:
- 1.检索到有空的SMNODE和检索有DirtyFlag的SMNODE.
- */
- #define STK_SM_TIMEOUT (INFINITE)
- #define STK_SM_NODE_COUNT (8)
- /*
- 做了一次计算,最大的数据INPUT量为500K不到.
- 只是为了读取做成1M,一次可以发起26万次Req,接近1000天的Req.
- */
- #define STK_SM_NODE_SIZE (1024*1024*1)
- #define STK_NODE_NAME_TMP "stk_nd_n"
- #define STK_WIF_EVT_NAME "stk_smif_w"
- #define STK_RIF_EVT_NAME "stk_smif_r"
- typedef enum _In_or_Out{
- STK_SM_WRITE,
- STK_SM_READ,
- STK_SM_DATA,
- STK_SM_MAX
- }STK_SM_OP;
- //内存结构
- //头信息
- typedef struct _stk_Sm_Head {
- volatile DWORD DrityFlag;//1:dirty,0:clean
- volatile DWORD Lock[STK_SM_MAX];//Tid or 0
- volatile DWORD LockRefCount[STK_SM_MAX];
- volatile DWORD SyncMode;//1:sync,0:async
- volatile DWORD BuffSize;//real buff size
- volatile DWORD DataSize;//used data size
- }STK_ST_SM_HEAD;
- //数据区
- //数据头
- typedef struct _Stk_Data_Head {
- UINT64 uTime;//Create时间
- DWORD TaskKey;//STK_BLK_DATATYPE
- char szCode[16];
- DWORD Block;//normally is 0
- DWORD StartPos;//for import,本块数据在整个数据序列中的偏移位置
- DWORD VecCount;//VEC的个数
- DWORD VecSize;//VEC的数组大小(后续的以第一个VECSIZE为准,NORMAL,HAND,L2等TASK需要遵从)
- DWORD ParamCount;//VEC以外的参数个数
- INT Param[4];
- }STK_DATA_HEAD;
- //[数据CONTEXT]
- #pragma warning (push)
- #pragma warning (disable : 4200)
- typedef enum _Stk_DataContext_Type {
- STK_DC_VEC32,
- STK_DC_VEC64,
- STK_DC_STR,
- STK_DC_MAX
- }STK_DC_TYPE;
- typedef struct _Stk_Data_Context32 {
- STK_DC_TYPE Type;
- DWORD Key;
- DWORD Size;//size in Count
- DWORD Rev;//for 64bit
- FLOAT VecContext[0];
- }STK_DATA_CONTEXT32;
- typedef struct _Stk_Data_Context64 {
- STK_DC_TYPE Type;
- DWORD Key;
- DWORD Size;//size in Count
- DWORD Rev;//for 64bit
- UINT64 VecContext[0];
- }STK_DATA_CONTEXT64;
- typedef struct _Stk_Data_Context_Str {
- STK_DC_TYPE Type;
- DWORD Key;
- DWORD Size;//size in byte
- DWORD Rev;//for 64bit
- char szStr[0];//make sure it's size qualifies to (val % sizeof(DWORD) == 0)
- }STK_DATA_CONTEXT_STR;
- typedef union _Stk_Data_Context
- {
- struct
- {
- STK_DC_TYPE Type;
- DWORD Key;
- DWORD Size;//size in Count
- DWORD Rev;//for 64bit
- }Common;
- STK_DATA_CONTEXT32 Context32;
- STK_DATA_CONTEXT64 Context64;
- STK_DATA_CONTEXT_STR ContextStr;
- }STK_DATA_CONTEXT;
- #pragma warning (pop)
- // 此类是从 ShareMem_Node.dll 导出的
- class SHAREMEM_NODE_API ShareMem_Node {
- PVOID m_SmBuff;
- HANDLE m_hMapping;
- /*
- 本Notify只用于双方更新完数据后给对方发起通知.
- 至于节点释放通知,由主IF对象中的2个R/W事件对象进行管理.
- */
- HANDLE m_Notify[STK_SM_MAX];//write & read
- STK_ST_SM_HEAD* GetHead();
- bool Lock_EnterCriticalSection(STK_SM_OP op, DWORD TryCount);
- void Lock_LeaveCriticalSection(STK_SM_OP op);
- public:
- ShareMem_Node();
- virtual ~ShareMem_Node();
- bool CreateNode(const char *pNodeName);
- bool OpenNode(const char *pNodeName);
- void ClearNode();
- HANDLE GetEvtHandle(STK_SM_OP op);
- DWORD Lock(STK_SM_OP op);
- void UnLock(STK_SM_OP op);
- DWORD GetDirtyFlag();
- void SetDirtyFlag(DWORD flag);
- DWORD GetSyncMode();
- void SetSyncMode(DWORD Sync);
- DWORD GetBuffSize();
- DWORD GetDataSize();
- void SetDataSize(DWORD Size);
- void UpdateDataSize();
- PVOID GetData();//get data buff
- STK_DATA_HEAD *GetDataHead();
- STK_DATA_CONTEXT *GetDataContext(DWORD Idx);//Get Exist one
- STK_DATA_CONTEXT *GetLastNewDataContext();//get last new one
- //业务功能
- //异步操作--------------------------------------------------------------
- //Async Request from Writer(单向写入)
- //--API:GetNode (帮你筛选&操作: DirtyFlag == 0 && WriteLock)
- //dataLock
- //1.update data
- //2.update datasize
- //3.update syncmode =0 (async)
- //4.set DirtyFlag = 1
- //dataUnLock
- //Set ReadEvt,GlobalReadEvt
- //WriteUnlock
- //Async Read from Writer(单向读取)
- //--API:GetNode (帮你筛选&操作: DirtyFlag == 1 && ReadLock)
- //DataLock
- //0.check syncmode == 0 (async)
- //1.process data
- //---------below is clean job
- //2.update datasize to 0
- //3.set DirtyFlag = 0
- //DataUnLock
- //Set WriteEvt,GlobalWriteEvt
- //ReadUnLock
- //同步操作--------------------------------------------------------------
- //sync Read from Writer(线程读写)
- //--API:GetNode (帮你筛选&操作: DirtyFlag == 1 && ReadLock)
- //DataLock
- //0.check syncmode == 1(sync)
- //1.process data
- //---------below is response job
- //2.update data with response
- //3.update datasize
- //4.set DirtyFlag = 0(目的是为了提示已经写入数据)
- //DataUnLock
- //Set WriteEvt
- //ReadUnLock
- //线程Write:
- //Step1:----------------------
- //线程write:
- //--API:GetNode (帮你筛选&操作: DirtyFlag == 0 && WriteLock)
- //dataLock
- //1.update data
- //2.update datasize
- //3.update syncmode =1 (sync)
- //4.set DirtyFlag = 1
- //dataUnLock
- //Set ReadEvt,GlobalReadEvt
- //WaitFor EvtOfWrite
- //dataLock
- //先读取Response数据,并保存。
- //dataUnLock
- //goto step2
- //Step2:--------------------
- //线程write:
- //dataLock
- //1.update data
- //2.update datasize
- //3.update syncmode =1 (sync)
- //4.set DirtyFlag = 1
- //dataUnLock
- //Set ReadEvt
- //WaitFor EvtOfWrite
- //dataLock
- //先读取Response数据,并保存。
- //dataUnLock
- //goto step3
- //Step3:--------------------
- //Step4:--------------------
- //Step...:--------------------
- //LastStep:(数据为空)
- //线程write:
- //dataLock
- //1.update data
- //2.update datasize = 0
- //3.update syncmode =0 (async)
- //4.set DirtyFlag = 1
- //dataUnLock
- //Set ReadEvt
- //WriteUnlock
- };
- SHAREMEM_NODE_C_API DWORD STK_GetMaxDataSize();
- SHAREMEM_NODE_C_API HANDLE STK_GetNotifyHandle(STK_SM_OP op);
- SHAREMEM_NODE_C_API bool STK_CreateSMIF();//server端用
- SHAREMEM_NODE_C_API bool STK_OpenSMIF();//Client端用
- SHAREMEM_NODE_C_API void STK_CloseSMIF();
- //1.check dirtyflag,if dirty or clean
- //2.try lock readlock or writelock,and check again.
- //3.if succeed return node.
- //4.if failed,then relase it.
- SHAREMEM_NODE_C_API ShareMem_Node *STK_GetNode(STK_SM_OP op, DWORD timeout = INFINITE);
- SHAREMEM_NODE_C_API void STK_NotifyAvalable(STK_SM_OP op, ShareMem_Node *pNode = NULL);
- SHAREMEM_NODE_C_API void STK_NotifyRelease(STK_SM_OP op, ShareMem_Node *pNode);
- SHAREMEM_NODE_C_API void STK_CleanUp(ShareMem_Node *pNode);//Reader的节点释放
- //后面的数据先到情况下,重新放入队列
- SHAREMEM_NODE_C_API void STK_RestoreNodeForRead(ShareMem_Node *pNode);
- SHAREMEM_NODE_C_API bool STK_CheckDataIntegrity(ShareMem_Node *pNode);
- //业务模块模板
- //异步接口
- //如果数据很大,内部不停的循环保存.
- //SHAREMEM_NODE_C_API bool STK_WriteData_Async(STK_DATA_HEAD *pHead, STK_DATA_CONTEXT *pInputData, DWORD timeout = STK_SM_TIMEOUT);
- SHAREMEM_NODE_C_API bool STK_WriteData_Async(ShareMem_Node *pNode);
- //同步接口
- //RET:有效数据的起始位置
- SHAREMEM_NODE_C_API INT STK_WriteData_Sync(ShareMem_Node *pNode, FLOAT *pOutputData, DWORD timeout = STK_SM_TIMEOUT);
- SHAREMEM_NODE_C_API ShareMem_Node *STK_ReadData_Get(STK_DATA_HEAD *&pHead, STK_DATA_CONTEXT *&pData, DWORD timeout = INFINITE);
- SHAREMEM_NODE_C_API void STK_ReadData_Finished(ShareMem_Node *pNode);
|