PPH_GET_CLIENT_ID_NAME PhSetHandleClientIdFunction( __in PPH_GET_CLIENT_ID_NAME GetClientIdName ) { return _InterlockedExchangePointer( (PPVOID)&PhHandleGetClientIdName, GetClientIdName ); }
VOID EtUpdateGpuNodeBitMap( _In_ PRTL_BITMAP NewBitMap ) { PULONG buffer; buffer = _InterlockedExchangePointer(&EtGpuNewNodeBitMapBuffer, NewBitMap->Buffer); if (buffer) PhFree(buffer); }
static VOID InitializeInternals() { //because we are using NKTHOOKLIB_CurrentProcess and ScanMappedImages to FALSE, we are avoiding the recursion LPVOID _hNtDll = ::NktHookLib::GetRemoteModuleBaseAddress(NKTHOOKLIB_CurrentProcess, L"ntdll.dll", FALSE); if (_hNtDll != NULL) { #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ lpfn_##name __fn_##name = (lpfn_##name)::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, \ _hNtDll, # name); #define NKT_PARSE_NTAPI_VOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_PVOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_BOOLEAN NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_ULONG NKT_PARSE_NTAPI_NTSTATUS #include "NtApiDeclarations.h" #undef NKT_PARSE_NTAPI_NTSTATUS #undef NKT_PARSE_NTAPI_VOID #undef NKT_PARSE_NTAPI_PVOID #undef NKT_PARSE_NTAPI_BOOLEAN #undef NKT_PARSE_NTAPI_ULONG #if defined(_M_IX86) #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ _InterlockedExchange((long volatile*)&(NktHookLib_fn_##name), (long)(__fn_##name)); #elif defined(_M_X64) #define NKT_PARSE_NTAPI_NTSTATUS(name, _notused, _notused2) \ _InterlockedExchangePointer((void* volatile*)&(NktHookLib_fn_##name), (__fn_##name)); #endif #define NKT_PARSE_NTAPI_VOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_PVOID NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_BOOLEAN NKT_PARSE_NTAPI_NTSTATUS #define NKT_PARSE_NTAPI_ULONG NKT_PARSE_NTAPI_NTSTATUS #include "NtApiDeclarations.h" #undef NKT_PARSE_NTAPI_NTSTATUS #undef NKT_PARSE_NTAPI_VOID #undef NKT_PARSE_NTAPI_PVOID #undef NKT_PARSE_NTAPI_BOOLEAN #undef NKT_PARSE_NTAPI_ULONG //---- NktHookLib_fn_vsnprintf = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "_vsnprintf"); NktHookLib_fn_vsnwprintf = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "_vsnwprintf"); NktHookLib_fn_DbgPrint = ::NktHookLib::GetRemoteProcedureAddress(NKTHOOKLIB_CurrentProcess, _hNtDll, "DbgPrint"); } #if defined(_M_IX86) _InterlockedExchange((long volatile*)&hNtDll, (long)_hNtDll); #elif defined(_M_X64) _InterlockedExchangePointer((volatile PVOID*)&hNtDll, _hNtDll); #endif return; }
/** * Sets a wake event, unblocking all queued wait blocks. * * \param WakeEvent A wake event. * \param WaitBlock A wait block for a cancelled wait, otherwise * NULL. */ VOID FASTCALL PhfSetWakeEvent( __inout PPH_QUEUED_LOCK WakeEvent, __inout_opt PPH_QUEUED_WAIT_BLOCK WaitBlock ) { PPH_QUEUED_WAIT_BLOCK waitBlock; PPH_QUEUED_WAIT_BLOCK nextWaitBlock; // Pop all waiters and unblock them. waitBlock = _InterlockedExchangePointer((PPVOID)&WakeEvent->Value, NULL); while (waitBlock) { nextWaitBlock = waitBlock->Next; PhpUnblockQueuedWaitBlock(waitBlock); waitBlock = nextWaitBlock; } if (WaitBlock) { // We're cancelling a wait; the thread called this function instead // of PhfWaitForWakeEvent. This will remove all waiters from // the list. However, we may not have popped and unblocked the // cancelled wait block ourselves. Another thread may have popped all // waiters but not unblocked them yet at this point: // // 1. This thread: calls PhfQueueWakeEvent. // 2. This thread: code determines that the wait should be cancelled. // 3. Other thread: calls PhfSetWakeEvent and pops our wait block off. // It hasn't unblocked any wait blocks yet. // 4. This thread: calls PhfSetWakeEvent. Since all wait blocks have // been popped, we don't do anything. The caller function exits, // making our wait block invalid. // 5. Other thread: tries to unblock our wait block. Anything could // happen, since our caller already returned. // // The solution is to (always) wait for an unblock. Note that the check below // for the spinning flag is not required, but it is a small optimization. // If the wait block has been unblocked (i.e. the spinning flag is cleared), // then there's no danger. if (WaitBlock->Flags & PH_QUEUED_WAITER_SPINNING) PhpBlockOnQueuedWaitBlock(WaitBlock, FALSE, NULL); } }
/** * Removes and frees objects from the to-free list. */ NTSTATUS PhpDeferDeleteObjectRoutine( __in PVOID Parameter ) { PPH_OBJECT_HEADER objectHeader; PPH_OBJECT_HEADER nextObjectHeader; // Clear the list and obtain the first object to free. objectHeader = _InterlockedExchangePointer(&PhObjectNextToFree, NULL); while (objectHeader) { nextObjectHeader = objectHeader->NextToFree; PhpFreeObject(objectHeader); objectHeader = nextObjectHeader; } return STATUS_SUCCESS; }
void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) { return _InterlockedExchangePointer(Target, Value); }
CKrkr2::XP3ExtractionFilterFunc CKrkr2Lite::SetXP3ExtractionFilter(CKrkr2::XP3ExtractionFilterFunc Filter) { return (CKrkr2::XP3ExtractionFilterFunc)_InterlockedExchangePointer(&m_ExtractionFilter, Filter); }
static VOID NTAPI ProcessesUpdatedCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { static ULONG runCount = 0; // MUST keep in sync with runCount in process provider DOUBLE elapsedTime; // total GPU node elapsed time in micro-seconds ULONG i; PLIST_ENTRY listEntry; FLOAT maxNodeValue = 0; PET_PROCESS_BLOCK maxNodeBlock = NULL; // Update global statistics. EtpUpdateSegmentInformation(NULL); EtpUpdateNodeInformation(NULL); elapsedTime = (DOUBLE)EtClockTotalRunningTimeDelta.Delta * 10000000 / EtClockTotalRunningTimeFrequency.QuadPart; if (elapsedTime != 0) EtGpuNodeUsage = (FLOAT)(EtGpuTotalRunningTimeDelta.Delta / (elapsedTime * EtGpuNodeBitMapBitsSet)); else EtGpuNodeUsage = 0; if (EtGpuNodeUsage > 1) EtGpuNodeUsage = 1; // Do the update of the node bitmap if needed. if (EtGpuNewNodeBitMapBuffer) { PULONG newBuffer; newBuffer = _InterlockedExchangePointer(&EtGpuNewNodeBitMapBuffer, NULL); if (newBuffer) { PhFree(EtGpuNodeBitMap.Buffer); EtGpuNodeBitMap.Buffer = newBuffer; EtGpuNodeBitMapBuffer = newBuffer; EtGpuNodeBitMapBitsSet = RtlNumberOfSetBits(&EtGpuNodeBitMap); EtSaveGpuMonitorSettings(); } } // Update per-process statistics. // Note: no lock is needed because we only ever modify the list on this same thread. //@@HTK listEntry = EtProcessBlockListHead.Flink; while (listEntry != &EtProcessBlockListHead) { PET_PROCESS_BLOCK block; block = CONTAINING_RECORD(listEntry, ET_PROCESS_BLOCK, ListEntry); EtpUpdateSegmentInformation(block); EtpUpdateNodeInformation(block); if (elapsedTime != 0) { block->GpuNodeUsage = (FLOAT)(block->GpuRunningTimeDelta.Delta / (elapsedTime * EtGpuNodeBitMapBitsSet)); if (block->GpuNodeUsage > 1) block->GpuNodeUsage = 1; } if (maxNodeValue < block->GpuNodeUsage) { maxNodeValue = block->GpuNodeUsage; maxNodeBlock = block; } listEntry = listEntry->Flink; } // Update history buffers. if (runCount != 0) { PhAddItemCircularBuffer_FLOAT(&EtGpuNodeHistory, EtGpuNodeUsage); PhAddItemCircularBuffer_ULONG(&EtGpuDedicatedHistory, (ULONG)(EtGpuDedicatedUsage / PAGE_SIZE)); PhAddItemCircularBuffer_ULONG(&EtGpuSharedHistory, (ULONG)(EtGpuSharedUsage / PAGE_SIZE)); for (i = 0; i < EtGpuTotalNodeCount; i++) { FLOAT usage; usage = (FLOAT)(EtGpuNodesTotalRunningTimeDelta[i].Delta / elapsedTime); if (usage > 1) usage = 1; PhAddItemCircularBuffer_FLOAT(&EtGpuNodesHistory[i], usage); } if (maxNodeBlock) { PhAddItemCircularBuffer_ULONG(&EtMaxGpuNodeHistory, HandleToUlong(maxNodeBlock->ProcessItem->ProcessId)); PhAddItemCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, maxNodeBlock->GpuNodeUsage); PhReferenceProcessRecordForStatistics(maxNodeBlock->ProcessItem->Record); } else { PhAddItemCircularBuffer_ULONG(&EtMaxGpuNodeHistory, 0); PhAddItemCircularBuffer_FLOAT(&EtMaxGpuNodeUsageHistory, 0); } } runCount++; }