Skip to contentSkip to conversation

Having linking problems with atomic_inc(), atomic_dec_and_test() in user app, help!

DISCUSSION jaf 6 participants 7 messages Jan 4, 2002

lore
Share & tools
lore

jaf

author
#0 lore raw

Hi Michael,

Quoted 1 line
Quoted 1 line

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

Quoted 2 lines

Why do you think you need to use atomic_inc directly instead of some pthreads wrapper?

I wasn't able to find a decent equivalent to atomic_t in the pthreads API.
The closest thing I could see would be to wrap my counter increments/ decrements in a pthread_mutex_t to serialize them, but creating a separate mutex for each atomic counter seems a bit expensive/ inefficient, considering there may be thousands of such atomic counters active at once. Is there some other way to use pthreads to get an atomic counter? Or is a pthread_mutex_t really efficient enough to make a decent atomic counter out of? Or do I need to redesign how my application works, because there is no good way to do a cheap, portable user-land atomic counter under Linux? :^(

Jeremy

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#1 lore raw
Quoted 7 lines
Quoted 2 lines
Quoted 2 lines

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 8 lines
Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

It's a kernel or libc header issue - what kernel/libc version was that on? As far as I can see atomic operations are exported to user programs except on ppc (not ppc64), mips*, arm and sparc. At least in one case it's obvious why: MIPS needs to protect against interrupts to guarantee atomicity.
Another corner case seems to be IBM 405 processors that use what I think is a privileged instruction as well in order to work around a hardware bug.

Quoted 5 lines
Quoted 2 lines

Why do you think you need to use atomic_inc directly instead of some pthreads wrapper?

I wasn't able to find a decent equivalent to atomic_t in the pthreads API.

pthreadss only came to mind first, there may be other packages. Point being, on those architectures that cannot guarantee atomic operations using nonprovileged instructions there has to be some sort of kernel cooperation (system call?).

Quoted 6 lines

The closest thing I could see would be to wrap my counter increments/ decrements in a pthread_mutex_t to serialize them, but creating a separate mutex for each atomic counter seems a bit expensive/ inefficient, considering there may be thousands of such atomic counters active at once. Is there some other way to use pthreads to get an atomic counter? Or is a pthread_mutex_t really efficient enough to

I have no experience with pthreads, sorry.

Quoted 3 lines

make a decent atomic counter out of? Or do I need to redesign how my application works, because there is no good way to do a cheap, portable user-land atomic counter under Linux? :^(

Worst-case? The latter. At least for MIPS there doesn't seem to be such a thing as atomic user land operations. How they would implement a mutex without those, I wonder ...

You can try to copy the atomic ops from the kernel headers for those architectures lacking them, hoping it won't break. If it doesn't, you have a good argument in favor of removing the #ifdef __KERNEL__ :-)

Michael

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#2 lore raw
Quoted 7 lines · Michael Schmitz
Quoted 7 lines
Quoted 2 lines
Quoted 2 lines

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 8 lines
Quoted 8 lines
Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

A userspace app using <asm/*.h> and <linux/*.h> is quite probably a bug. If you need something from the kernel, make a local copy and never, ever, ever, reference it directly, since it can change on you.

--
Tom Rini (TR1265)
http://gate.crashing.org/~trini/

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#3 lore raw

Re: Having linking problems with atomic_inc(), atomic_dec_and_test()in user app, help!

In reply to Michael Schmitz
Quoted 16 lines · Michael Schmitz
Quoted 7 lines
Quoted 2 lines
Quoted 2 lines

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 8 lines
Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

Quoted 8 lines

It's a kernel or libc header issue - what kernel/libc version was that on? As far as I can see atomic operations are exported to user programs except on ppc (not ppc64), mips*, arm and sparc. At least in one case it's obvious why: MIPS needs to protect against interrupts to guarantee atomicity.
Another corner case seems to be IBM 405 processors that use what I think is a privileged instruction as well in order to work around a hardware bug.

The dcbt instruction (the workaround) should not be privileged.

< stuff deleted >

-Frank
--
Frank Rowand <[email protected]>
MontaVista Software, Inc

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#4 lore raw

Re: Having linking problems with atomic_inc(), atomic_dec_and_test()in user app, help!

Quoted 6 lines
Quoted 4 lines

Another corner case seems to be IBM 405 processors that use what I think is a privileged instruction as well in order to work around a hardware bug.

The dcbt instruction (the workaround) should not be privileged.

Thanks; anything not using syncs should be fine then?

Michael

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#5 lore raw
In reply to jaf

Hi,

There are a number of places you can get atomic increment and decrement code:

1. borrow the implementations from the kernel

2. look at www.openOffice.org CVS sal/osl/unx/interlck.c for atomic increment and decrement code for both x86 linux and ppc linux, and the proper includes for Solaris.

3. adapt the code from glibc-2.2.4/linuxthreads/sysdeps/powerpc/pt-machine.h for "compare _and_swap" and "test_and_set" t do your own "dec_and_test"

4. simply use a pthread mutex to protect the counter (complete overkill)

5. look at the implementations of these synchronization functions in the IBM/Motorola PowerPC Microprocessor Family: The Programming Environment" manual (available as a pdf from the Motorola site). They have implementations for "Fetch and Add", "Test and Set" , "Compare and Swap" "Lock Acquisition and Release" and "List Insertion"

I personally recommend using the code from interlck.c from OpenOffice as your guide and falling back to using a mutex to protect the count for unknown processors. That way it will always work but if performance is an issue, someone can add the support for other processors. This is what OpenOffice does for its refernce counted strings.

Hope this helps,

Kevin

Quoted 26 lines · jaf

Hi Michael,

Quoted 1 line
Quoted 1 line

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

Quoted 2 lines

Why do you think you need to use atomic_inc directly instead of some pthreads wrapper?

Quoted 11 lines

I wasn't able to find a decent equivalent to atomic_t in the pthreads API.
The closest thing I could see would be to wrap my counter increments/ decrements in a pthread_mutex_t to serialize them, but creating a separate mutex for each atomic counter seems a bit expensive/ inefficient, considering there may be thousands of such atomic counters active at once. Is there some other way to use pthreads to get an atomic counter? Or is a pthread_mutex_t really efficient enough to make a decent atomic counter out of? Or do I need to redesign how my application works, because there is no good way to do a cheap, portable user-land atomic counter under Linux? :^(

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#6 lore raw

Hi,

One other thing, PPC implements synchronization using a reservation bit for specific address with a special instruction pair that sets and clears the reservation. But the address to set/clear the reservation on is only unique down the the cache line size (in most cases 32 bytes for ppc) i.e. the reservation granularity.

In English, what this means is that if two counters you want to atomically increment or decrement are stored within 32 bytes of each other and different threads are simulataneously trying to increment or decrement them, the reservation can get spurious clears that prevents either one from working without more looping (i.e performance starts to suffer).

In practive I have very very rarely ever seen this problem have an impact on anything. Others may know more.

Hope this helps,

Kevin

Quoted 29 lines · Kevin B. Hendricks

Hi,

There are a number of places you can get atomic increment and decrement code:

1. borrow the implementations from the kernel

2. look at www.openOffice.org CVS sal/osl/unx/interlck.c for atomic increment and decrement code for both x86 linux and ppc linux, and the proper includes for Solaris.

3. adapt the code from glibc-2.2.4/linuxthreads/sysdeps/powerpc/pt-machine.h for "compare _and_swap" and "test_and_set" t do your own "dec_and_test"

4. simply use a pthread mutex to protect the counter (complete overkill)

5. look at the implementations of these synchronization functions in the IBM/Motorola PowerPC Microprocessor Family: The Programming Environment" manual (available as a pdf from the Motorola site). They have implementations for "Fetch and Add", "Test and Set" , "Compare and Swap" "Lock Acquisition and Release" and "List Insertion"

I personally recommend using the code from interlck.c from OpenOffice as your guide and falling back to using a mutex to protect the count for unknown processors. That way it will always work but if performance is an issue, someone can add the support for other processors. This is what OpenOffice does for its refernce counted strings.

Quoted 43 lines

Hope this helps,

Kevin

Quoted 37 lines · jaf

Hi Michael,

Quoted 1 line
Quoted 1 line

Also, what does "relocation truncated to fit: R_PPC_REL24

atomic_inc(atomic_t

Quoted 3 lines
Quoted 1 line

*)" mean?

About as much as 'unresolved external reference'. atomic_inc isn't

defined

Quoted 1 line

in the scope of your code. Look at the kernel headers; it might be

inside

Quoted 1 line

#ifdef __KRENEL__ (actually it is).

I see... when I wrote the code using Red Hat, this was not the case. I assumed
things would be similar under all Linuxes... apparently a bad assumption.

Quoted 2 lines

Why do you think you need to use atomic_inc directly instead of some pthreads wrapper?

I wasn't able to find a decent equivalent to atomic_t in the pthreads API.
The closest thing I could see would be to wrap my counter increments/ decrements in a pthread_mutex_t to serialize them, but creating a separate mutex for each atomic counter seems a bit expensive/ inefficient, considering there may be thousands of such atomic counters active at once. Is there some other way to use pthreads to get an atomic counter? Or is a pthread_mutex_t really efficient enough to make a decent atomic counter out of? Or do I need to redesign how my application works, because there is no good way to do a cheap, portable user-land atomic counter under Linux? :^(

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/