VOID EtDiskProcessDiskEvent( __in PET_ETW_DISK_EVENT Event ) { PETP_DISK_PACKET packet; if (!EtDiskEnabled) return; packet = PhAllocateFromFreeList(&EtDiskPacketFreeList); memcpy(&packet->Event, Event, sizeof(ET_ETW_DISK_EVENT)); packet->FileName = EtFileObjectToFileName(Event->FileObject); RtlInterlockedPushEntrySList(&EtDiskPacketListHead, &packet->ListEntry); }
FORCEINLINE PPH_WORK_QUEUE_ITEM PhpCreateWorkQueueItem( _In_ PUSER_THREAD_START_ROUTINE Function, _In_opt_ PVOID Context, _In_opt_ PPH_WORK_QUEUE_ITEM_DELETE_FUNCTION DeleteFunction ) { PPH_WORK_QUEUE_ITEM workQueueItem; workQueueItem = PhAllocateFromFreeList(&PhWorkQueueItemFreeList); workQueueItem->Function = Function; workQueueItem->Context = Context; workQueueItem->DeleteFunction = DeleteFunction; return workQueueItem; }
/** * Allocates storage for an object. * * \param ObjectType The type of the object. * \param ObjectSize The size of the object, excluding the header. * \param Flags A combination of flags specifying how the object is to be allocated. */ PPH_OBJECT_HEADER PhpAllocateObject( __in PPH_OBJECT_TYPE ObjectType, __in SIZE_T ObjectSize, __in ULONG Flags ) { PPH_OBJECT_HEADER objectHeader; if (ObjectType->Flags & PHOBJTYPE_USE_FREE_LIST) { #ifdef PHOBJ_STRICT_CHECKS if (ObjectType->FreeList.Size != PhpAddObjectHeaderSize(ObjectSize)) PhRaiseStatus(STATUS_INVALID_PARAMETER); #else assert(ObjectType->FreeList.Size == PhpAddObjectHeaderSize(ObjectSize)); #endif objectHeader = PhAllocateFromFreeList(&ObjectType->FreeList); objectHeader->Flags = PHOBJ_FROM_TYPE_FREE_LIST; REF_STAT_UP(RefObjectsAllocatedFromTypeFreeList); } else if (ObjectSize <= PHOBJ_SMALL_OBJECT_SIZE) { objectHeader = PhAllocateFromFreeList(&PhObjectSmallFreeList); objectHeader->Flags = PHOBJ_FROM_SMALL_FREE_LIST; REF_STAT_UP(RefObjectsAllocatedFromSmallFreeList); } else { objectHeader = PhAllocate(PhpAddObjectHeaderSize(ObjectSize)); objectHeader->Flags = 0; REF_STAT_UP(RefObjectsAllocated); } return objectHeader; }
/** * Queues a work item to a work queue. * * \param WorkQueue A work queue object. * \param Function A function to execute. * \param Context A user-defined value to pass to the function. */ VOID PhQueueItemWorkQueue( __inout PPH_WORK_QUEUE WorkQueue, __in PTHREAD_START_ROUTINE Function, __in_opt PVOID Context ) { PPH_WORK_QUEUE_ITEM workQueueItem; workQueueItem = PhAllocateFromFreeList(&PhWorkQueueItemFreeList); PhpInitializeWorkQueueItem(workQueueItem, Function, Context); // Enqueue the work item. PhAcquireQueuedLockExclusive(&WorkQueue->QueueLock); InsertTailList(&WorkQueue->QueueListHead, &workQueueItem->ListEntry); PhReleaseQueuedLockExclusive(&WorkQueue->QueueLock); // Signal the semaphore once to let a worker thread continue. NtReleaseSemaphore(WorkQueue->SemaphoreHandle, 1, NULL); PHLIB_INC_STATISTIC(WqWorkItemsQueued); // Check if all worker threads are currently busy, // and if we can create more threads. if ( WorkQueue->BusyThreads == WorkQueue->CurrentThreads && WorkQueue->CurrentThreads < WorkQueue->MaximumThreads ) { // Lock and re-check. PhAcquireQueuedLockExclusive(&WorkQueue->StateLock); if (WorkQueue->CurrentThreads < WorkQueue->MaximumThreads) { PhpCreateWorkQueueThread(WorkQueue); } PhReleaseQueuedLockExclusive(&WorkQueue->StateLock); } }