Leaked source code of windows server 2003
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

/*++
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_