why spinlock raises IRQL to DISPATCH

Discussion in 'Windows Vista Drivers' started by Bajamani, May 16, 2005.

  1. Bajamani

    Bajamani Guest

    Why does spinlock implementation raise the irql to dispatch level? just
    acquiring the lock at passive level should prevent other threads from
    accessing the same lock.
     
    Bajamani, May 16, 2005
    #1
    1. Advertisements

  2. Bajamani

    Don Burn Guest

    Because a spinlock has other threads spin on the lock. If you do not
    disable scheduling you can create a situation where most of your systems CPU
    time is spent spinning on locks, and where a low priority thread has
    acquired the lock then is starved by spinning to the point that it taks a
    long time to release it.

    Spin locks are spupposed to be low overhead locks for short periods of use.
    Note: on a uniprocessor implementation the lock is never set, the
    implementation is just raise to dispatch to disable scheduling.
     
    Don Burn, May 16, 2005
    #2
    1. Advertisements

  3. Maybe need to add ( for full clearance ) that the thread scheduler run at
    DISPATCH_LEVEL , so that's the way of disable sheduling
    Arkady
     
    Arkady Frenkel, May 16, 2005
    #3
  4. I think saying the scheduler runs at DISPATCH_LEVEL will lead to many
    problems for people to understand it correctly. It runs when the IRQL is
    going to drop below DISPATCH_LEVEL. If you say that the scheduler runs at
    DISPATCH_LEVEL you can be lead to believe that multiple threads can run at
    DISPATCH_LEVEL on the same CPU.

    I have always wondered if a CPU is running a thread at DISPATCH_LEVEL and a
    hardware interrupt occurs, how does the hardware/OS decide to use that CPU
    or another that might be running at passive. If the other CPU was running
    at DIRQL, will that thread that was preempted be switched to the first CPU
    that drops below DIRQL? Keeping the stacks straight might be a problem in
    doing that. I guess you could have a CPU that is running at passive while
    another is running at DIRQL and keeping a DISPATCH_LEVEL from running.
     
    David J. Craig, May 16, 2005
    #4
  5. Actually, if you want to get real technical about it, I doubt anyone on the
    planet knows what IRQL the scheduler runs at as the scheduler is distributed
    all over the place in the OS. The dispatcher however, definitely runs at
    DISPATCH_LEVEL (hence the name). The dispatcher, distinct from the
    scheduler, is what actually places the next thread on the processor to be
    executed.

    As the dispatcher would not be invoked during an interrupt of a thread
    executing at DISPATCH_LEVEL, there would be no practical way of moving the
    thread to another processor. Also, DPC queues are per processor, so a
    DISPATCH_LEVEL thread would have to be requed on another processor.
    DISPATCH_LEVEL threads are guaranteed to execute to completion, moving a
    thread from one processor to another, would violate this. Not to mention
    the fact that interrupts occur within the context of the currently executing
    thread on a given CPU, so no task switch occurs.
     
    Bill McKenzie, May 16, 2005
    #5
  6. On passive-level, it is possible for the dispatcher to switch to another
    thread. This thread can be any, and can possibly try to take the same spinlock,
    which would cause a deadlock.
     
    Maxim S. Shatskih, May 16, 2005
    #6
  7. You can think of a spinlock as a two dimensional object. The first
    dimension is IRQL and that synchronizes on the local processor only.
    The second dimension is shared memory and that synchronizes cross
    process. Of course the second dimension vanishes on a uni-processor
    machine.
    So why do we need to synchronize on the local processor? Well the operating
    system is interrupt driven. So you need to enumerate all the places your
    spinlock
    is used and work out the maximum IRQL it's acquired from. You need to
    raise to this maximum level when ever you acquire otherwise that interrupt
    could run on top of your thread while you own the lock and deadlock
    yourself.
    Not the system makes multiple threads run on a single processor by using
    DISPATCH_LEVEL interrupts to preempt threads. This means that if you
    raise to an IRQL less than DISPATCH_LEVEL then it's thread local.
    Your would raise get preempted and another thread could try and grab
    the spinlock and spin. Not very efficient and in cases like this you likely
    want to give up spinning and wait on an object until the lock is released
    instead.
    So that basically sets a minimum IRQL level of DISPATCH_LEVEL for
    all spinlocks. As a consequence of this you can really think of spinlocks
    being owned by a processor rather than a thread.
    Now the second dimension of the lock comes in after we have the first
    local level synchronization sorted out. We extend our lock across all
    processors by using things like test and set instructions to shared memory.
    Neill.
     
    Neill Clift [MSFT], May 17, 2005
    #7
  8. Bajamani

    Bajamani Guest

    I am not clear as to how it will cause deadlock. if the second thread
    tries
    to acquire the same lock then it will wait.
     
    Bajamani, May 20, 2005
    #8
  9. It will deadlock. Acquiring the same spinlock by the same CPU second time
    is a deadlock.

    Spinlocks are acquired by CPUs and not by threads. They keep no thread
    context and are not associated with the dispatcher.
     
    Maxim S. Shatskih, May 20, 2005
    #9
  10. if the thread isn't raised to DISPATCH_LEVEL then a DPC could run on that
    same processor and attempt to acquire the same spinlock. This would be an
    immediate deadlock.

    -p
     
    Peter Wieland [MSFT], May 20, 2005
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.