阅读:1294回复:3
在driverstudio下,我对系统线程的理解和做法对么?50分
中断方式的WDM模式9052PCI卡驱动,中断间隔不到100ms,一次中断要输出1M数据,原来驱动设计方法是,APP层上异步写,写过后即组织下一批数据。IRP下来后,排入队列。中断到来时,在中断服务中,检查队列中有无待处的IRP,如有,申请一个DPC,在DPC例程中,将队列中的IRP取出,直接输出,输出完毕后,将IRP完成返回;APP上等待IRP完成的事件后,再将组织好的下一批数据写下来。
由于这种方法占用处理器时间太多,一开始由于APP上只写了数据输出部分,所以除了计算机对别的操作(如MOUSE)响应变得迟钝了之外,没显出处理器不够用;但现在APP上其它的功能都加上了,共计有32个文件的读,以及1M字节的逐一字节处理,结果处理器就不够用了,总是有前一个IRP已经完成,但数据还没组织好,中断发生时,并没有IRP下来,致使中断落空。因此,除了着手在APP上想办法之外,驱动占用太多资源,也不得不考虑节省的方法了! DPC中直接输出数据,CPU等于只在做这一项工作,使用系统线程来作,是不是可以将CPU与PCI的速度差的时间节省下来呢?《WDM驱动设计》上,称系统线程通常是用来做那种不能中断CPU的外设的驱动,以便于进行轮循! 今天着手看driverstudio的随机文档中关于系统线程的部分以及其提供的范例,虽然看得云山雾绕,但也有了些模糊的认识,在这里说给大佬们听听,看我理解地对不对,以及我对新驱动的设想是否合理:(关于系统线程的部分基本上是从范例上抄来的,天下程序一大抄,只要抄对就行) 一:关于增加一个系统线程的步骤: 1:创建一个KSystemThread类的子类,命名为SysThread,增加两个公共成员变量 KInterlockedList<IRP> m_Queue; KSemaphore m_Mailbox; 2:在Device类中,定义一个SysThread类的实例作为成员,命名为m_Thread,定义一个成员函数MyThread(),作为系统线程的主函数。 3:在驱动的设备类构建函数MyDevice::MyDevice()中,调用m_Thread.Start(LinkTo( MyThread ),this)启动系统线程,并将线程函数链接到 MyThread()函数上。 二:如何完成我所希望的数据输出操作。 SysThread类中增加的成员函数POST,在范例中显然是用于传递一个IRP指针的。因此,我考虑解决方法如下: 1:当APP执行了一个写操作,IRP传到Write(KIrp I)函数时,Write()立刻将这个IRP挂起,然后将此IRP作为参数,调用m_Thread.m_Queue.InsertTail(I);将当前IRP的地址加入m_Queue对象的列表中。 2:当一个中断到来的时,在中断服务程序中,调用m_Thread.m_Mailbox.Signal();将m_Mailbox对象置为有信号状态。 3:系统线程的主函数中,使用一个无条件循环,循环体的前部,加入 m_Thread.m_Mailbox.Wait();阻塞线程的执行,直到m_Mailbox有信号,然后从m_Queue中提出首部的IRP,进行处理;程序如下: KIrp I = m_Thread.m_Queue.RemoveHead(); KMemory Mem(NULL); Mem=KMemory(I.Mdl()); PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace(); m_MemoryRange1.outd(0,PULONG(pBuffer),dwTotalSize); I.Information() = dwTotalSize*4; I.Complete(STATUS_SUCCESS); 实际上,上面的处理程序,和原来的程序中的DPC基本相似,只是原程序使用的是系统队列来暂存IRP,而现在则是将IRP挂起,使用m_Queue对象来保存挂起的IRP地址,从语句上我看不出还有什么区别,因此,能不能达到我所希望的节省系统资源的目的,实在心里没底。 三:几个问题: 1:系统线程,是不是可以在任何位置启动,比如在DeviceControl(KIrp I)中由APP控制启动? 2:中断服务中,可否执行m_Thread.m_Mailbox.Signal();我记得有位大佬说过在中断中连置位事件对象都不可以。 3:IRP挂起(PENDING)后再将其地址压入m_Queue对列有什么意义?这是从范例上抄来的句子,我搞不懂为什么要挂起来! 4:系统线程是不是真能节省CPU时间??这才是我最关心的问题。 |
|
最新喜欢:jinghu...
|
沙发#
发布于:2002-11-25 09:25
其实系统线程和普通线程在运行机制上没有什么区别,他们都公平竞争cpu时间。他们不过运行在系统空间,在一些函数的调用上减少从用户空间切换到系统空间的的开销。
我觉的“APP层上异步写,写过后即组织下一批数据”这句话有问题,是不是考虑在APP异步写的同时另外开辟线程进行数据处理? 你的pci卡处理数据是不是就是映射1M的卡上内存,然后把数据放进这块内存后启动传输?这样的话大可不必在DPC内部进行,可已使用系统线程或者工作者线程。如果用DMA的话我不是很清楚。 |
|
板凳#
发布于:2002-11-26 12:42
数据处理是在APP上做的,单用一个线程。所谓处理,只是把1M字节数据的排列顺序按要求重新排列,然后将其输出,也就是在APP上用写文件的方式把输出请求发给驱动。
我希望在驱动中开一个系统线程专门用来输出数据。原来在DPC中输出数据,由于一次传输的数据量较大,输出期间独占了CPU,把其它线程都阻断了,这在APP上都能表现出来(系统响应变得迟钝了)。 |
|
|
地板#
发布于:2002-11-26 13:45
应改是可以的.我还是想问一下,你的pci卡映射了多少内存?
|
|