I certainly don’t intend for this to become an iTunes gossip thread, but I don’t think what you have posted is necessarily sufficient evidence of a kernel or driver problem. I’m not asserting there isn’t a problem, only that this post doesn’t meet my threshold of proof. What you’ve posted is consistent with my own experience with recent versions of iTunes. iTunes 7.x has some serious problems with audio quality and buffering, compared to 6.x. 7.0 was so bad that playback was simply unusable on most of my home machines, and these are machines running quite vanilla XP installs; 7.0.1 fixed some of these problems, but there is still a serious problem with clock synchronization / drift, which causes a buffer drop about every 30 seconds. Very annoying. If you can get hold of the installer for any version of iTunes 6.x, I would recommend doing some experiments, and seeing whether the problem still occurs with that version.
Please note that I’m posting this as a user of iTunes, and not an employee / representative of Microsoft. I am not in any way involved in Microsoft’s music / DRM efforts / WMP, and my commentary on iTunes is solely my own. Some might consider this off-topic for NTDEV, but I think your initial approach and request for advice was well-considered.
If I had to guess, I would say that iTunes is simply not buffering much, and in ordinary circumstances, this is probably a good approach, but in your specific situation, it looks like your system experiences a burst of activity, the audio driver exhausts that buffer, and for whatever reason, iTunes cannot fill the buffer fast enough. Not exactly a Sherlock Holmes-level deduction, but my guess as to why is that the ATAPI stack, especially when dealing with CD-ROMs, can sometimes consume a lot of time in DPCs.
DPCs are a complex subject. Since you have developed drivers, here’s a pub intro to DPCs. A DPC is a “Deferred Procedure Call”, and it is one of the main ways that hardware-based drivers (as opposed to virtual NICs and the like) get scheduled and get work done. Most driver code can be lumped into three domains: 1) code paths that run in response to requests from other drivers or processes, 2) code that runs as a DPC, and 3) code that runs in response to hardware interrupts (ISRs). In *nix terminology, ISRs and DPCs are roughly equivalent to the “bottom half” of a *nix driver, and code paths that run in response to processes (system calls) are the “upper half”. Driver ISRs are intended to be as simple as possible; they examine device registers, read the cause of interrupts, acknowledge them (causing the device to stop asserting the interrupt), schedule a DPC, and then return immediately.
DPCs are intended to perform small, non-blocking units of work. DPCs never block in the scheduler; if there is a need to wait for something, DPCs must set internal state, and processing must continue in some other callback (which might be another call to the same DPC, later on). DPCs take priority over all user-mode threads. More specifically, DPCs run at DISPATCH_LEVEL, which is a priority level that is higher than PASSIVE_LEVEL, which is what all user-mode threads run at when they have not entered the kernel.
So if a driver is scheduling an excessive amount of DPCs, or those DPCs are running for too long a time, then user-mode threads won’t be scheduled enough to keep up with the real-time workload of filling audio buffers.
Try a few experiments. Disable one processor (core) and see whether the problem still happens, is worse / better, etc. If you have access to a different SMP machine (discrete processor packages, not SMP-on-die), try the same arrangement there; I suspect it won’t make a difference, though. Use perfmon (start, run, perfmon.msc) and monitor the “% DPC Time”, “% Interrupt Time”, “% User Time”, and “DPC Rate” counters under the “Processor” object. Excessive spikes in DPC activity can prevent user-mode code from doing any work, so watch those and see if they correlate with the audio drops. Do some basic monitoring with Performance Monitor, and see if this gives you an indication. If so, there are tools for getting finer-grained data on DPCs (e.g. kernrate), such as profiling the specific drivers that are scheduling DPCs and how much time they are using.
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Jon Watte
Sent: Tuesday, January 02, 2007 10:40 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] Multi-core CPU interrupt routing or global locks?
I’m seeing an annoying behavior, as a user of a system, and I’m trying
to figure it out as a first step towards trying to resolve it. I’ve
convinced myself the problem is somewhere at the kernel level, but I’d
like some help theorizing or explaining why that would be.
My experience: I’ve developed drivers for other OS-es before, but never
for Windows, so if my terminology is off, please correct me. I’ve also
used WinDbg to analyze minidumps to find out how to work around driver
problems at the user level, but my Windows kernel experience stops there.
The system: Windows XP SP2 32-bit, Atlon X2 (dual core) CPU, NVIDIA 400
series chip set, ACPI 2.x BIOS, Creative X-Fi sound card, SATA hard disk
array and PATA CD/DVD drive.
The behavior: Whenever I’m playing music in iTunes for Windows (which is
horribly modal in its UI, by the way), and encoding CDs using
AudioGrabber, the sound playback stutters (repeats a buffer) when
starting and stopping the ripping process. I know that iTunes queues a
fair bit of data, so it’s likely that the stuttering is caused by the
sound driver missing an interrupt, or getting the interrupt but not
being able to handle it. There’s a small chance that the problem might
be caused higher up, such as in DirectSound not being able to re-fill
the buffer, although with two CPUs, that’s less likely to be the cause.
I don’t understand why the missing interrupt would happen, though.
First, there are two CPUs, and the documentation on the NT kernel I’ve
found says that Windows services interrupts on any CPU, so if the PATA
CD device driver disables interrupts for extended periods of time, the
interrupt service for the sound card would just go to the other CPU.
Second, I don’t think it can be any specific device contention, because
iTunes and AudioGrabber actually shares no devices (except for the
graphics card and user input).
iTunes reads from an SMB file system using a network card, and plays
through a sound card.
Audiograbber reads from a PATA device, and writes to an NTFS file system
on a SATA array device.
So, there must either be some global lock that both the CD digital audio
reading device wants, and the X-fi sound card wants, OR the discussion
about sharing interrupts across CPUs that I read is either only
advisory, or doesn’t apply to a dual-core single-package CPU. OR there’s
some totally different cause which I don’t know about at all.
Any discussion, reference, or theories you might have would help!
Cheers,
/ h+
Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer