CPU与IRP的一些相关函数

VOID

KiAdjustIrpCredits (

    VOID

    )其中        Number = KeNumberProcessors;Prcb = KiProcessorBlock[Index];

多核情况下调整每个CPU的IRP对象配额。在while (Index < Number);轮询调整1-n的CPU的配额InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, Adjust),不过最后一个CPU为什么是 InterlockedExchangeAdd(&Prcb->LookasideIrpFloat, -TotalAdjust)??  PIRP

IopAllocateIrpPrivate(

    IN CCHAR StackSize,

    IN BOOLEAN ChargeQuota

    )分配IRP首先根据IRP需要的栈单元决定是否从两个快查表中的一个分配。一个栈单元为1则为LookasideSmallIrpList ,一个栈单元小于8大于1则为LookasideLargeIrpList.然后从指定的快查表中摘除一个作为IRP的空间。如果超过8 则自行分配。没什么说的了。 里面的IopInitializeIrp倒是个需要注意的 StackSize  是IRP要分配的堆栈数目PacketSize是IRP的长度加上 StackSize *stack的长度#define IopInitializeIrp( Irp, PacketSize, StackSize ) {          \

    RtlZeroMemory( (Irp), (PacketSize) );                         \

    (Irp)->Type = (CSHORT) IO_TYPE_IRP;                           \

    (Irp)->Size = (USHORT) ((PacketSize));                        \

    (Irp)->StackCount = (CCHAR) ((StackSize));                    \

    (Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1);           \

    (Irp)->ApcEnvironment = KeGetCurrentApcEnvironment();         \

    InitializeListHead (&(Irp)->ThreadListEntry);                 \

    (Irp)->Tail.Overlay.CurrentStackLocation =                    \

        ((PIO_STACK_LOCATION) ((UCHAR *) (Irp) +                  \

            sizeof( IRP ) +                                       \

            ( (StackSize) * sizeof( IO_STACK_LOCATION )))); } IopFreeIrp情况类似:首先检验IRP是否是IO_TYPE_IRP,&(Irp)->ThreadListEntry为空。当前IRP的CurrentLocation大于IRP的STACKCOUNT。获取当前CPU的PKPRCB , prcb = KeGetCurrentPrcb();然后根据IRP之前是从快查表分配还是使用自行分配进行处理。 另:这里是 gussing是个错别字 的博客

http://www.cnblogs.com/gussing/archive/2011/01/18/1938140.html因为他不允许转载 所以在这里谈谈内容 也推荐大家对驱动内核有兴趣的去看下他的wdk tips IRP的创建可以为自写驱动创建和IO管理器创建,在释放上有自己释放或者由IO管理器释放两种IoAllocateIrp IoBuildAsynchronousFsdRequest属于需要自行释放,WDK帮助也有提到。( IoBuildSynchronousFsdRequest   IoBuildDeviceIoControlRequest TdiBuildInternalDeviceControlIrp 属于交与IO管理器释放。 PIRP

IoBuildAsynchronousFsdRequest(

    IN ULONG MajorFunction,

    IN PDEVICE_OBJECT DeviceObject,

    IN OUT PVOID Buffer OPTIONAL,

    IN ULONG Length OPTIONAL,

    IN PLARGE_INTEGER StartingOffset OPTIONAL,

    IN PIO_STATUS_BLOCK IoStatusBlock OPTIONAL

    )

{

    PIRP irp;

    PIO_STACK_LOCATION irpSp;    //    分配IRP 第一个是IRP的stack数目 ,第二个参数是不改变IRP配额    irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );

    if (!irp) {

        return irp;

    }    // 按推荐的博客的那个作者的意思 这里应该不设置THREAD 因为他将创建的IRP分类至NON THREAD IRP。    irp->Tail.Overlay.Thread = PsGetCurrentThread();    irpSp = IoGetNextIrpStackLocation( irp );    irpSp->MajorFunction = (UCHAR) MajorFunction;    if (MajorFunction != IRP_MJ_FLUSH_BUFFERS &&

        MajorFunction != IRP_MJ_SHUTDOWN &&

        MajorFunction != IRP_MJ_PNP &&

        MajorFunction != IRP_MJ_POWER) {    // ......根据设备对象的类型来决定 BUFFER的种类是SYSBUF 还是MDL 或者原函数输入BUF......   // 代码比较简单  分配IRP并设置读写参数        if (MajorFunction == IRP_MJ_WRITE) {

            irpSp->Parameters.Write.Length = Length;

            irpSp->Parameters.Write.ByteOffset = *StartingOffset;

        } else {

            irpSp->Parameters.Read.Length = Length;

            irpSp->Parameters.Read.ByteOffset = *StartingOffset;

        }

    }    irp->UserIosb = IoStatusBlock;

    return irp;

}    IoBuildsynchronousFsdRequest还是调用IoBuildAsynchronousFsdRequest只不过多了一行 irp->UserEvent = Event,用于同步时候的等待。     

 

你可能感兴趣的:(cpu)