/*++

Copyright (c) Microsoft Corporation. All rights reserved. 

You may only use this code if you agree to the terms of the Windows Research Kernel Source Code License agreement (see License.txt).
If you do not agree to the terms, do not use the code.


Module Name:

    perf.h

Abstract:

    This module contains the macro definition of all performance hooks.

--*/

#ifndef _PERF_H
#define _PERF_H

#include <wmistr.h>
#include <ntwmi.h>
#include <ntperf.h>

extern PERFINFO_GROUPMASK *PPerfGlobalGroupMask;
extern const PERFINFO_HOOK_HANDLE PerfNullHookHandle;
#define PERF_NULL_HOOK_HANDLE (PerfNullHookHandle)

typedef enum _PERFINFO_START_LOG_LOCATION {
    PERFINFO_START_LOG_AT_BOOT,
    PERFINFO_START_LOG_POST_BOOT,
    PERFINFO_START_LOG_FROM_GLOBAL_LOGGER
} PERFINFO_START_LOG_LOCATION, *PPERFINFO_START_LOG_LOCATION;

typedef struct _PERFINFO_ENTRY_TABLE {
    PVOID *Table;
    LONG NumberOfEntries;
} PERFINFO_ENTRY_TABLE, *PPERFINFO_ENTRY_TABLE;

NTSTATUS
PerfInfoStartLog (
    PERFINFO_GROUPMASK *pGroupMask,
    PERFINFO_START_LOG_LOCATION StartLogLocation
    );

NTSTATUS
PerfInfoStopLog (
    VOID
    );

NTSTATUS
PerfInfoLogFileName(
    PVOID  FileObject,
    PUNICODE_STRING SourceString
    );

ULONG
PerfInfoCalcHashValue(
    PVOID Key,
    ULONG Len
    );

BOOLEAN
PerfInfoAddToFileHash(
    PPERFINFO_ENTRY_TABLE HashTable,
    PVOID ObjectPointer
    );

VOID
ObPerfHandleTableWalk (
    PEPROCESS Process,
    PPERFINFO_ENTRY_TABLE HashTable
    );

VOID
FASTCALL
PerfProfileInterrupt(
    IN KPROFILE_SOURCE Source,
    IN PVOID InstructionPointer
    );

VOID
PerfInfoFlushProfileCache(
    VOID
    );

VOID
FASTCALL
PerfInfoLogInterrupt(
    IN PVOID ServiceRoutine,
    IN ULONG RetVal,
    IN ULONGLONG InitialTime
    );

#define PERFINFO_IS_ANY_GROUP_ON() (PPerfGlobalGroupMask != NULL)

#define PERFINFO_IS_GROUP_ON(_Group) PerfIsGroupOnInGroupMask(_Group, PPerfGlobalGroupMask)

#define PERF_FINISH_HOOK(_HookHandle) WmiReleaseKernelBuffer((_HookHandle).WmiBufferHeader);

NTSTATUS
PerfInfoReserveBytes(
    PPERFINFO_HOOK_HANDLE Hook,
    USHORT HookId,
    ULONG BytesToReserve
    );

NTSTATUS
PerfInfoLogBytes(
    USHORT HookId,
    PVOID Data,
    ULONG NumBytes
    );

NTSTATUS
PerfInfoLogBytesAndUnicodeString(
    USHORT HookId,
    PVOID SourceData,
    ULONG SourceByteCount,
    PUNICODE_STRING String
    );

//
// Macros for TimeStamps
//
#if defined(_X86_)
__inline
LONGLONG
PerfGetCycleCount(
    )
{
    __asm{
        RDTSC
    }
}
#elif defined(_AMD64_)
__inline
LONGLONG
PerfGetCycleCount(
            )
{
    return ReadTimeStampCounter();
}
#else
#error "perf: a target architecture must be defined."
#endif

#define PerfTimeStamp(TS) TS.QuadPart = (*WmiGetCpuClock)();

//
// Macros used in \nt\base\ntos\io\iomgr\parse.c
//
#define PERFINFO_LOG_FILE_CREATE(FileObject, CompleteName)                                              \
    if (PERFINFO_IS_GROUP_ON(PERF_FILENAME_ALL)){                                                       \
        PerfInfoLogFileName(FileObject, CompleteName);                                                  \
    }

// Macros used in \nt\base\ntos\mm\creasect.c
//
#define PERFINFO_SECTION_CREATE(ControlArea)

//
// Macros used in \nt\base\ntos\ps\psquery.c
//

#define PERFINFO_CONVERT_TO_GUI_THREAD(EThread)                                                         \
    if (PERFINFO_IS_GROUP_ON(PERF_MEMORY)) {                                                            \
        PERFINFO_THREAD_INFORMATION _ThreadInfo;                                                        \
        _ThreadInfo.ProcessId = HandleToUlong((EThread)->Cid.UniqueProcess);                            \
        _ThreadInfo.ThreadId = HandleToUlong((EThread)->Cid.UniqueThread);                              \
        _ThreadInfo.StackBase = (EThread)->Tcb.StackBase;                                               \
        _ThreadInfo.StackLimit = (EThread)->Tcb.StackLimit;                                             \
        _ThreadInfo.UserStackBase = 0;                                                                  \
        _ThreadInfo.UserStackLimit = 0;                                                                 \
        _ThreadInfo.StartAddr = 0;                                                                      \
        _ThreadInfo.Win32StartAddr = 0;                                                                 \
        _ThreadInfo.WaitMode = -1;                                                                      \
        PerfInfoLogBytes(                                                                               \
            PERFINFO_LOG_TYPE_CONVERTTOGUITHREAD,                                                       \
            &_ThreadInfo,                                                                               \
            sizeof(_ThreadInfo)                                                                         \
            );                                                                                          \
    }

//
// Macros used in \NT\PRIVATE\NTOS\ps\psdelete.c
//

#define PERFINFO_PROCESS_DELETE(EProcess)                                                               \
    WmiTraceProcess(EProcess, FALSE);

#define PERFINFO_THREAD_DELETE(EThread)                                                                 \
    WmiTraceThread(EThread, NULL, FALSE);
//
// Macros used in \NT\PRIVATE\NTOS\ps\create.c
//

#define PERFINFO_PROCESS_CREATE(EProcess)                                                               \
    WmiTraceProcess(EProcess, TRUE);

#define PERFINFO_THREAD_CREATE(EThread, ITeb)                                                           \
    WmiTraceThread(EThread, ITeb, TRUE);                                                                \

#define PERFINFO_MMINIT_START()
#define PERFINFO_IS_LOGGING_TO_PERFMEM() (FALSE)

#define PERFINFO_ADD_OBJECT_TO_ALLOCATED_TYPE_LIST(CreatorInfo, ObjectType)
#define PERFINFO_ADDPOOLPAGE(CheckType, PoolIndex, Addr, PoolDesc)
#define PERFINFO_ADDTOWS(PageFrame, Address, Pid)
#define PERFINFO_BIGFOOT_REPLACEMENT_CLAIMS(WorkingSetList, WsInfo)
#define PERFINFO_BIGFOOT_REPLACEMENT_FAULTS(WorkingSetList, WsInfo)
#define PERFINFO_BIGPOOLALLOC(Type, PTag, NumBytes, Addr)
#define PERFINFO_CLEAR_OBJECT(CurrentState, Object)
#define PERFINFO_DECLARE_OB_ENUMERATE_ALLOCATED_OBJECTS_BY_TYPE()
#define PERFINFO_DECLARE_OBJECT(Object)
#define PERFINFO_DECREFCNT(PageFrame, Flag, Type)
#define PERFINFO_DEFINE_OB_ENUMERATE_ALLOCATED_OBJECTS_BY_TYPE()
#define PERFINFO_DELETE_STACK(PointerPte, NumberOfPtes)
#define PERFINFO_DETACH_PROCESS(KThread, KProcess)
#define PERFINFO_DO_PAGEFAULT_CLUSTERING() 1
#define PERFINFO_DRIVER_INTENTIONAL_DELAY()
#define PERFINFO_DRIVER_STACKTRACE()
#define PERFINFO_EXALLOCATEPOOLWITHTAG_DECL()
#define PERFINFO_EXFREEPOOLWITHTAG_DECL()
#define PERFINFO_FAULT_NOTIFICATION(Address, TrapInfo)
#define PERFINFO_FREEPOOL(Addr)
#define PERFINFO_FREEPOOLPAGE(CheckType, PoolIndex, Addr, PoolDesc)
#define PERFINFO_GET_PAGE_INFO(PointerPte)
#define PERFINFO_GET_PAGE_INFO_REPLACEMENT(PointerPte)
#define PERFINFO_GET_PAGE_INFO_WITH_DECL(PointerPte)
#define PERFINFO_GROW_STACK(EThread)
#define PERFINFO_HIBER_ADJUST_PAGECOUNT_FOR_BBTBUFFER(pPageCount)
#define PERFINFO_HIBER_DUMP_PERF_BUFFER()
#define PERFINFO_HIBER_HANDLE_BBTBUFFER_RANGE(HiberContext)
#define PERFINFO_HIBER_PAUSE_LOGGING()
#define PERFINFO_HIBER_REINIT_TRACE()
#define PERFINFO_HIBER_START_LOGGING()
#define PERFINFO_HIVECELL_REFERENCE_FLAT(Hive, pcell, Cell)
#define PERFINFO_HIVECELL_REFERENCE_PAGED(Hive, pcell, Cell, Type, Map)
#define PERFINFO_IMAGE_LOAD(LdrDataTableEntry)
#define PERFINFO_IMAGE_UNLOAD(Address)
#define PERFINFO_INIT_KTHREAD(KThread)
#define PERFINFO_INIT_TRACEFLAGS(OptnString, SpecificOptn)
#define PERFINFO_INITIALIZE_OBJECT_ALLOCATED_TYPE_LIST_HEAD(NewObjectType)
#define PERFINFO_INSERT_FRONT_STANDBY(Page)
#define PERFINFO_INSERTINLIST(Page, ListHead)
#define PERFINFO_INSWAP_PROCESS(OutProcess)
#define PERFINFO_LOG_MARK(PMARK)
#define PERFINFO_LOG_MARK_SPRINTF(PMARK, VARIABLE)
#define PERFINFO_LOG_WS_REMOVAL(Type, WsInfo)
#define PERFINFO_LOG_WS_REPLACEMENT(WsInfo)
#define PERFINFO_MOD_PAGE_WRITER3()
#define PERFINFO_MUNG_FILE_OBJECT_TYPE_INITIALIZER(init)
#define PERFINFO_PAGE_INFO_DECL()
#define PERFINFO_PAGE_INFO_REPLACEMENT_DECL()
#define PERFINFO_POOL_ALLOC_COMMON(Type, PTag, NumBytes)
#define PERFINFO_POOLALLOC(Type, PTag, NumBytes)
#define PERFINFO_POOLALLOC_ADDR(Addr)
#define PERFINFO_POOLALLOC_EARLYEXIT()
#define PERFINFO_POWER_BATTERY_LIFE_INFO(_RemainingCapacity, _Rate)
#define PERFINFO_POWER_IDLE_STATE_CHANGE(_PState, _Direction)
#define PERFINFO_PRIVATE_COPY_ON_WRITE(CopyFrom, PAGE_SIZE)
#define PERFINFO_PRIVATE_PAGE_DEMAND_ZERO(VirtualAddress)
#define PERFINFO_REG_DELETE_KEY(KeyControlBlock)
#define PERFINFO_REG_DELETE_VALUE(KeyControlBlock, ValueName)
#define PERFINFO_REG_DUMP_CACHE()
#define PERFINFO_REG_ENUM_KEY(KeyControlBlock, Index)
#define PERFINFO_REG_ENUM_VALUE(KeyControlBlock, Index)
#define PERFINFO_REG_KCB_CREATE(kcb)
#define PERFINFO_REG_NOTIFY(NotifiedKCB, ModifiedKCB)
#define PERFINFO_REG_PARSE(kcb, RemainingName)
#define PERFINFO_REG_QUERY_KEY(KeyControlBlock)
#define PERFINFO_REG_QUERY_MULTIVALUE(KeyControlBlock, CurrentName)
#define PERFINFO_REG_QUERY_VALUE(KeyControlBlock, ValueName)
#define PERFINFO_REG_SET_VALUE_DECL()
#define PERFINFO_REG_SET_VALUE(KeyControlBlock)
#define PERFINFO_REG_SET_VALUE_DONE(ValueName)
#define PERFINFO_REG_SET_VALUE_EXIST()
#define PERFINFO_REG_SET_VALUE_NEW()
#define PERFINFO_REGPARSE(kcb, RemainingName)
#define PERFINFO_REGPARSE_END(status)
#define PERFINFO_REMOVE_OBJECT_FROM_ALLOCATED_TYPE_LIST(CreatorInfo, ObjectHeader)
#define PERFINFO_SECTION_CREATE1(File)
#define PERFINFO_SEGMENT_DELETE(FileName)
#define PERFINFO_SHUTDOWN_LOG_LAST_MEMORY_SNAPSHOT()
#define PERFINFO_SHUTDOWN_DUMP_PERF_BUFFER()
#define PERFINFO_SIGNAL_OBJECT(CurrentState, Object)
#define PERFINFO_SOFTFAULT(PageFrame, Address, Type)
#define PERFINFO_STACKWALK_THRESHHOLD_CM_DECL
#define PERFINFO_STACKWALK_THRESHHOLD_DECL
#define PERFINFO_UNLINKFREEPAGE(Index, Location)
#define PERFINFO_UNLINKPAGE(Index, Location)
#define PERFINFO_UNMUNG_FILE_OBJECT_TYPE_INITIALIZER(init)
#define PERFINFO_UNWAIT_OBJECT(Object, Status)
#define PERFINFO_UNWAIT_OBJECTS(Object, CountIn, WaitType, WaitStatus)
#define PERFINFO_WAIT_ON_OBJECT(Object)
#define PERFINFO_WAIT_ON_OBJECTS(Object, CountIn, WaitType)
#define PERFINFO_WAITLOGGED_DECL
#define PERFINFO_WSMANAGE_ACTUALTRIM(Trim)
#define PERFINFO_WSMANAGE_CHECK()
#define PERFINFO_WSMANAGE_DECL()
#define PERFINFO_WSMANAGE_DUMPENTRIES()
#define PERFINFO_WSMANAGE_DUMPENTRIES_CLAIMS()
#define PERFINFO_WSMANAGE_DUMPENTRIES_FAULTS()
#define PERFINFO_WSMANAGE_DUMPWS(VmSupport, SampledAgeCounts)
#define PERFINFO_WSMANAGE_FINALACTION(TrimAction)
#define PERFINFO_WSMANAGE_LOGINFO_CLAIMS(TrimAction)
#define PERFINFO_WSMANAGE_LOGINFO_FAULTS(TrimAction)
#define PERFINFO_WSMANAGE_STARTLOG()
#define PERFINFO_WSMANAGE_STARTLOG_CLAIMS()
#define PERFINFO_WSMANAGE_STARTLOG_FAULTS()
#define PERFINFO_WSMANAGE_TOTRIM(Trim)
#define PERFINFO_WSMANAGE_TRIMACTION(TrimAction)
#define PERFINFO_WSMANAGE_TRIMEND_CLAIMS(Criteria)
#define PERFINFO_WSMANAGE_TRIMEND_FAULTS(Criteria)
#define PERFINFO_WSMANAGE_TRIMWS(Process, SessionSpace, VmSupport)
#define PERFINFO_WSMANAGE_TRIMWS_CLAIMINFO(VmSupport)
#define PERFINFO_WSMANAGE_TRIMWS_CLAIMINFO(VmSupport)
#define PERFINFO_WSMANAGE_WAITFORWRITER_CLAIMS()
#define PERFINFO_WSMANAGE_WAITFORWRITER_FAULTS()
#define PERFINFO_WSMANAGE_WILLTRIM(ReductionGoal, FreeGoal)
#define PERFINFO_WSMANAGE_WILLTRIM_CLAIMS(Criteria)
#define PERFINFO_WSMANAGE_WILLTRIM_FAULTS(Criteria)
#define PERF_BRANCH_TRACING_OFF_KD()
#define PERF_BRANCH_TRACING_ON_KD()
#define PERF_PF_MODLOAD_DECL()
#define PERF_PF_MODLOAD_SAVE()
#define PERF_PF_MODLOAD_RESTORE()
#define PERF_PF_SANITIZE_CONTEXT(Context)
#define PERF_BRANCH_TRACING_BREAKPOINT(ExceptionRecord, TrapFrame)
#define PERF_ASSERT_TRACING_OFF()
#define PERF_IS_BRANCH_TRACING_ON()
#define PERFINFO_LOG_PREFETCH_BEGIN_TRACE(ScenarioId, ScenarioType, Process)
#define PERFINFO_LOG_PREFETCH_END_TRACE(ScenarioId, ScenarioType, Process, Status)
#define PERFINFO_LOG_PREFETCH_SECTIONS(PrefetchHeader, PrefetchType, PagesToPrefetch)
#define PERFINFO_LOG_PREFETCH_SECTIONS_END(PrefetchHeader, Status, PagesRequested)
#define PERFINFO_LOG_PREFETCH_METADATA(PrefetchHeader)
#define PERFINFO_LOG_PREFETCH_METADATA_END(PrefetchHeader, Status)
#define PERFINFO_LOG_PREFETCH_SCENARIO(PrefetchHeader, ScenarioId, ScenarioType)
#define PERFINFO_LOG_PREFETCH_SCENARIO_END(PrefetchHeader, Status)
#define PERFINFO_LOG_PREFETCH_REQUEST(RequestId, NumLists, RequestLists)
#define PERFINFO_LOG_PREFETCH_READLIST(RequestId, ReadList)
#define PERFINFO_LOG_PREFETCH_READ(FileObject, Offset, ByteCount)

#endif  // PERF_H

