InterlockedExchange

Hello,
Had a question regarding InterlockedExchanges. Im at my wits end to find
out what this is all about.

We are basically operating at DIRQL and need to synchronize between
functions running at various IRQLs. Now i know we can use KeSynch…but…

So…say this is a function I use to synchronize

void LockIRQLIndependent( ULONG *LockVar )
{
while (InterlockedExchange(LockVar ,1) != 0);
}

void UnLockIRQLIndependent( ULONG *LockVar )
{
InterlockedExchange(LockVar , 0);
}

And since I am operating at DIRQL…no spin locks also. So…this does NOT
work. I still see the two differnt functions entering at the same time.
Also, this seems to be horribly inefficient. So assuming I Cannot use
KeSync and have to use this:

  1. Is there a more efficient way of using Interlocked…
  2. Is the above implementation wrong?

Thanks a bunch!
Mark

Hmm, I thought DIRQL was just short hand for IRQL==DISPATCH_LEVEL in
which case you can use spin locks. However, I could be mistaken.

Anyway, if you are operating at DISPATCH_LEVEL or above, you are running
on a uniprocessor machine, and you enter LockIRQLIndependent while some
other thread is holding the lock, then you are going lock up the system.
The problem is, at DISPATCH_LEVEL or above, threads are not preemptable.
That is, the dispatcher is not going to let any other threads run until
you drop below DISPATCH_LEVEL. You aren’t going to do that until you
acquire the lock. You can’t acquire the lock until some other thread
runs. Dead-lock.

Hope this helps.

Aaron Stavens
NetMotion Wireless, Inc.

-----Original Message-----
From: Mark [mailto:xxxxx@yahoo.com]
Sent: Monday, April 15, 2002 7:32 PM
To: NT Developers Interest List
Subject: [ntdev] InterlockedExchange

Hello,
Had a question regarding InterlockedExchanges. Im at my wits end to find
out what this is all about.

We are basically operating at DIRQL and need to synchronize between
functions running at various IRQLs. Now i know we can use
KeSynch…but…

So…say this is a function I use to synchronize

void LockIRQLIndependent( ULONG *LockVar )
{
while (InterlockedExchange(LockVar ,1) != 0);
}

void UnLockIRQLIndependent( ULONG *LockVar )
{
InterlockedExchange(LockVar , 0);
}

And since I am operating at DIRQL…no spin locks also. So…this does
NOT
work. I still see the two differnt functions entering at the same time.
Also, this seems to be horribly inefficient. So assuming I Cannot use
KeSync and have to use this:

  1. Is there a more efficient way of using Interlocked…
  2. Is the above implementation wrong?

Thanks a bunch!
Mark


You are currently subscribed to ntdev as: xxxxx@nmwco.com
To unsubscribe send a blank email to %%email.unsub%%

But…if it is a uniprocessor machine and say one of the miniports entry points is entered:

  1. The other miniport functions will not be entered because the miniport driver is single threaded
  2. The external callback, which is not via the miniport, cannot run at the same time, because as u mentioned, at that interrupt level, it is not pre-emptable. So no one else could be possible holding the lock. Same goes if the external callback is running. If it is running, the IRQL is DIRQL, and so the same thing applies.So it pretty much means someone else cannot be holding the lock. If it is, then the lock up makes sense. But the lock/unlock combinations are all correct.
    Im actually running on a multi processor machine. And this problem is happening when one of them holds the lock and the other tries to get it, which in effect means that something is terribly wrong with the way I am trying to do it!!!
    Thanks
    Mark

Aaron Stavens wrote: Hmm, I thought DIRQL was just short hand for IRQL==DISPATCH_LEVEL in
which case you can use spin locks. However, I could be mistaken.

Anyway, if you are operating at DISPATCH_LEVEL or above, you are running
on a uniprocessor machine, and you enter LockIRQLIndependent while some
other thread is holding the lock, then you are going lock up the system.
The problem is, at DISPATCH_LEVEL or above, threads are not preemptable.
That is, the dispatcher is not going to let any other threads run until
you drop below DISPATCH_LEVEL. You aren’t going to do that until you
acquire the lock. You can’t acquire the lock until some other thread
runs. Dead-lock.

Hope this helps.

Aaron Stavens
NetMotion Wireless, Inc.

-----Original Message-----
From: Mark [mailto:xxxxx@yahoo.com]
Sent: Monday, April 15, 2002 7:32 PM
To: NT Developers Interest List
Subject: [ntdev] InterlockedExchange

Hello,
Had a question regarding InterlockedExchanges. Im at my wits end to find
out what this is all about.

We are basically operating at DIRQL and need to synchronize between
functions running at various IRQLs. Now i know we can use
KeSynch…but…

So…say this is a function I use to synchronize

void LockIRQLIndependent( ULONG *LockVar )
{
while (InterlockedExchange(LockVar ,1) != 0);
}

void UnLockIRQLIndependent( ULONG *LockVar )
{
InterlockedExchange(LockVar , 0);
}

And since I am operating at DIRQL…no spin locks also. So…this does
NOT
work. I still see the two differnt functions entering at the same time.
Also, this seems to be horribly inefficient. So assuming I Cannot use
KeSync and have to use this:
1) Is there a more efficient way of using Interlocked…
2) Is the above implementation wrong?

Thanks a bunch!
Mark


You are currently subscribed to ntdev as: xxxxx@nmwco.com
To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntdev as: xxxxx@yahoo.com
To unsubscribe send a blank email to %%email.unsub%%

---------------------------------
Do You Yahoo!?
Yahoo! Tax Center - online filing with TurboTax

> Aaron Stavens wrote: Hmm, I thought DIRQL was just short hand for IRQL==DISPATCH_LEVEL in
> which case you can use spin locks. However, I could be mistaken.

DIRQL == Device IRQL. Guarantied to be above DISPATCH_LEVEL. Depends
on Devices IRQ mapping.

-----------------------------------------------------------------
| Norbert Kawulski | mailto:xxxxx@stollmann.de |
| Stollmann E+V GmbH, Development | http://www.stollmann.de |

The only way to go for an ISR that needs synchronized access to data
that is shared with a routine at passive level is KeSynch…

That is because KeSynch is the only way to keep out your ISR from
occuring. Else your ISR may interrupt your other routine/DPC.

Maybe you should have a passive level thread that reads from an
interlocked queue and others like the DpcForIsr write to this queue.
So only this thread touches your data hence no concurrence.


| Norbert Kawulski | mailto:xxxxx@stollmann.de |
| Stollmann E+V GmbH, Development | http://www.stollmann.de |
–If it’s ISDN or Bluetooth, make sure it’s driven by Stollmann–

“I want to die in my sleep like my grandfather…Not screaming and
yelling like his passengers.”

> 1) Is there a more efficient way of using Interlocked…

  1. Is the above implementation wrong?

Use spinlocks and KeSynchronizeExecution instead of these handicrafted spinlocks you try to make. If the ISR will interrupt the code
which holds your “lock”, and then try to acquire the lock again - a deadlock.

Max

Hi Jake,
Thanks for the reply!
We are actually not implementing locks without IRQLs. The miniport
entry points are called at DIRQL anyways, and only one entry point could be
executing at one time.
In the case of the external callback into the miniport( which is
primarily what we are trying to synchronize with ) , as mentioned in the
email, the IRQL is first raised and then we try to get the lock. So the
question of the ISR interrupting does not occur, because the IRQL has
already been raised to DIRQL.

Ill explain what the problem is:

We have a miniport, which has external callbacks into it. We are trying to synchronize the miniport entry points with these external callbacks. I know this is not the recommended way, but we inherited this code and we have to fix it now. Redesigning is not an option.The way the code was written initally was that the external callback was called *after* raising the IRQL to DIRQL, so an ISR interrupting the callback is not possible. Now this worked on a single processor, but of course, on a MP system, it failed to work. So the solution we came up with was to use InterlockedExchange calls after the IRQL has been raised. But…it still does not work. Locks up on us. We cannot use Lists as of now, but some redesigning is on the cards, but we need a solution atleast for now. So the closest we could think about was using these Interlocked calls.

I hope I have explained the problem. Do you see any problems with this approach…or is there any other way to implement a IRQL independent lock?

Thanks,

Mark


Do You Yahoo!?
Yahoo! Tax Center - online filing with TurboTax

“Mark Lobo” wrote in message news:xxxxx@ntdev…
>
>We have a miniport, which has external callbacks into it. We are trying to
synchronize the >miniport entry points with these external callbacks. I know
this is not the recommended way, >but we inherited this code and we have to
fix it now. Redesigning is not an option.The way >the code was written
initally was that the external callback was called after raising the >IRQL
to DIRQL, so an ISR interrupting the callback is not possible. Now this
worked on a >single processor, but of course, on a MP system, it failed to
work. So the solution we came >up with was to use InterlockedExchange calls
after the IRQL has been raised.
>

You ARE re-inventing spin locks. You want multiprocessor serialization at
IRQL x, where IRQL x is some IRQL > DISPATCH_LEVEL. You STILL do this with
spin locks.

I’d say your best options are:

1) KeAcquireInterruptSpinLock(…)
2) KeAcquireSpinLockRaiseToSync(…) - A very large hammer… Please tell me
this is a very limited distribution product. This acquires an IRQL
SYNC_LEVEL spin lock. Nuff said?
3) KeSynchronizeExecution(…) - which is a PITA, but at least it works.

You should be aware that there’s a problem with calling
KeAcquireSpinLockRaiseToSync in that driver verifier doesn’t support it very
well. When you drop the lock, Verifier will “fail” you for dropping a lock
from other than DISPATCH_LEVEL (FWIW, I’ve talked to the verifier guy about
this, but he’s not hot to fix it). Just so nobody reads this and gets the
wrong idea, you do NOT avoid this problem by first dropping the IRQL to
DISPATCH_LEVEL and THEN releasing the lock (that avoids the problem, but
gets you a potential deadlock in return).

Peter
OSR

Unfortunately, this is not a limited distribution product!!!
I tried to look up KeAcquireInterruptSpinLock() in the docs, but couldnt find it. One big problem is: How do I get access to the miniports Interrupt object? Doesnt the port driver claim it on the miniports behalf? Is there a way to access a miniports interrupt object? If yes, then I am OK with using KeSync…the whole reason for inventing this was that we dont have access to the interrupt object!!! Or maybe I am missing something really basic here.
Thanks,
Mark

Peter Viscarola wrote: “Mark Lobo” wrote in message news:xxxxx@ntdev…
>
>We have a miniport, which has external callbacks into it. We are trying to
synchronize the >miniport entry points with these external callbacks. I know
this is not the recommended way, >but we inherited this code and we have to
fix it now. Redesigning is not an option.The way >the code was written
initally was that the external callback was called after raising the >IRQL
to DIRQL, so an ISR interrupting the callback is not possible. Now this
worked on a >single processor, but of course, on a MP system, it failed to
work. So the solution we came >up with was to use InterlockedExchange calls
after the IRQL has been raised.
>

You ARE re-inventing spin locks. You want multiprocessor serialization at
IRQL x, where IRQL x is some IRQL > DISPATCH_LEVEL. You STILL do this with
spin locks.

I’d say your best options are:

1) KeAcquireInterruptSpinLock(…)
2) KeAcquireSpinLockRaiseToSync(…) - A very large hammer… Please tell me
this is a very limited distribution product. This acquires an IRQL
SYNC_LEVEL spin lock. Nuff said?
3) KeSynchronizeExecution(…) - which is a PITA, but at least it works.

You should be aware that there’s a problem with calling
KeAcquireSpinLockRaiseToSync in that driver verifier doesn’t support it very
well. When you drop the lock, Verifier will “fail” you for dropping a lock
from other than DISPATCH_LEVEL (FWIW, I’ve talked to the verifier guy about
this, but he’s not hot to fix it). Just so nobody reads this and gets the
wrong idea, you do NOT avoid this problem by first dropping the IRQL to
DISPATCH_LEVEL and THEN releasing the lock (that avoids the problem, but
gets you a potential deadlock in return).

Peter
OSR


You are currently subscribed to ntdev as: xxxxx@yahoo.com
To unsubscribe send a blank email to %%email.unsub%%

---------------------------------
Do You Yahoo!?
Yahoo! Tax Center - online filing with TurboTax

> 1) KeAcquireInterruptSpinLock(…)

Is it some new undocumented function from XP?
It does not exported from kernel and HAL on w2k SP2.
It does not documented in MSDN Library Jan 2002.

Max

I’m not entirely sure that I understand your problem. But I am sure
that the code that you posted is trying to spin waiting for other code
to release a lock, which is the same as a spinlock. Doing this by hand
will only open you up to bug introduction.

Interlocked instructions are useful for manipulating lists, reference
counts and a few other odds and ends. They are not a general
replacement for spinlocks. You can get a lot of use out of them if you
re-design your code. But I don’t think that there’s a quick fix here.

  • Jake

-----Original Message-----
Subject: Re: InterlockedExchange
From: Mark Lobo
Date: Tue, 16 Apr 2002 11:11:02 -0700 (PDT)
X-Message-Number: 37

–0-701817045-1018980662=:55909
Content-Type: text/plain; charset=us-ascii

Hi Jake,
Thanks for the reply!
We are actually not implementing locks without IRQLs. The miniport
entry points are called at DIRQL anyways, and only one entry point could
be
executing at one time.
In the case of the external callback into the miniport( which is
primarily what we are trying to synchronize with ) , as mentioned in the

email, the IRQL is first raised and then we try to get the lock. So the

question of the ISR interrupting does not occur, because the IRQL has
already been raised to DIRQL.

Ill explain what the problem is:

We have a miniport, which has external callbacks into it. We are trying
to synchronize the miniport entry points with these external callbacks.
I know this is not the recommended way, but we inherited this code and
we have to fix it now. Redesigning is not an option.The way the code was
written initally was that the external callback was called after
raising the IRQL to DIRQL, so an ISR interrupting the callback is not
possible. Now this worked on a single processor, but of course, on a MP
system, it failed to work. So the solution we came up with was to use
InterlockedExchange calls after the IRQL has been raised. But…it still
does not work. Locks up on us. We cannot use Lists as of now, but some
redesigning is on the cards, but we need a solution atleast for now. So
the closest we could think about was using these Interlocked calls.

I hope I have explained the problem. Do you see any problems with this
approach…or is there any other way to implement a IRQL independent
lock?

Thanks,

Mark

Hi,

What is a PITA ? Never heard that one before :))

Jos.

pain in the ass

On Wed, 17 Apr 2002, Jos Scherders wrote:

Hi,

What is a PITA ? Never heard that one before :))

Jos.


You are currently subscribed to ntdev as: xxxxx@inkvine.fluff.org
To unsubscribe send a blank email to %%email.unsub%%


Peter xxxxx@inkvine.fluff.org
http://www.inkvine.fluff.org/~peter/

logic kicks ass:
(1) Horses have an even number of legs.
(2) They have two legs in back and fore legs in front.
(3) This makes a total of six legs, which certainly is an odd number of
legs for a horse.
(4) But the only number that is both odd and even is infinity.
(5) Therefore, horses must have an infinite number of legs.

PITA => Pain In The Ass

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Jos Scherders
Sent: Wednesday, April 17, 2002 12:32 PM
To: NT Developers Interest List
Subject: [ntdev] Re: InterlockedExchange

Hi,

What is a PITA ? Never heard that one before :))

Jos.


You are currently subscribed to ntdev as: xxxxx@pdq.net
To unsubscribe send a blank email to %%email.unsub%%

Pain In The Asshole

----- Original Message -----
From: “Jos Scherders”
To: “NT Developers Interest List”
Sent: Wednesday, April 17, 2002 9:32 PM
Subject: [ntdev] Re: InterlockedExchange

> Hi,
>
> What is a PITA ? Never heard that one before :))
>
> Jos.
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to %%email.unsub%%
>

I knew this discussion will eventually end there…

However, google disagrees with you. See http://www.pita.org.fj/:

What is PITA?
The Pacific Islands Telecommunications Association (PITA) is a non-profit
organisation formed to represent the interests of small island nations in
the Pacific Region in the field of telecommunications.

Best regards,

Michal Vodicka
STMicroelectronics Design and Application s.r.o.
[michal.vodicka@st.com, http:://www.st.com]


From: xxxxx@storagecraft.com[SMTP:xxxxx@storagecraft.com]
Reply To: xxxxx@lists.osr.com
Sent: Wednesday, April 17, 2002 9:49 PM
To: xxxxx@lists.osr.com
Subject: [ntdev] Re: InterlockedExchange

Pain In The Asshole

----- Original Message -----
From: “Jos Scherders”
> To: “NT Developers Interest List”
> Sent: Wednesday, April 17, 2002 9:32 PM
> Subject: [ntdev] Re: InterlockedExchange
>
>
> > Hi,
> >
> > What is a PITA ? Never heard that one before :))
> >
> > Jos.
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
> —
> You are currently subscribed to ntdev as: michal.vodicka@st.com
> To unsubscribe send a blank email to %%email.unsub%%
>

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>
> > 1) KeAcquireInterruptSpinLock(…)
>
> Is it some new undocumented function from XP?
> It does not exported from kernel and HAL on w2k SP2.
> It does not documented in MSDN Library Jan 2002.
>
From Windows XP, Build 2600, NTDDK.H:

NTKERNELAPI
KIRQL
KeAcquireInterruptSpinLock (
IN PKINTERRUPT Interrupt
);

NTKERNELAPI
VOID
KeReleaseInterruptSpinLock (
IN PKINTERRUPT Interrupt,
IN KIRQL OldIrql
);

Peter
OSR

> From Windows XP, Build 2600, NTDDK.H:

NTKERNELAPI
KIRQL
KeAcquireInterruptSpinLock (
IN PKINTERRUPT Interrupt
);

Then let’s file a Bug Bash report on these functions not being documented in MSDN Library Jan 2002?

Max

Should these functions be treates as an alternative
to using KeSynchronizeExecution, however specific to
Windows XP?

Paul

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Peter Viscarola
Sent: Thursday, April 18, 2002 6:11 PM
To: NT Developers Interest List
Subject: [ntdev] Re: InterlockedExchange

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>
> > 1) KeAcquireInterruptSpinLock(…)
>
> Is it some new undocumented function from XP?
> It does not exported from kernel and HAL on w2k SP2.
> It does not documented in MSDN Library Jan 2002.
>
>From Windows XP, Build 2600, NTDDK.H:

NTKERNELAPI
KIRQL
KeAcquireInterruptSpinLock (
IN PKINTERRUPT Interrupt
);

NTKERNELAPI
VOID
KeReleaseInterruptSpinLock (
IN PKINTERRUPT Interrupt,
IN KIRQL OldIrql
);

Peter
OSR


You are currently subscribed to ntdev as: xxxxx@compelson.com
To unsubscribe send a blank email to %%email.unsub%%

Yup… You bet!

Everybody: If it’s in the header files, it SHOULD have an entry in the docs.
If there’s no entry, this is a legitimate bug, and needs to be filed against
the doc writers.

Peter
OSR

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
>
> > From Windows XP, Build 2600, NTDDK.H:
> >
> > NTKERNELAPI
> > KIRQL
> > KeAcquireInterruptSpinLock (
> > IN PKINTERRUPT Interrupt
> > );
>
> Then let’s file a Bug Bash report on these functions not being documented
in MSDN Library Jan 2002?
>
> Max
>
>
>