Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

PerfData.h

Go to the documentation of this file.
00001 /*  PerfData.h - Helpers for exposing performance counters
00002 
00003     Copyright (C) 2004 Mark Weaver
00004     Written by Mark Weaver <mark@npsl.co.uk>
00005 
00006     Part of the Open-Win32 library.
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public
00018     License along with this library; if not, write to the
00019     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020     Boston, MA  02111-1307, USA.
00021 */
00022 
00028 #ifndef OW32_PerfData_h
00029 #define OW32_PerfData_h
00030 
00031 #include <OW32/OW32libs.h>
00032 #include <OW32/windows.h>
00033 #include <winperf.h>
00034 #include <string>
00035 #include <map>
00036 #include <OW32/tstl.h>
00037 #include <OW32/XHANDLE.h>
00038 #include <OW32/SyncObjects.h>
00039 
00040 namespace OW32
00041 {
00042 
00043 class OW32_LIB_EXPORT CPerfObject;
00044 class OW32_LIB_EXPORT CPerfCounter;
00045 
00049 class OW32_LIB_EXPORT CPerfDataException
00050 {
00051 public:
00059     CPerfDataException(
00060         LPCTSTR prefix, 
00061         DWORD   error = ERROR_INTERNAL_ERROR
00062     ) :
00063         m_prefix(prefix),
00064         m_error(error)
00065     {
00066     }
00067 
00072     DWORD getWin32Error() const { return m_error; }
00073 
00077     const std::_tstring &getPrefix() const { return m_prefix; }
00078 
00082     std::_tstring getFormattedError() const;
00083 
00084 private:
00085     std::_tstring   m_prefix;
00086     DWORD           m_error;
00087 };
00088 
00089 #ifdef _MSC_VER
00090 #pragma warning(disable: 4251)
00091 #endif
00092 
00096 class OW32_LIB_EXPORT CPerfData
00097 {
00098 public:
00102     typedef DWORD ObjectId;
00103 
00107     typedef DWORD CounterId;
00108 
00112     typedef DWORD InstanceId;
00113     
00119     enum { PERF_COUNTER_STORAGE = sizeof(__int64) };
00120 
00126     CPerfData(LPCWSTR appName);
00127 
00131     ~CPerfData();
00132 
00140     void addObject(CPerfObject *object);
00141 
00148     CPerfObject *getObjectById(ObjectId objectId);
00149 
00168     DWORD collect(LPWSTR values, LPVOID *ppData, LPDWORD pBytes, LPDWORD pcObjectTypes);
00169 
00186     void activate(bool fApplication);
00187 
00204     void deactivate();
00205 
00211     void install(LPCTSTR perfCollectorPath);
00212 
00216     void uninstall();
00217 
00232     InstanceId addInstance(ObjectId objectId, LPCWSTR name,
00233         ObjectId parentObjectId = 0, InstanceId parentInstanceId = 0)
00234     {
00235         return addInstance(objectId, name, PERF_NO_UNIQUE_ID, parentObjectId, parentInstanceId);
00236     }
00237 
00253     InstanceId addInstance(ObjectId objectId, LONG uniqueID,
00254         ObjectId parentObjectId = 0, InstanceId parentInstanceId = 0)
00255     {
00256         return addInstance(objectId, NULL, uniqueID, parentObjectId, parentInstanceId);
00257     }
00258 
00268     void removeInstance(ObjectId objectId, InstanceId instanceId);
00269 
00287     __int64 *getCounter64(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0)
00288     {
00289         return (__int64 *)getCounter(objectId, counterId, instanceId);
00290     }
00291 
00309     LONG *getCounter32(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0)
00310     {
00311         return (LONG *)getCounter(objectId, counterId, instanceId);
00312     }
00313 
00331     BYTE *getCounter(ObjectId objectId, CounterId counterId, InstanceId instanceId = 0);
00332 
00352     bool lock(DWORD timeout = INFINITE);
00353 
00361     void unlock();
00362 
00363 private:
00364 
00382     InstanceId addInstance(ObjectId objectId, LPCWSTR name, LONG uniqueID,
00383         ObjectId parentObjectId, InstanceId parentInstanceId);
00384 
00388     void initialiseMMF();
00389 
00393     void computeMMFOffsets();
00394 
00398     void readCounterIndexes();
00399 
00407     void appendCounterTitle(std::wstring &data, LPCWSTR title);
00408 
00416     void appendHelpTitle(std::wstring &data, LPCWSTR title);
00417 
00421     CPerfObject *m_firstObject;
00422 
00426     CPerfObject *m_lastObject;
00427 
00431     DWORD       m_firstHelp;
00432 
00436     DWORD       m_lastHelp;
00437 
00441     DWORD       m_firstCounter;
00442     
00446     DWORD       m_lastCounter;
00447 
00451     LPCWSTR     m_appName;
00452 
00456     XHANDLE     m_hPerfData;
00457 
00464     BYTE        *m_pPerfData;
00465 
00469     typedef std::map<CPerfData::ObjectId, CPerfObject*> object_id_map_t;
00470 
00474     object_id_map_t m_objectIdMap;
00475 
00482     CEvent m_lockEvent;
00483 
00493     CEvent m_applicationEvent;
00494 
00501     bool m_fApplication;
00502 };
00503 
00504 #ifdef _MSC_VER
00505 #pragma warning(default: 4251)
00506 #endif
00507 
00508 #ifdef _MSC_VER
00509 #pragma warning(disable: 4251)
00510 #endif
00511 
00515 class OW32_LIB_EXPORT CPerfObject
00516 {
00517 public:
00530     CPerfObject(
00531         CPerfData               *perfData,
00532         CPerfData::ObjectId     objectId, 
00533         LPCWSTR                 name,
00534         LPCWSTR                 help,
00535         DWORD                   detailLevel,
00536         CPerfData::CounterId    defaultCounterId,
00537         DWORD                   maxInstances,
00538         DWORD                   maxInstanceName
00539     );
00540 
00544     DWORD addCounter(CPerfCounter *counter);
00545 
00549     void setNext(CPerfObject *next);
00550 
00554     void setTitleInfo(DWORD titleIndex, DWORD helpTitleIndex);
00555 
00562     void setPerfInstanceInfo(BYTE *firstInstance, DWORD instanceSize);
00563 
00569     void setPerfType(PERF_OBJECT_TYPE *type);
00570 
00578     bool getFreeInstance(PERF_INSTANCE_DEFINITION **instance, CPerfData::InstanceId *instanceId);
00579 
00583     DWORD getPerfInstanceIndex(CPerfData::InstanceId instanceId);
00584 
00595     BYTE *getCounter(CPerfData::InstanceId instanceId, CPerfData::CounterId counterId);
00596 
00600     void removeInstance(CPerfData::InstanceId instanceId);
00601 
00605     CPerfCounter *getCounterById(CPerfData::CounterId counterId);
00606 
00610     CPerfObject *getNext() const { return m_next; }
00611 
00615     CPerfCounter *getFirstCounter() const { return m_firstCounter; }
00616 
00620     CPerfData::ObjectId getId() const { return m_objectId; }
00621 
00625     LPCWSTR getName() const { return m_name; }
00626 
00630     LPCWSTR getHelp() const { return m_help; }
00631 
00635     DWORD getDetailLevel() const { return m_detailLevel; }
00636 
00640     CPerfData::CounterId getDefaultCounterId() const { return m_defaultCounterId; }
00641 
00647     DWORD getMaxInstances() const { return m_maxInstances; }
00648 
00652     bool singleInstance() const { return m_maxInstances == PERF_NO_INSTANCES; }
00653 
00658     DWORD getMaxInstanceName() const { return m_maxInstanceName; }
00659 
00663     DWORD getTitleIndex() const { return m_titleIndex; }
00664 
00668     DWORD getHelpTitleIndex() const { return m_helpTitleIndex; }
00669 
00679     DWORD collect(CPerfData *perfData, LPVOID *pBuffer, LPDWORD pBytes);
00680 
00684     void setCollect(bool fCollect) { m_fCollect = fCollect; }
00685 
00689     bool getCollect() const { return m_fCollect; }
00690 
00697     void checkChildDependencies(CPerfData *perfData);
00698 
00703     DWORD getCountersWithData() const { return m_countersWithData; }
00704 
00705 private:
00709     CPerfData::ObjectId         m_objectId;
00710 
00714     LPCWSTR                     m_name;
00715 
00719     LPCWSTR                     m_help;
00720 
00724     DWORD                       m_detailLevel;
00725 
00729     CPerfData::CounterId        m_defaultCounterId;
00730 
00734     DWORD                       m_maxInstances;
00735 
00739     DWORD                       m_maxInstanceName;
00740 
00744     CPerfObject                 *m_next;
00745 
00749     CPerfCounter                *m_firstCounter;
00750 
00754     CPerfCounter                *m_lastCounter;
00755 
00759     DWORD                       m_titleIndex;
00760 
00764     DWORD                       m_helpTitleIndex;
00765 
00769     BYTE                        *m_firstInstance;
00770 
00774     DWORD                       m_instanceSize;
00775 
00779     PERF_OBJECT_TYPE            *m_perfObjectType;
00780 
00784     typedef std::map<CPerfData::CounterId, CPerfCounter*> counter_id_map_t;
00785 
00786     /*
00787      * The counterId->counter map
00788      */
00789     counter_id_map_t m_counterIdMap;
00790 
00794     bool                        m_fCollect;
00795 
00801     DWORD                       m_countersWithData;
00802 };
00803 
00804 #ifdef _MSC_VER
00805 #pragma warning(default: 4251)
00806 #endif
00807 
00811 class OW32_LIB_EXPORT CPerfCounter
00812 {
00813 public:
00827     CPerfCounter(
00828         CPerfObject             *object,
00829         CPerfData::CounterId    counterId,
00830         LPCWSTR                 name,
00831         LPCWSTR                 help,
00832         DWORD                   detailLevel,
00833         DWORD                   defaultScale,
00834         DWORD                   type,
00835         CPerfData::CounterId    counterIdParent = 0
00836     );
00837     
00843     void setNext(CPerfCounter *next);
00844 
00851     void setTitleInfo(DWORD counterTitleIndex, DWORD helpTitleIndex);
00852 
00856     DWORD getIndex() const { return m_index; }
00857 
00861     CPerfData::CounterId getId() const { return m_counterId; }
00862     
00866     CPerfCounter *getNext() const { return m_next; }
00867 
00871     LPCWSTR getName() const { return m_name; }
00872 
00876     LPCWSTR getHelp() const { return m_help; }
00877 
00881     DWORD getDetailLevel() const { return m_detailLevel; }
00882 
00886     DWORD getDefaultScale() const { return m_defaultScale; }
00887 
00891     DWORD getType() const { return m_type; }
00892 
00896     CPerfData::CounterId getParentCounter() const { return m_parentCounterId; }
00897 
00901     bool shared() const { return m_parentCounterId != 0; }
00902 
00903 private:
00907     CPerfData::CounterId        m_counterId;
00908 
00912     LPCWSTR                     m_name;
00913 
00917     LPCWSTR                     m_help;
00918 
00922     DWORD                       m_detailLevel;
00923 
00927     DWORD                       m_defaultScale;
00928 
00932     DWORD                       m_type;
00933 
00937     DWORD                       m_index;
00938 
00942     CPerfCounter                *m_next;
00943 
00947     DWORD                       m_counterTitleIndex;
00948 
00952     DWORD                       m_helpTitleIndex;
00953 
00957     CPerfData::CounterId        m_parentCounterId;
00958 };
00959 
00969 #define PERF_DECLARE_MAP(appName) \
00970     extern OW32::CPerfData g_perfData_##appName;
00971 
00983 #define PERF_DEFINE_OBJECT(sym, val) \
00984     const OW32::CPerfData::ObjectId sym = (OW32::CPerfData::ObjectId)val;
00985 
00995 #define PERF_DEFINE_COUNTER(sym, val) \
00996     const OW32::CPerfData::CounterId sym = (OW32::CPerfData::CounterId)val;
00997 
01008 #define PERF_MAP_BEGIN(appName) \
01009     OW32::CPerfData g_perfData_##appName(L#appName); \
01010     class CPerfMapConstructor \
01011     { \
01012     public: \
01013         CPerfMapConstructor(OW32::CPerfData *perfData); \
01014     }; \
01015     \
01016     CPerfMapConstructor::CPerfMapConstructor(OW32::CPerfData *perfData) \
01017     {
01018 
01033 #define PERF_MAP_BEGIN_OBJECT(objectId, name, help, detailLevel, defaultCounterId, maxInstances, maxInstanceName) \
01034         { \
01035             static OW32::CPerfObject currentObject( \
01036                 perfData, objectId, L##name, L##help, detailLevel, defaultCounterId, \
01037                 static_cast<DWORD>(maxInstances), maxInstanceName);
01038 
01049 #define PERF_MAP_COUNTER(counterId, name, help, detailLevel, defaultScale, type) \
01050             { \
01051                 static OW32::CPerfCounter currentCounter( \
01052                     &currentObject, counterId, L##name, L##help, detailLevel, \
01053                     static_cast<DWORD>(defaultScale), type); \
01054             }
01055 
01073 #define PERF_MAP_COUNTER_SHARED(counterId, counterIdData, name, help, detailLevel, defaultScale, type) \
01074             { \
01075                 static OW32::CPerfCounter currentCounter( \
01076                     &currentObject, counterId, L##name, L##help, detailLevel, defaultScale, type, counterIdData); \
01077             }
01078 
01083 #define PERF_MAP_END_OBJECT() \
01084         } \
01085 
01086 
01093 #define PERF_MAP_END(appName) \
01094     } \
01095     static CPerfMapConstructor s_constructPerfData(&g_perfData_##appName);
01096 
01114 #define PERF_IMPLEMENT_COLLECTOR(appName) \
01115     extern OW32::CPerfData g_perfData_##appName; \
01116     extern "C" { \
01117     DWORD WINAPI OW32_PerfData_##appName##_Open(LPWSTR /*lpDevNames*/) \
01118     { \
01119         try \
01120         { \
01121             g_perfData_##appName.activate(false); \
01122             return ERROR_SUCCESS; \
01123         } \
01124         catch (const OW32::CPerfDataException &e) \
01125         { \
01126             return e.getWin32Error(); \
01127         } \
01128     } \
01129     \
01130     DWORD WINAPI OW32_PerfData_##appName##_Close() \
01131     { \
01132         g_perfData_##appName.deactivate(); \
01133         return ERROR_SUCCESS; \
01134     } \
01135     \
01136     DWORD WINAPI OW32_PerfData_##appName##_Collect(LPWSTR values, LPVOID *ppData, LPDWORD pBytes, LPDWORD pcObjectTypes) \
01137     { \
01138         try \
01139         { \
01140             return g_perfData_##appName.collect(values, ppData, pBytes, pcObjectTypes); \
01141         } \
01142         catch (const OW32::CPerfDataException &e) \
01143         { \
01144             return e.getWin32Error(); \
01145         } \
01146     } \
01147     }
01148 
01165 #define PERF_IMPLEMENT_COLLECTOR_REGISTRATION(appName) \
01166     extern OW32::CPerfData g_perfData_##appName; \
01167     extern "C" { \
01168     HINSTANCE ghInstance; \
01169     \
01170     BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) \
01171     { \
01172         if (dwReason == DLL_PROCESS_ATTACH) \
01173         { \
01174             ghInstance = hInstance; \
01175             DisableThreadLibraryCalls(hInstance); \
01176         } \
01177         return TRUE; \
01178     } \
01179     \
01180     STDAPI DllRegisterServer() \
01181     { \
01182         TCHAR path[MAX_PATH*2]; \
01183         if (GetModuleFileName((HMODULE)ghInstance, path, sizeof(path)/sizeof(path[0]))==0) \
01184             return HRESULT_FROM_WIN32(::GetLastError()); \
01185         try \
01186         { \
01187             g_perfData_##appName.install(path); \
01188         } \
01189         catch (const OW32::CPerfDataException &e) \
01190         { \
01191             return HRESULT_FROM_WIN32(e.getWin32Error()); \
01192         } \
01193         return S_OK; \
01194     } \
01195     \
01196     STDAPI DllUnregisterServer() \
01197     { \
01198         try \
01199         { \
01200             g_perfData_##appName.uninstall(); \
01201         } \
01202         catch (const OW32::CPerfDataException &e) \
01203         { \
01204             return HRESULT_FROM_WIN32(e.getWin32Error()); \
01205         } \
01206         return S_OK; \
01207     } \
01208     }
01209 
01210 }; // namespace OW32
01211 
01212 #endif // OW32_PerfData_h

Generated on Sun Jun 5 01:29:18 2005 for OW32 by  doxygen 1.3.9.1