📄 com_support.cpp
字号:
/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·笆布の (1)×(4) の掘凤か·Free Software Foundation * によって给山されている GNU General Public License の Version 2 に淡 * 揭されている掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェア * を猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを·ライブラリ妨及など·戮のソフトウェア倡券に蝗 * 脱できる妨で浩芹邵する眷圭には·浩芹邵に燃うドキュメント∈网脱 * 荚マニュアルなど∷に·惧淡の螟侯涪山绩·この网脱掘凤および布淡 * の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを·怠达に寥み哈むなど·戮のソフトウェア倡券に蝗 * 脱できない妨で浩芹邵する眷圭には·肌のいずれかの掘凤を塔たすこ * とˉ * (a) 浩芹邵に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟 * 侯涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 浩芹邵の妨轮を·侍に年める数恕によって·TOPPERSプロジェクトに * 鼠桂することˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚およびTOPPERSプロジェクトを倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚お * よびTOPPERSプロジェクトは·塑ソフトウェアに簇して·その努脱材墙拉も * 崔めて·いかなる瘦沮も乖わないˉまた·塑ソフトウェアの网脱により木 * 儡弄または粗儡弄に栏じたいかなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: com_support.cpp,v 1.10 2003/12/15 07:19:22 takayuki Exp $ */#include <vitron.h>#include <com_support.h>#include <eventlog.h>#include "syslog.h"#include <resource.h>#include <commctrl.h>/* * 涟に使かれた祸の棱汤 * Q: CスタイルコメントとC++スタイルコメントが寒ざっていますが? * A: 丹弛にコメントアウトされると氦る借妄がCスタイルコメントで、击たような借妄をする眷疥の棱汤にC++スタイルコメントを蝗っています。 * * Q: 恃眶の叹づけ惮搂がめちゃくちゃですが? * A: 答塑弄にスコ〖プ认跋で蝗い尸けています。 * ロ〖カルが井矢机+"_", グロ〖バルが络矢机井矢机, メンバがJavaっぽいスタイル * * Q: INVALID_HANDLE_VALUE と NULL をどう蝗い尸けているのですか? * A: CreateXxxxが己窃箕に手笛する猛であわせました。 * 恶挛弄には、ファイルはINVALID_HANDLE_VALUE(CreateFile)で、それ笆嘲がNULLになってます。 */#ifndef __COM_NOT_REQUIRED__//===================================================/* * 鼎奶婶 */extern "C" SYSTIM _kernel_systim_offset;extern "C" SYSTIM _kernel_current_time;extern "C" HINSTANCE ProcessInstance;extern "C" HANDLE PrimaryDialogHandle;extern "C" BOOL ShutdownPostponementRequest;extern "C" int CPUStatus;extern "C" void FatalAssertion(int exp, LPCSTR format, ... );extern "C" void enter_system_critical_section(BOOL * cookie);extern "C" void leave_system_critiacl_section(BOOL * cookie);#ifdef KERNEL_DEBUG_MODE extern "C" _kernel_debugprintf(const char * format, ... );# define kprintf(x) _kernel_debugprintf x#else# define kprintf(x)#endif//=================================================== /* ユ〖ザ年盗のログ */#define USERDEFINED 0x60#define LOG_MODULENAME (0 | USERDEFINED) /* モジュ〖ルの叹涟 */#define LOG_TIMESTAMP (1 | USERDEFINED) /* 淡峡を倡幌した箕癸 (SYSTEMTIME菇陇挛をそのままダンプ) */#define __HAL_MSG_MSGONLY#include <hal_msg.h>#include <string>namespace{ /* * COMインタ〖フェ〖ス簇息の年盗 */ //紧」のIDの离咐 const IID IID_IKernelEvents = {0x1353969D,0xE84F,0x463F,{0xB2,0x11,0x33,0x7E,0x9B,0xCF,0xB9,0x9E}}; const IID IID_IKernel = {0xD3E42099,0x3FDD,0x4A78,{0xBD,0xBD,0x4E,0x57,0xD3,0x62,0xF5,0xED}}; const CLSID CLSID_Kernel = {0x51789667,0x9F20,0x40AF,{0xAF,0x7F,0x98,0x56,0x32,0x5D,0xFB,0x0B}}; // IKernelインタ〖フェ〖ス年盗 class IKernel : public IUnknown { public: STDMETHOD(Read)(unsigned long address,unsigned long sz,char __RPC_FAR data[]) PURE; STDMETHOD(IsValid)(BOOL __RPC_FAR * valid) PURE; STDMETHOD(Write)(unsigned long address,unsigned long sz,char __RPC_FAR data[]) PURE; STDMETHOD(OnLogEvent)(long sz, unsigned char __RPC_FAR data[]) PURE; }; // IKernelEventsインタフェ〖ス年盗 class IKernelEvents : public IUnknown { public: STDMETHOD(QueryInterface)(REFIID iid, void ** unk); STDMETHOD_(ULONG,AddRef)(); STDMETHOD_(ULONG,Release)(); STDMETHOD(OnInterruptRequest)(long inhno); IKernelEvents(void); long RefCount; }; /* * IKernelEvents悸刘 */ IKernelEvents::IKernelEvents(void) : RefCount(0) {} STDMETHODIMP IKernelEvents::QueryInterface(REFIID iid, void ** unk) { if( iid == IID_IKernelEvents || iid == IID_IUnknown ) { *unk = this; ::InterlockedIncrement(&RefCount); return S_OK; } return E_NOINTERFACE; } STDMETHODIMP_(ULONG) IKernelEvents::AddRef() { return ::InterlockedIncrement(&RefCount); } STDMETHODIMP_(ULONG) IKernelEvents::Release() { if( ::InterlockedDecrement(&RefCount) == 0) delete this; return RefCount; } STDMETHODIMP IKernelEvents::OnInterruptRequest(long inhno) { if(inhno < 0) { /* inhno < 0 は泼检な罢蹋を积つ */ /* inhno = -1 : keep-alive */ }else ::PostMessage((HWND)PrimaryDialogHandle,HALMSG_MESSAGE,HALMSG_INTERRUPT,(LPARAM)inhno); return S_OK; }}namespace { /* * COM奶慨脱侯度スレッドに簇する年盗 */ HANDLE request_semaphore = NULL; //妥滇略ちセマフォ HANDLE worker_thread_handle = NULL; //侯度スレッドのハンドル //============================================================================== //COM侯度スレッドが赖撅に侯瓢しているか容か inline bool IsValid(void) { return (request_semaphore != NULL) && (worker_thread_handle != NULL); } //=================================================== /* * Q: どうしてシステムロックが涩妥なの? * A: ログイベントをキュ〖イングするために称タスク/充哈みスレッドがメモリを艰る * -> VisualC++のマルチスレッド脱メモリ澄瘦ライブラリは柒婶でクリティカルセクションオブジェクトを蝗って怯戮扩告している * -> TOPPERS/JSP Windowsのディスパッチャ(瓷妄スレッド)は妥滇が丸ると海瓢いているスレッドを贿めにかかる * -> メモリ澄瘦脱のクリティカルセクションを积ったままSuspendThreadされてしまい、メモリ澄瘦妥滇を叫した戮のスレッド链てがロック * -> 瓷妄スレッドもログを叫すためにメモリをとりに丸るので、瓷妄スレッドもロック * -> 瓷妄スレッドがロックされると、呵介にSuspendThreadされたヤツを弹こすスレッドがいない * -> デッドロック * 输颅 : COM奶慨侯度スレッドやコンソ〖ル瓷妄スレッドのように瓷妄スレッドのSuspendThreadの滦据にならないスレッドはロックしなくてもいい */ //=================================================== /* 侯度スレッドに涂えるデ〖タを瘦积するクラス */ class Request { public: enum tagRequestType { Confirmation = 0x00, /* ワ〖カスレッドの瓢侯澄千 (セマフォをたたくだけ) */ DeviceRead = 0x01, /* デバイスエミュレ〖ション 粕叫し拎侯 */ DeviceWrite = 0x02, /* デバイスエミュレ〖ション 今哈み拎侯 */ EventLog = 0x03, /* イベントログ流叫 */ QuitThread = 0xff /* 侯度スレッドの姜位 */ }; protected: bool blocking; bool allocated; enum tagRequestType type; unsigned long address; /* デバイス : デバイスのあるアドレス */ unsigned long size; /* 鼎奶 : storageが积つデ〖タのサイズ */ HGLOBAL storage; /* 鼎奶 : デ〖タを呈羌している挝拌のアドレス(ハンドル) */ int result; /* 鼎奶 : ブロッキング悸乖箕の手笛孟 */ HANDLE signalobject; /* 鼎奶 : ブロッキング悸乖箕のスレッドハンドル */ Request * next; /* キュ〖にするためのリンク */ static LONG RequestCount; //キュ〖につながっているリクエストの眶 static Request * top; //リクエストキュ〖の黎片 (もっとも概いリクエスト) static Request * tail; //リクエストキュ〖の琐萨 (もっとも糠しいリクエスト) static CRITICAL_SECTION cs; //怯戮キュ〖拎侯脱错副挝拌オブジェクト void connect(void) { //妥滇をキュ〖につなぐ ::EnterCriticalSection(&cs); next = NULL; if(tail != NULL) tail->next = this; tail = this; if(top == NULL) top = tail; ::LeaveCriticalSection(&cs); ::InterlockedIncrement(&RequestCount); } protected: //コンストラクタ Request(enum tagRequestType _type, bool _block, unsigned int _size = 0, void * _storage = NULL, unsigned long _address = 0) : blocking(_block), allocated(false), type(_type), address(_address), size(0), storage(NULL), result(-1), signalobject(NULL), next(NULL) { size = _size; if(size != 0) { //挝拌が回年されてない眷圭、瓢弄に澄瘦する if(_storage != NULL) storage = static_cast<HGLOBAL>(_storage); else allocate(size, false); } } public: //デストラクタ virtual ~Request(void) { //挝拌が瓢弄澄瘦されていた眷圭、撬逮を乖う if(storage != NULL && allocated) { BOOL lock; enter_system_critical_section(&lock); ::GlobalFree(storage); leave_system_critiacl_section(&lock); } } static void initialize(void) { kprintf(("Request::initialize()\n")); if(RequestCount == -1) { ::InitializeCriticalSection(&cs); RequestCount = 0; top = NULL; tail = NULL; } } static void finalize(void) { kprintf(("Request::finalize()\n")); if(RequestCount != -1) { while(top != NULL) { Request * target = top; top = top->next; delete target; } ::DeleteCriticalSection(&cs); RequestCount = -1; } } // システムをロックしないでメモリ倡庶 inline void release(void) { if(storage != NULL && allocated) { ::GlobalFree(storage); storage = 0; } } inline bool isBlockingRequest(void) const { return blocking; } inline enum tagRequestType getType(void) const { return type; } inline bool operator == (enum tagRequestType _type) const { return type == _type; } inline bool operator != (enum tagRequestType _type) const { return !(operator ==(_type)); } inline void * getStorage(void) { return reinterpret_cast<void *>(storage); } inline unsigned long getAddress(void) const { return address; } inline unsigned long getSize(void) const { return size; } inline int getResult(void) const { return result; } static inline LONG getRequestCount(void) { return RequestCount; } //挝拌の澄瘦 // _size : 涩妥とする挝拌のサイズ // realloc : 柒推を瘦积するか容か bool allocate(unsigned int _size, bool realloc = false) { unsigned long old_size; HGLOBAL old_storage; BOOL lock; FatalAssertion(type != Confirmation, "Request::allocate was performed with Confirmation Request Object."); old_size = size; old_storage = storage; enter_system_critical_section(&lock); storage = ::GlobalAlloc(GMEM_FIXED, _size); FatalAssertion(storage != NULL, "Request::allocate failed to allocate a memory block."); //涟の柒推の瘦积 および挝拌撬逮 if(old_storage != NULL) { if(realloc) ::CopyMemory(storage, old_storage, old_size); if(allocated) ::GlobalFree(old_storage); } leave_system_critiacl_section(&lock); allocated = true; size = _size; return true; } //柒推を瘦积したまま浩アロケ〖ト inline bool reallocate(unsigned int _size) { return allocate(_size, true); } //瘦积挝拌に滦する今哈み inline void set(void * data, unsigned int sz, unsigned int offset = 0) { if(size < sz) reallocate(sz + offset);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -