[wdmaudiodev] Re: Problem capturing midi on multiprocessor (SMP) XP machines

  • From: Matt Gonzalez <matt@xxxxxxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Thu, 13 Jan 2005 15:38:21 -0800

This came up a while back; here's the posting from the Yahoo wdmaudiodev group.  Basically, it's a bug in the sample driver.

Matt


====================================================

Oops, the list stripped out the actual .cpp and .h file I sent.  I
basically changed the code to the following:
 
miniport.cpp
...
//new begin
#pragma code_seg()
/***********************************************************************
******
 * CMiniportDMusUARTStream::PutMessageLocked()
 
************************************************************************
*****
 * Now that the spinlock is held, add this message to the queue.
 */
inline void CMiniportDMusUARTStream::PutMessageLocked(PDMUS_KERNEL_EVENT
pDMKEvt)
{

    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
    if (m_DMKEvtQueue)
    {
        pDMKEvt = m_DMKEvtQueue;            //  put pDMKEvt in event
queue
 
        while (pDMKEvt->pNextEvt)
        {
            pDMKEvt = pDMKEvt->pNextEvt;
        }
        pDMKEvt->pNextEvt = pDMKEvt;        //  here is end of queue
    }
    else                                    //  currently nothing in
queue
    {
        m_DMKEvtQueue = pDMKEvt;
        if (m_DMKEvtOffset)
        {
            _DbgPrintF(DEBUGLVL_ERROR, ("PutMessage  Nothing in the
queue, but m_DMKEvtOffset == %d",m_DMKEvtOffset));
            m_DMKEvtOffset = 0;
        }
    }
}
//new end
 
#pragma code_seg()
/***********************************************************************
******
 * CMiniportDMusUARTStream::PutMessage()
 
************************************************************************
*****
 * Writes an outgoing MIDI message.
 * We don't sort a new message into the queue -- we append it.
 * This is fine, since the sequencer feeds us sequenced data.
 * Timestamps will ascend by design.
 */
NTSTATUS CMiniportDMusUARTStream::PutMessage(PDMUS_KERNEL_EVENT pDMKEvt)
{
    NTSTATUS    ntStatus = STATUS_SUCCESS;
    PDMUS_KERNEL_EVENT aDMKEvt;
 
    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
 
    if (!m_fCapture)
    {
        _DbgPrintF(DEBUGLVL_BLAB, ("PutMessage to render stream"));
        if (pDMKEvt)
        {
            KeAcquireSpinLockAtDpcLevel(&m_DpcSpinLock);
// new begin
            PutMessageLocked(pDMKEvt);
// new end
            KeReleaseSpinLockFromDpcLevel(&m_DpcSpinLock);
        }
        if (!m_TimerQueued)
        {
            (void) ConsumeEvents();
        }
    }
    else    //  capture
    {
        _DbgPrintF(DEBUGLVL_BLAB, ("PutMessage to capture stream"));
        ASSERT(NULL == pDMKEvt);
 
        SourceEvtsToPort();
    }
    return ntStatus;
}
...
 
and
 
private.h
...
    STDMETHODIMP_(NTSTATUS) SourceEvtsToPort();
    STDMETHODIMP_(NTSTATUS) ConsumeEvents();
    STDMETHODIMP_(void)     PutMessageLocked(PDMUS_KERNEL_EVENT
pDMKEvt);  // new
...
 
-----Original Message-----
From: Martin Puryear 
Sent: Thursday, May 31, 2001 11:03 PM
To: wdmaudiodev@xxxxxxxxxxxxxxx
Subject: RE: [wdmaudiodev] DMusUART sample code


You are right Matt.  Looks like a valid bug.  

You are also correct that package events are never emitted by today's
DMus port, so that's why this isn't exposed.  With a bug like this, I
suppose they never will be.

How do these files look?

-----Original Message-----
From: Matt Gonzalez [mailto:matt@xxxxxxxxxxxxx] 
Sent: Thursday, May 31, 2001 3:22 PM
To: wdmaudiodev@xxxxxxxxxxxxxxx
Subject: [wdmaudiodev] DMusUART sample code


Hello all-

I may be missing something, but I think I've found a serious bug in the
DMusUART sample code.

In the function CMiniportDMusUARTStream::ConsumeEvents, there is the
following
code:

            else if (PACKAGE_EVT(aDMKEvt))
            {
                // do stuff

                ntStatus = (PutMessage(aDMKEvt->uData.pPackageEvt));

                // null this because we are about to throw it in the
allocator
                // blah blah blah
            }

In other words, the PutMessage method of CMiniportDMusUARTStream is
being
called.  However, PutMessage is being called "inside" the m_DpcSpinLock;
that
is, m_DpcSpinLock is acquired at the top of ConsumeEvents.

The problem is that the PutMessage then tries to acquire the same
SpinLock.
This seems bad to me.

Does this mean that packages never actually show up and so this code
never gets
hit?  I can see that there's a "to do" remark at the top of this
function that
says that packages need to be handled right; is this part of that?

Anyone?  Please note that I'm quoting from the Beta 2 DDK build 2462.

Matt



****************** WDMAUDIODEV addresses: Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx Subscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe Unsubscribe: mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe Moderator: mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx URL to WDMAUDIODEV page: http://www.wdmaudiodev.de/

Other related posts: