Path: news.mitre.org!blanket.mitre.org!philabs!newsjunkie.ans.net!newsfeeds.ans.net!news-was.dfn.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!streamer1.cleveland.iagnet.net!qual.net!iagnet.net!pushkin.conxion.com!news.he.net!newshub.cts.com!newsfeed.cts.com!cmkrnl!jeh From: jeh@cmkrnl.com (Jamie Hanrahan) Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode Subject: Re: Synchronization of driver routines w/spinlock Message-ID: <1998Jan13.200459.8405@cmkrnl> Date: 13 Jan 98 20:04:59 PST References: <693kh2$f55$1@Radon.Stanford.EDU> <34ba0edf.2602462@spock> Organization: Kernel Mode Systems, San Diego, CA Lines: 111 In article , sihde@Xenon.Stanford.EDU (Steve Ihde) writes: > jeh@cmkrnl.com (Jamie Hanrahan) writes: > >>In article <34baa5bd.0@news.osr.com>, markr@osr.com (Mark Roddy) writes: >>> On Mon, 12 Jan 1998 20:04:08 GMT, tony@ercolano.com (Anthony V. >>> Ercolano) wrote: >>> >>>>"Stephan Wolf" wrote: >>>>I thought you could be context switched away at APC level (and PASSIVE >>>>as well, but that would be quibbling). >>>> >>>>- tony >>> >>> Nope. Context switching only occurs at PASSIVE_LEVEL. > >>Nope. Context switching most certainly occurs at APC_LEVEL. >>(Try it.) > >>APC_LEVEL is actually a state of a thread that says "I am currently >>running a kernel-mode APC, or I want to block kernel-mode APCs; in any >>case, don't deliver a kernel-mode APC to me until I return from this >>one or lower IRQL." > >>But while the thread is running that APC it can still be preempted or >>timesliced in favor of another thread, and that thread might be at >>PASSIVE_LEVEL. > >>The other non-PASSIVE IRQLs, DISPATCH_LEVEL and above, are processor >>states rather than thread states. > > I agree with Jamie's analysis; Tony's original question of whether you > could be switched away at APC_LEVEL was prompted by this bit here: > >>"Stephan Wolf" wrote: >>>2. A routine running at some IRQL cannot be interrupted by any other >>>routine that would be running on the same or a lower IRQL *on the same >>>processor*. However, *any* other routine *can* be running at the same >>>time (i.e. in parallel) on some other processor. >> >>I thought you could be context switched away at APC level (and PASSIVE >>as well, but that would be quibbling). >> >>- tony > > I believe that Tony interpreted Stephen Wolf as implying that an APC > couldn't be interrupted by a regular PASSIVE_LEVEL thread because the > thread would run at a lower IRQL than the APC. > > Stephen's statement is correct; a routine running at APC_LEVEL cannot > be interrupted by any routine running at APC_LEVEL or below. However, > it can be interrupted by the thread dispatcher, a routine which runs > at DISPATCH_LEVEL, which is higher than APC_LEVEL. The dispatcher may > then choose to schedule another thread to run, which may be running at > PASSIVE_LEVEL. > > I hope that helps clear things up rather than clouds them further. I'm afraid I think it clouds things, at least in that you're using the term "interrupt" imprecisely. (Sorry for what may seem like a nitpick... but I've found that inconsistent use of terminology is a real impediment to understanding.) Threads do not "interrupt" other threads and it is misleading and confusing to think of them as doing so. For example, the CPU register context that is saved and restored across an ISR is a tiny subset of that that is saved and restored across a thread context switch. Interrupts are prioritized according to IRQL; threads, according to their priority. And so on. Rather, devices cause hardware interrupts; the hardware interrupt service routines may request software interrupts that execute DPC routines; and these may end up calling the NT scheduler routines, possibly causing a thread *context switch*. From the point of view of the threads it might look as though one thread has "interrupted" another, but that is not the best mental model to use, as the actual interrupts that started it all are quite far removed from the thread context switch. Threads can also cause context switches more directly, by either going to a Wait state or by signalling an object that some other, higher-priority thread is Waiting for, but this isn't "one thread interrupting the other thread" either. Of course, all of the scheduler's routines run above APC_LEVEL, so running at APC_LEVEL does not inhibit them from running... > Stephen's statement is correct; a routine running at APC_LEVEL cannot > be interrupted by any routine running at APC_LEVEL or below. What he actually said was: >>>2. A routine running at some IRQL cannot be interrupted by any other >>>routine that would be running on the same or a lower IRQL *on the same >>>processor*. However, *any* other routine *can* be running at the same >>>time (i.e. in parallel) on some other processor. ...and he's correct, for IRQLs >= DISPATCH_LEVEL. For APC_LEVEL, the things that you can do and that can happen to you (waiting, preemption, quantum expiration) are really no different than from PASSIVE_LEVEL, except that no kernel APCs will be delivered to your thread if you're at APC_LEVEL. You therefore "own your thread" when you're at APC_LEVEL, and that is the reason for being there. --- Jamie Hanrahan, Kernel Mode Systems, San Diego CA Internet: jeh@cmkrnl.com (JH645) CompuServe: 74140,2055 drivers, internals, networks, applications, and training for VMS and Windows NT NT driver FAQ, links, and other information: http://www.cmkrnl.com/ If you post a reply in news, please don't e-mail it too.