You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
7.0 KiB
242 lines
7.0 KiB
/*++
|
|
|
|
Copyright (c) 1998-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
thrdpool.h
|
|
|
|
Abstract:
|
|
|
|
This module contains public declarations for the thread pool package.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _THRDPOOL_H_
|
|
#define _THRDPOOL_H_
|
|
|
|
|
|
//
|
|
// Pointer to a thread pool worker function.
|
|
//
|
|
|
|
typedef union _UL_WORK_ITEM *PUL_WORK_ITEM;
|
|
|
|
typedef
|
|
VOID
|
|
(*PUL_WORK_ROUTINE)(
|
|
IN PUL_WORK_ITEM pWorkItem
|
|
);
|
|
|
|
|
|
//
|
|
// A work item. A work item may only appear on the work queue once.
|
|
//
|
|
|
|
typedef union _UL_WORK_ITEM
|
|
{
|
|
DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) ULONGLONG Alignment;
|
|
|
|
struct
|
|
{
|
|
SLIST_ENTRY QueueListEntry; // Next pointer
|
|
PUL_WORK_ROUTINE pWorkRoutine; // Callback routine
|
|
};
|
|
|
|
} UL_WORK_ITEM, *PUL_WORK_ITEM;
|
|
|
|
//
|
|
// We have to be sure that the DriverContext (PVOID [4]) in the IRP is
|
|
// big enough to hold both the process pointer and a UL_WORK_ITEM.
|
|
//
|
|
|
|
C_ASSERT(FIELD_OFFSET(UL_WORK_ITEM, pWorkRoutine)
|
|
<= (4 - 2) * sizeof(PVOID));
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
NTSTATUS
|
|
UlInitializeThreadPool(
|
|
IN USHORT ThreadsPerCpu
|
|
);
|
|
|
|
VOID
|
|
UlTerminateThreadPool(
|
|
VOID
|
|
);
|
|
|
|
//
|
|
// One-time initialization of a UL_WORK_ITEM. Note that UlpThreadPoolWorker
|
|
// will reinitialize the workitem just before calling pWorkRoutine(), so
|
|
// this only needs to be done when the UL_WORK_ITEM (or enclosing struct)
|
|
// is first created. We need this so that we can check that a workitem is
|
|
// not being queued when it is already on the queue---a catastrophic error.
|
|
//
|
|
|
|
#if DBG
|
|
// Use non-zero values to ensure that item is properly initialized
|
|
// and not just zero by coincidence
|
|
# define WORK_ITEM_INIT_LIST_ENTRY ((PSLIST_ENTRY) 0xda7a)
|
|
# define WORK_ITEM_INIT_ROUTINE ((PUL_WORK_ROUTINE) 0xc0de)
|
|
#else
|
|
// Use zero for efficiency
|
|
# define WORK_ITEM_INIT_LIST_ENTRY NULL
|
|
# define WORK_ITEM_INIT_ROUTINE NULL
|
|
#endif
|
|
|
|
__inline
|
|
VOID
|
|
UlInitializeWorkItem(
|
|
IN PUL_WORK_ITEM pWorkItem)
|
|
{
|
|
pWorkItem->QueueListEntry.Next = WORK_ITEM_INIT_LIST_ENTRY;
|
|
pWorkItem->pWorkRoutine = WORK_ITEM_INIT_ROUTINE;
|
|
}
|
|
|
|
__inline
|
|
BOOLEAN
|
|
UlIsInitializedWorkItem(
|
|
IN PUL_WORK_ITEM pWorkItem)
|
|
{
|
|
return (BOOLEAN)(WORK_ITEM_INIT_LIST_ENTRY == pWorkItem->QueueListEntry.Next
|
|
&& WORK_ITEM_INIT_ROUTINE == pWorkItem->pWorkRoutine);
|
|
}
|
|
|
|
VOID
|
|
UlQueueWorkItem(
|
|
IN PUL_WORK_ITEM pWorkItem,
|
|
IN PUL_WORK_ROUTINE pWorkRoutine,
|
|
IN PCSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_QUEUE_WORK_ITEM( pWorkItem, pWorkRoutine ) \
|
|
UlQueueWorkItem( \
|
|
pWorkItem, \
|
|
pWorkRoutine, \
|
|
__FILE__, (USHORT) __LINE__ \
|
|
)
|
|
|
|
//
|
|
// Store a WORK_ITEM inside IRP::Tail.Overlay.DriverContext (array of 4 PVOIDs)
|
|
// Ensure that it's correctly aligned for the platform
|
|
//
|
|
|
|
#ifdef _WIN64
|
|
|
|
// DriverContext[1] is 16-byte aligned
|
|
|
|
C_ASSERT(((1 * sizeof(PVOID) + FIELD_OFFSET(IRP, Tail.Overlay.DriverContext))
|
|
& (MEMORY_ALLOCATION_ALIGNMENT - 1)
|
|
) == 0);
|
|
|
|
#define UL_PROCESS_FROM_IRP( _irp ) \
|
|
(*(PEPROCESS*)&((_irp)->Tail.Overlay.DriverContext[0]))
|
|
|
|
#define UL_MDL_FROM_IRP( _irp ) \
|
|
(*(PMDL*)&((_irp)->Tail.Overlay.DriverContext[0]))
|
|
|
|
#define UL_WORK_ITEM_FROM_IRP( _irp ) \
|
|
(PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[1])
|
|
|
|
#define UL_WORK_ITEM_TO_IRP( _workItem ) \
|
|
CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[1])
|
|
|
|
#else // !_WIN64
|
|
|
|
// DriverContext[0] is 8-byte aligned
|
|
|
|
C_ASSERT(((0 * sizeof(PVOID) + FIELD_OFFSET(IRP, Tail.Overlay.DriverContext))
|
|
& (MEMORY_ALLOCATION_ALIGNMENT - 1)
|
|
) == 0);
|
|
|
|
#define UL_PROCESS_FROM_IRP( _irp ) \
|
|
(*(PEPROCESS*)&((_irp)->Tail.Overlay.DriverContext[3]))
|
|
|
|
#define UL_MDL_FROM_IRP( _irp ) \
|
|
(*(PMDL*)&((_irp)->Tail.Overlay.DriverContext[3]))
|
|
|
|
#define UL_WORK_ITEM_FROM_IRP( _irp ) \
|
|
(PUL_WORK_ITEM)&((_irp)->Tail.Overlay.DriverContext[0])
|
|
|
|
#define UL_WORK_ITEM_TO_IRP( _workItem ) \
|
|
CONTAINING_RECORD( (_workItem), IRP, Tail.Overlay.DriverContext[0])
|
|
|
|
#endif // !_WIN64
|
|
|
|
VOID
|
|
UlQueueSyncItem(
|
|
IN PUL_WORK_ITEM pWorkItem,
|
|
IN PUL_WORK_ROUTINE pWorkRoutine,
|
|
IN PCSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_QUEUE_SYNC_ITEM( pWorkItem, pWorkRoutine ) \
|
|
UlQueueSyncItem( \
|
|
pWorkItem, \
|
|
pWorkRoutine, \
|
|
__FILE__, __LINE__ \
|
|
)
|
|
|
|
VOID
|
|
UlQueueWaitItem(
|
|
IN PUL_WORK_ITEM pWorkItem,
|
|
IN PUL_WORK_ROUTINE pWorkRoutine,
|
|
IN PCSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_QUEUE_WAIT_ITEM( pWorkItem, pWorkRoutine ) \
|
|
UlQueueWaitItem( \
|
|
pWorkItem, \
|
|
pWorkRoutine, \
|
|
__FILE__, __LINE__ \
|
|
)
|
|
|
|
VOID
|
|
UlQueueHighPriorityItem(
|
|
IN PUL_WORK_ITEM pWorkItem,
|
|
IN PUL_WORK_ROUTINE pWorkRoutine,
|
|
IN PCSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_QUEUE_HIGH_PRIORITY_ITEM( pWorkItem, pWorkRoutine ) \
|
|
UlQueueHighPriorityItem( \
|
|
pWorkItem, \
|
|
pWorkRoutine, \
|
|
__FILE__, __LINE__ \
|
|
)
|
|
|
|
VOID
|
|
UlCallPassive(
|
|
IN PUL_WORK_ITEM pWorkItem,
|
|
IN PUL_WORK_ROUTINE pWorkRoutine,
|
|
IN PCSTR pFileName,
|
|
IN USHORT LineNumber
|
|
);
|
|
|
|
#define UL_CALL_PASSIVE( pWorkItem, pWorkRoutine ) \
|
|
UlCallPassive( \
|
|
pWorkItem, \
|
|
pWorkRoutine, \
|
|
__FILE__, __LINE__ \
|
|
)
|
|
|
|
PETHREAD
|
|
UlQueryIrpThread(
|
|
VOID
|
|
);
|
|
|
|
|
|
#endif // _THRDPOOL_H_
|