2002-06-03 14:59:41

by Gregory Giguashvili

[permalink] [raw]
Subject: Atomic operations

Hello,

I forgot to add that I know that it can be implemented using XCHG and LOCK
operations. However, I'm not an expert in ASM, so I was hoping somebody
would help me...

Thanks
Giga


2002-06-03 18:10:57

by Gregory Giguashvili

[permalink] [raw]
Subject: RE: Atomic operations

Peter,

Thanks a lot for your help.

> atomic_t test_then_add (int i, atomic_t* v)
> {
> atomic_t old = *v;
> v->counter += i;
> return old;
> }
> There is no way to do this (without waiting and trying again type
> code) that I know of on i386. However, you can test for zeroness of
> the result, or for <= 0, or a few other options.

Could you, please, clarify what you meant saying that there was no way of
doing so. I admit, I'm no expert in i386 assembly, but this operation seems
so simple to me...

Could you, please, suggest some other implementation (with waiting and
trying again - whatever this means)?

test_and_set and test_then_add functions are coming from code written for
IRIX. Solaris has similar functionality. Windows NT also provides these
primitives in Win32 API (possibly implemented not in the most effective way,
according to what you say). The only OS where they are missing is Linux.

Unfortunately, these primitives became an integral part of our code, which
makes it very painful to change their behavior.

Thanks in advance.
Giga

2002-06-03 18:43:36

by H. Peter Anvin

[permalink] [raw]
Subject: Re: Atomic operations

Followup to: <EE83E551E08D1D43AD52D50B9F5110927E7A15@ntserver2>
By author: Gregory Giguashvili <[email protected]>
In newsgroup: linux.dev.kernel
>
> Could you, please, clarify what you meant saying that there was no way of
> doing so. I admit, I'm no expert in i386 assembly, but this operation seems
> so simple to me...
>

That doesn't mean the hardware is going to provide it atomically.

>
> Could you, please, suggest some other implementation (with waiting and
> trying again - whatever this means)?
>

Very simple:

- Set a spinlock (note: you need a spinlock variable)
- Read
- Add
- Clear spinlock

This is called "bootstrapping" -- using a more primitive atomic
operation to get what you need.

-hpa
--
<[email protected]> at work, <[email protected]> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt <[email protected]>

2002-06-04 08:25:02

by Gregory Giguashvili

[permalink] [raw]
Subject: RE: Atomic operations

Hello,

Thanks a lot for your help to all of you...

The last thing, I want to make sure of, is that the following type of code:

int atomic_xadd(int i, atomic_t *v)
{
int ret;
__asm__(LOCK "xaddl %1,%0"
: "=m" (v->counter), "=r" (ret)
: "0" (v->counter), "1" (i));
return ret;
}

is less efficient than this one:

int atomic_xadd(int i, atomic_t *v)
{
asm volatile(LOCK "xaddl %1,%0"
: "+m" (v->counter), "+r" (i));
return i;
}

The reason for it is that the first one is more easy to read (at least for
me as a beginner).

Thanks again for your precious comments.
Best,
Giga