InterlockedExhangeAdd

Guys,
Working on a Sunday evening and just need the assembly
implementation for InterlockedExchangeAdd and an
equivalent function for substraction. Just porting
some stuff and changing some at the same time, so need
an OS independent x86 way of doing these things. Im no
asembly expert, so need some help.

For InterlockedExchangeAdd I have:
long InterlockedExchangeAdd(long * p_plValue, long
p_lAdd)
{
long l_lResult;
asm volatile (
“push %%EBX;”
“movl %1, %%EBX;”
“movl %2, %%EAX;”
“lock; xadd %%EAX, (%%EBX);”
“inc %%EAX;”
“mov %%EAX, %0;”
“pop %%EBX”
: “=g”(l_lResult) : “g”(p_plValue), “g”(p_lAdd) );
return l_lResult;
}

is that correct? Will it work on Linux correctly as in
it will add the new value and return the old value?

Also I need the substract equivalent of the above in
assembly, that will substract a value from the
variable atomically and return the old value. Can
someone please give me the asm source for that?

Thanks in advance folks,
Mark


Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Ntddk.h has assembly implementations of all of these functions defined
as inlines. I suppose you can borrow them. I don’t see any reason why
they wouldn’t work on other x86 operating systems as-is.

  • Nick Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Mark Lobo
Sent: Sunday, June 15, 2003 6:51 PM
To: NT Developers Interest List
Subject: [ntdev] InterlockedExhangeAdd

Guys,
Working on a Sunday evening and just need the assembly
implementation for InterlockedExchangeAdd and an equivalent
function for substraction. Just porting some stuff and
changing some at the same time, so need an OS independent x86
way of doing these things. Im no asembly expert, so need some help.

For InterlockedExchangeAdd I have:
long InterlockedExchangeAdd(long * p_plValue, long
p_lAdd)
{
long l_lResult;
asm volatile (
“push %%EBX;”
“movl %1, %%EBX;”
“movl %2, %%EAX;”
“lock; xadd %%EAX, (%%EBX);”
“inc %%EAX;”
“mov %%EAX, %0;”
“pop %%EBX”
: “=g”(l_lResult) : “g”(p_plValue), “g”(p_lAdd) );
return l_lResult;
}

is that correct? Will it work on Linux correctly as in
it will add the new value and return the old value?

Also I need the substract equivalent of the above in
assembly, that will substract a value from the
variable atomically and return the old value. Can
someone please give me the asm source for that?

Thanks in advance folks,
Mark


Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month! http://sbc.yahoo.com


You are currently subscribed to ntdev as: xxxxx@nryan.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Yeah, but NT doesnt have an InterlockedExchangeSub.
Would the only difference be using a subl instead of
xadd?

— Nick Ryan wrote:
> Ntddk.h has assembly implementations of all of these
> functions defined
> as inlines. I suppose you can borrow them. I don’t
> see any reason why
> they wouldn’t work on other x86 operating systems
> as-is.
>
> - Nick Ryan
>
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com] On
> Behalf Of Mark Lobo
> > Sent: Sunday, June 15, 2003 6:51 PM
> > To: NT Developers Interest List
> > Subject: [ntdev] InterlockedExhangeAdd
> >
> >
> > Guys,
> > Working on a Sunday evening and just need the
> assembly
> > implementation for InterlockedExchangeAdd and an
> equivalent
> > function for substraction. Just porting some stuff
> and
> > changing some at the same time, so need an OS
> independent x86
> > way of doing these things. Im no asembly expert,
> so need some help.
> >
> > For InterlockedExchangeAdd I have:
> > long InterlockedExchangeAdd(long * p_plValue, long
> > p_lAdd)
> > {
> > long l_lResult;
> > asm volatile (
> > “push %%EBX;”
> > “movl %1, %%EBX;”
> > “movl %2, %%EAX;”
> > “lock; xadd %%EAX, (%%EBX);”
> > “inc %%EAX;”
> > “mov %%EAX, %0;”
> > “pop %%EBX”
> > : “=g”(l_lResult) : “g”(p_plValue),
> “g”(p_lAdd) );
> > return l_lResult;
> > }
> >
> > is that correct? Will it work on Linux correctly
> as in
> > it will add the new value and return the old
> value?
> >
> > Also I need the substract equivalent of the above
> in
> > assembly, that will substract a value from the
> > variable atomically and return the old value. Can
> > someone please give me the asm source for that?
> >
> > Thanks in advance folks,
> > Mark
> >
> >
> > Do you Yahoo!?
> > SBC Yahoo! DSL - Now only $29.95 per month!
> http://sbc.yahoo.com
> >
> >
> > —
> > You are currently subscribed to ntdev as:
> xxxxx@nryan.com
> > To unsubscribe send a blank email to
> xxxxx@lists.osr.com
> >
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
xxxxx@lists.osr.com


Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

xxxxx@sneakemail.com said:

Yeah, but NT doesnt have an InterlockedExchangeSub. Would the only
difference be using a subl instead of xadd?

Add -1?


Steve Williams “The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep.”

Its substracting a value, not decrementing by 1.
The API I want is:
InterlockedExchangeAdd(long *variable. long value)
Adds value to variable and returns the old value of
variable.

InterlockedExchangeSub(long *variable. long value)
Subs value from variable and returns the old value of
variable.

Maybe its assembly 101:) But I dont know know anything
but 8086 and that I had done ages back.
So Is the source I originally showed alright? And how
do I change it to use it like InterlockedExchangeSub?
I would appreciate any help! I normally dont ask for
the source, but can someone give me the asm source? I
think the one I have below is ok. I did look in
ntddk.h and it did have InterLockedExchangeAdd, and I
guess I just can use it?

and what do I change for the substract operation
because there is no InterlockedExchangedSub cause NT
does not support it that oprtation?

Thanks,
Mark

— Stephen Williams
wrote:
>
> xxxxx@sneakemail.com said:
> > Yeah, but NT doesnt have an
> InterlockedExchangeSub. Would the only
> > difference be using a subl instead of xadd?
>
> Add -1?
>
> –
> Steve Williams “The woods are lovely,
> dark and deep.
> steve at icarus.com But I have promises to
> keep,
> http://www.icarus.com and lines to code
> before I sleep,
> http://www.picturel.com And lines to code
> before I sleep.”
>
>
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
xxxxx@lists.osr.com

__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

The below code works for single processor. Add lock prefix to xadd
instruction for multiprocessor.

LONG
InterlockedExchangeAdd(PLONG variable, LONG value)
{
LONG RetVal;
_asm {
mov eax, value
mov ecx, variable
xadd [ecx], eax
mov RetVal, eax
}

return RetVal;
}

-Srin.

-----Original Message-----
From: Mark Lobo [mailto:xxxxx@yahoo.com]
Sent: Sunday, June 15, 2003 10:32 PM
To: NT Developers Interest List
Subject: [ntdev] RE: InterlockedExhangeAdd

Its substracting a value, not decrementing by 1.
The API I want is:
InterlockedExchangeAdd(long *variable. long value)
Adds value to variable and returns the old value of
variable.

InterlockedExchangeSub(long *variable. long value)
Subs value from variable and returns the old value of
variable.

Maybe its assembly 101:) But I dont know know anything
but 8086 and that I had done ages back.
So Is the source I originally showed alright? And how
do I change it to use it like InterlockedExchangeSub?
I would appreciate any help! I normally dont ask for
the source, but can someone give me the asm source? I
think the one I have below is ok. I did look in
ntddk.h and it did have InterLockedExchangeAdd, and I
guess I just can use it?

and what do I change for the substract operation
because there is no InterlockedExchangedSub cause NT
does not support it that oprtation?

Thanks,
Mark

— Stephen Williams
> wrote:
> >
> > xxxxx@sneakemail.com said:
> > > Yeah, but NT doesnt have an
> > InterlockedExchangeSub. Would the only
> > > difference be using a subl instead of xadd?
> >
> > Add -1?
> >
> > –
> > Steve Williams “The woods are lovely,
> > dark and deep.
> > steve at icarus.com But I have promises to
> > keep,
> > http://www.icarus.com and lines to code
> > before I sleep,
> > http://www.picturel.com And lines to code
> > before I sleep.”
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as:
> > xxxxx@yahoo.com
> > To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>
>
> __________________________________
> Do you Yahoo!?
> SBC Yahoo! DSL - Now only $29.95 per month!
> http://sbc.yahoo.com
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@nai.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com

To subtract, simply add the negation of the value you wish to subtract:

long InterlockedExchangeSub(long *variable. long value)
{
return InterlockedExchangeAdd(variable, -value);
}

Chuck

----- Original Message -----
From: “Mark Lobo”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 12:32 PM
Subject: [ntdev] RE: InterlockedExhangeAdd

>
> Its substracting a value, not decrementing by 1.
> The API I want is:
> InterlockedExchangeAdd(long *variable. long value)
> Adds value to variable and returns the old value of
> variable.
>
> InterlockedExchangeSub(long *variable. long value)
> Subs value from variable and returns the old value of
> variable.
>
> Maybe its assembly 101:) But I dont know know anything
> but 8086 and that I had done ages back.
> So Is the source I originally showed alright? And how
> do I change it to use it like InterlockedExchangeSub?
> I would appreciate any help! I normally dont ask for
> the source, but can someone give me the asm source? I
> think the one I have below is ok. I did look in
> ntddk.h and it did have InterLockedExchangeAdd, and I
> guess I just can use it?
>
> and what do I change for the substract operation
> because there is no InterlockedExchangedSub cause NT
> does not support it that oprtation?
>
> Thanks,
> Mark

Im sorry for such a stupid question, but this doesnt
compile. I am extremely bad at assembly syntax:) This
might complile on Windows, but does not on Linux cause
I guess assembler syntax is diff?? Do I sound like
some dumb ass fool here?:slight_smile: .
Lemme give you the atomic_dec example on Linux:

static inline void atomic_dec(atomic_t *v)
{
asm volatile(
LOCK “decl %0”
:“=m” (v->counter)
:“m” (v->counter));
}

where
typedef struct { volatile int counter; } atomic_t;

I tried a bunch of things, like putting quotes, but
didnt work.

Thanks,
Mark

xxxxx@NAI.com wrote:

The below code works for single processor. Add lock
prefix to xadd
instruction for multiprocessor.

LONG
InterlockedExchangeAdd(PLONG variable, LONG value)
{
LONG RetVal;
_asm {
mov eax, value
mov ecx, variable
xadd [ecx], eax
mov RetVal, eax
}

return RetVal;
}

-Srin.

> -----Original Message-----
> From: Mark Lobo [mailto:xxxxx@yahoo.com]
> Sent: Sunday, June 15, 2003 10:32 PM
> To: NT Developers Interest List
> Subject: [ntdev] RE: InterlockedExhangeAdd
>
>
> Its substracting a value, not decrementing by 1.
> The API I want is:
> InterlockedExchangeAdd(long *variable. long value)
> Adds value to variable and returns the old value
of
> variable.
>
> InterlockedExchangeSub(long *variable. long value)
> Subs value from variable and returns the old value
of
> variable.
>
> Maybe its assembly 101:) But I dont know know
anything
> but 8086 and that I had done ages back.
> So Is the source I originally showed alright? And
how
> do I change it to use it like
InterlockedExchangeSub?
> I would appreciate any help! I normally dont ask
for
> the source, but can someone give me the asm
source? I
> think the one I have below is ok. I did look in
> ntddk.h and it did have InterLockedExchangeAdd,
and I
> guess I just can use it?
>
> and what do I change for the substract operation
> because there is no InterlockedExchangedSub cause
NT
> does not support it that oprtation?
>
> Thanks,
> Mark
>
> — Stephen Williams
> > wrote:
> > >
> > > xxxxx@sneakemail.com said:
> > > > Yeah, but NT doesnt have an
> > > InterlockedExchangeSub. Would the only
> > > > difference be using a subl instead of xadd?
> > >
> > > Add -1?
> > >
> > > –
> > > Steve Williams “The woods are
> lovely,
> > > dark and deep.
> > > steve at icarus.com But I have
> promises to
> > > keep,
> > > http://www.icarus.com and lines to code
> > > before I sleep,
> > > http://www.picturel.com And lines to code
> > > before I sleep.”
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as:
> > > xxxxx@yahoo.com
> > > To unsubscribe send a blank email to
> > xxxxx@lists.osr.com
> >
> >
> >
> > Do you Yahoo!?
> > SBC Yahoo! DSL - Now only $29.95 per month!
> > http://sbc.yahoo.com
> >
> >
> > —
> > You are currently subscribed to ntdev as:
> xxxxx@nai.com
> > To unsubscribe send a blank email to
> xxxxx@lists.osr.com
>
>
> —
> You are currently subscribed to ntdev as:
> xxxxx@yahoo.com
> To unsubscribe send a blank email to
xxxxx@lists.osr.com


Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com

Yes, the assembler syntax used by the Linux world is completely different
than that used by the MS world. I’ve seen examples of the Linux stuff a few
times, but I can’t help you on how to make it work. I’m not even sure which
order the operands go in, but it appears to be the reverse of how the
instructions actually work.

If you have the atomic add inline working, why not just add the inline
wrapper function that negates the value for the atomic sub, and let the
compiler figure out how to generate the code? That’s what compilers are
for!

Loren

http://linuxassembly.org might help

Amit Manocha

“Mark Lobo” wrote in message news:xxxxx@ntdev…
>
> Guys,
> Working on a Sunday evening and just need the assembly
> implementation for InterlockedExchangeAdd and an
> equivalent function for substraction. Just porting
> some stuff and changing some at the same time, so need
> an OS independent x86 way of doing these things. Im no
> asembly expert, so need some help.
>
> For InterlockedExchangeAdd I have:
> long InterlockedExchangeAdd(long * p_plValue, long
> p_lAdd)
> {
> long l_lResult;
> asm volatile (
> “push %%EBX;”
> “movl %1, %%EBX;”
> “movl %2, %%EAX;”
> “lock; xadd %%EAX, (%%EBX);”
> “inc %%EAX;”
> “mov %%EAX, %0;”
> “pop %%EBX”
> : “=g”(l_lResult) : “g”(p_plValue), “g”(p_lAdd) );
> return l_lResult;
> }
>
> is that correct? Will it work on Linux correctly as in
> it will add the new value and return the old value?
>
> Also I need the substract equivalent of the above in
> assembly, that will substract a value from the
> variable atomically and return the old value. Can
> someone please give me the asm source for that?
>
> Thanks in advance folks,
> Mark
>
> __________________________________
> Do you Yahoo!?
> SBC Yahoo! DSL - Now only $29.95 per month!
> http://sbc.yahoo.com
>
>
>

> _asm {

mov eax, value
mov ecx, variable
xadd [ecx], eax
mov RetVal, eax
}

Gee, assembler language. I feel like I’m back in the 70’s…

You guys DO realize, of course, that all this embedded assembler won’t work
when you move your drivers to the AMD64 – which, before you say anything,
is turning out to be one HECK of a great desktop system… And, of course,
it won’t work on the Itanium either, if you care.

So, you might have a multi-O/S compliant solution, but one that won’t even
work on all Windows platforms.

Embedded _asm is evil,

Peter
OSR

When we need that kind of code, the only replacement to embedded assembler
is a language standard that includes the facility we need. OS calls are not
the answer. But C doesn’t have the equivalent of an interlocked add, I wish
they had some facility to guarantee atomic behavior, for example, a square
bracket instead of a curly bracket would do, or maybe angle brackets, or
even a double bracket:

[myvar += mybumpvalue;]
< myvar += mybumpvalue; >
{{ myvar += mybumpvalue; }}

That of course allows the programmer to specify atomic blocks, not just
statements - and I mean atomic, that is, multiprocessor safe. And who cares
how the OS implements it.

Meanwhile, you guys DO realize, of course, :-), that not every call works on
every OS. Using pure, standard C or C++ makes your code more robust by
avoiding OS dependencies; and when the language doesn’t have the facilities
to do what we want, machine code is the way to go. The ideal OS isn’t the
one that has a call for everything, but the one that you take for granted
and that has a minimalist set of features that’s not expressable in a bog
standard way from inside the high level language we’re using.

And you know what, if I have to choose between feeding the hardware or the
OS trolls, I’ll choose the hardware 100% of the time !

Alberto.

-----Original Message-----
From: Peter Viscarola [mailto:xxxxx@osr.com]
Sent: Monday, June 16, 2003 9:45 AM
To: NT Developers Interest List
Subject: [ntdev] Re: InterlockedExhangeAdd

_asm {
mov eax, value
mov ecx, variable
xadd [ecx], eax
mov RetVal, eax
}

Gee, assembler language. I feel like I’m back in the 70’s…

You guys DO realize, of course, that all this embedded assembler won’t work
when you move your drivers to the AMD64 – which, before you say anything,
is turning out to be one HECK of a great desktop system… And, of course,
it won’t work on the Itanium either, if you care.

So, you might have a multi-O/S compliant solution, but one that won’t even
work on all Windows platforms.

Embedded _asm is evil,

Peter
OSR


You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

I can’t resist a bit of mischief.

Whenever I mention 64-bit machines to people developing actual
production code – this happened last week, for example – I get a
“Yeah, but we don’t see a need anytime soon; all our customers and their
desktops and their servers are 32-bit.” I started talking about 64-bit
support in my project’s code in 1999, and then, as now, all I’ve gotten
from the people on the ground is a yawn.


If replying by e-mail, please remove “nospam.” from the address.

James Antognini

Assembler syntax will depend on the compiler, not the OS (given we’re
already talking about the same CPU architecture). The syntax he’s using
looks like GNU C.

Chuck

----- Original Message -----
From: “Loren Wilton”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 2:40 PM
Subject: [ntdev] RE: InterlockedExhangeAdd

> Yes, the assembler syntax used by the Linux world is completely
different
> than that used by the MS world. I’ve seen examples of the Linux stuff
a few
> times, but I can’t help you on how to make it work. I’m not even sure
which
> order the operands go in, but it appears to be the reverse of how the
> instructions actually work.
>
> If you have the atomic add inline working, why not just add the inline
> wrapper function that negates the value for the atomic sub, and let
the
> compiler figure out how to generate the code? That’s what compilers
are
> for!
>
> Loren

“James Antognini” wrote in message
news:xxxxx@ntdev…
>
> I can’t resist a bit of mischief.
>

Bring it! I’m always up for the fun…

>
> I started talking about 64-bit
> support in my project’s code in 1999, and then, as now, all I’ve gotten
> from the people on the ground is a yawn.
>

Well, that’s because back in 1999 it deserved a yawn.

What’s changing all that is the AMD64, which rocks running ordinary 32-bit
applications without recompiling, cuz there’s emulation or translation to
perform.

Now that there’s a viable platform that doesn’t require every single piece
of existing software to be re-written, we driver devs have to step up and
get our stuff working on 64-bit Windows.

We’ve already started here at OSR. One of our tool kits took, oh, less than
an hour to port and validate (we had a couple of cases where we cast
poitners to ULONGS… you change the ULONG to ULONG_PTR and your done). So,
the porting is easy.

Spread the word!

Peter
OSR

>To subtract, simply add the negation of the value you wish to subtract:

I was getting a little worried… I’m glad at least someone figured this
out! :slight_smile:

Mat

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Monday, June 16, 2003 2:13 AM
To: NT Developers Interest List
Subject: [ntdev] RE: InterlockedExhangeAdd

To subtract, simply add the negation of the value you wish to subtract:

long InterlockedExchangeSub(long *variable. long value)
{
return InterlockedExchangeAdd(variable, -value);
}

Chuck

----- Original Message -----
From: “Mark Lobo”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 12:32 PM
Subject: [ntdev] RE: InterlockedExhangeAdd

>
> Its substracting a value, not decrementing by 1.
> The API I want is:
> InterlockedExchangeAdd(long *variable. long value)
> Adds value to variable and returns the old value of
> variable.
>
> InterlockedExchangeSub(long *variable. long value)
> Subs value from variable and returns the old value of
> variable.
>
> Maybe its assembly 101:) But I dont know know anything
> but 8086 and that I had done ages back.
> So Is the source I originally showed alright? And how
> do I change it to use it like InterlockedExchangeSub?
> I would appreciate any help! I normally dont ask for
> the source, but can someone give me the asm source? I
> think the one I have below is ok. I did look in
> ntddk.h and it did have InterLockedExchangeAdd, and I
> guess I just can use it?
>
> and what do I change for the substract operation
> because there is no InterlockedExchangedSub cause NT
> does not support it that oprtation?
>
> Thanks,
> Mark


You are currently subscribed to ntdev as: xxxxx@guillemot.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Are you SURE you want the “inc %%EAX”? That looks suspicious to me.
Also, you should read the GNU C docs on inline assembly syntax. By
specifying more precise register descriptions, you can get more
efficient code generation by having the compiler do the work of making
sure parameters are already in the correct registers before the assembly
code is executed, and by telling the compiler which register the result
is left in. Incidentally, inline assembly in GNU C is nice that way.
Read this:

http://www-106.ibm.com/developerworks/linux/library/l-ia.html?dwzone=lin
ux

And try this:

long InterlockedExchangeAdd(long * p_plValue, long p_lAdd)
{
/* Try doing this in Visual C! */
asm volatile ( “lock; xadd %0, (%1);” : “=r”(p_lAdd) :
“r”(p_plValue), “0”(p_lAdd) );
return p_lAdd;
}

However, this isn’t entirely complete. You may run into problems due to
optimization if the compiler doesn’t realize that the memory pointed to
by p_plValue has been modified. You can take care of this in one of two
ways:

  1. Make sure all your synchronization variables are declared volatile.
  2. Specify memory as a clobbered item in the inline assembly (sorry,
    don’t recall the syntax for this).

#1 is better because last time I checked, there wasn’t a way to specify
what memory exactly was clobbered, so specifying memory in general as
a clobbered item will force the compiler to reload all memory variables,
generally something you want to avoid. Not that the x86 has a whole lot
of registers…

Chuck

----- Original Message -----
From: “Mark Lobo”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 8:50 AM
Subject: [ntdev] InterlockedExhangeAdd

> Guys,
> Working on a Sunday evening and just need the assembly
> implementation for InterlockedExchangeAdd and an
> equivalent function for substraction. Just porting
> some stuff and changing some at the same time, so need
> an OS independent x86 way of doing these things. Im no
> asembly expert, so need some help.
>
> For InterlockedExchangeAdd I have:
> long InterlockedExchangeAdd(long * p_plValue, long
> p_lAdd)
> {
> long l_lResult;
> asm volatile (
> “push %%EBX;”
> “movl %1, %%EBX;”
> “movl %2, %%EAX;”
> “lock; xadd %%EAX, (%%EBX);”
> “inc %%EAX;”
> “mov %%EAX, %0;”
> “pop %%EBX”
> : “=g”(l_lResult) : “g”(p_plValue), “g”(p_lAdd) );
> return l_lResult;
> }
>
> is that correct? Will it work on Linux correctly as in
> it will add the new value and return the old value?
>
> Also I need the substract equivalent of the above in
> assembly, that will substract a value from the
> variable atomically and return the old value. Can
> someone please give me the asm source for that?
>
> Thanks in advance folks,
> Mark

I should correct myself. Assembler syntax will actually depend on the
underlying assembler the compiler uses, should it use one.

Chuck

----- Original Message -----
From: “Chuck Batson”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 10:44 PM
Subject: [ntdev] RE: InterlockedExhangeAdd

> Assembler syntax will depend on the compiler, not the OS (given we’re
> already talking about the same CPU architecture). The syntax he’s
using
> looks like GNU C.
>
> Chuck

> >To subtract, simply add the negation of the value you wish to
subtract:

I was getting a little worried… I’m glad at least someone figured
this
out! :slight_smile:

As long as you’re using a 2’s complement binary machine where arithmetic
is performed modulo 2 ^ n, this should would, last time I checked…
=^)

Chuck

You can look at the Linux source code for a couple of examples of using xadd
with the GNU C asm syntax: if you go to

http://lxr.linux.no

and go to file rwsem.h, take a look at __down_write() on line 147 or
__up_read on line 187. Use the source, Luke !

Alberto.

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Monday, June 16, 2003 12:21 PM
To: NT Developers Interest List
Subject: [ntdev] Re: InterlockedExhangeAdd

Are you SURE you want the “inc %%EAX”? That looks suspicious to me.
Also, you should read the GNU C docs on inline assembly syntax. By
specifying more precise register descriptions, you can get more
efficient code generation by having the compiler do the work of making
sure parameters are already in the correct registers before the assembly
code is executed, and by telling the compiler which register the result
is left in. Incidentally, inline assembly in GNU C is nice that way.
Read this:

http://www-106.ibm.com/developerworks/linux/library/l-ia.html?dwzone=lin
ux

And try this:

long InterlockedExchangeAdd(long * p_plValue, long p_lAdd)
{
/* Try doing this in Visual C! */
asm volatile ( “lock; xadd %0, (%1);” : “=r”(p_lAdd) :
“r”(p_plValue), “0”(p_lAdd) );
return p_lAdd;
}

However, this isn’t entirely complete. You may run into problems due to
optimization if the compiler doesn’t realize that the memory pointed to
by p_plValue has been modified. You can take care of this in one of two
ways:

  1. Make sure all your synchronization variables are declared volatile.
  2. Specify memory as a clobbered item in the inline assembly (sorry,
    don’t recall the syntax for this).

#1 is better because last time I checked, there wasn’t a way to specify
what memory exactly was clobbered, so specifying memory in general as
a clobbered item will force the compiler to reload all memory variables,
generally something you want to avoid. Not that the x86 has a whole lot
of registers…

Chuck

----- Original Message -----
From: “Mark Lobo”
To: “NT Developers Interest List”
Sent: Monday, June 16, 2003 8:50 AM
Subject: [ntdev] InterlockedExhangeAdd

> Guys,
> Working on a Sunday evening and just need the assembly
> implementation for InterlockedExchangeAdd and an
> equivalent function for substraction. Just porting
> some stuff and changing some at the same time, so need
> an OS independent x86 way of doing these things. Im no
> asembly expert, so need some help.
>
> For InterlockedExchangeAdd I have:
> long InterlockedExchangeAdd(long * p_plValue, long
> p_lAdd)
> {
> long l_lResult;
> asm volatile (
> “push %%EBX;”
> “movl %1, %%EBX;”
> “movl %2, %%EAX;”
> “lock; xadd %%EAX, (%%EBX);”
> “inc %%EAX;”
> “mov %%EAX, %0;”
> “pop %%EBX”
> : “=g”(l_lResult) : “g”(p_plValue), “g”(p_lAdd) );
> return l_lResult;
> }
>
> is that correct? Will it work on Linux correctly as in
> it will add the new value and return the old value?
>
> Also I need the substract equivalent of the above in
> assembly, that will substract a value from the
> variable atomically and return the old value. Can
> someone please give me the asm source for that?
>
> Thanks in advance folks,
> Mark


You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.