Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - atomic_read() equivalent mechanism in QNX: (15 Items)
   
atomic_read() equivalent mechanism in QNX  
Hello friends,

I am using atomic operations provided by the QNX to change and access (or check) variable value between two threads... 
Here is pseudo implementation of my case.

volatile unsigned digit;

thread_1()
{
       while(1) {
           if(digit > 10)
               break;
           else
              ....
       }
   ...
}

thread_2()
{
       while(1) {
           delay(10);

           atomic_add(&digit, 1);
       }
   ...
}


Now, As far as I know there isn't any function (like atomic_read() in Linux) to read and then test variable atomically 
which I can use for checking "digit" value in "If statement" in thread_1.

So, please anyone tell me, is it enough what I have done in above case or do I have to use other synchronization 
mechanism like mutex or spinlock?


Thank you very much
Apurva

Re: atomic_read() equivalent mechanism in QNX  
For the example provided you do not need atomic operations. You need them neither for reading nor for writing as there 
is just one thread writing and and anoth one thread reading and value being read may be safely re-read many times. :)
Well, if also depends on the contents of 'else' clause of readed function as it may allow (or may not) the compiler to 
optimize entire function out completely.

If you still want to bother yourself with atomics ;) look at 
#include _NTO_CPU_HDR_(smpxchg.h)
and find 
int _smp_cmpxchg(volatile unsigned *__dst, unsigned __cmp, unsigned __new);
int _smp_xchg(volatile unsigned *__dst, unsigned __src);
in it.
Re: atomic_read() equivalent mechanism in QNX  
Also, you can always use atomic_add_value(&var, 0) for the same purpose if you do not want to dig in system includes.

> For the example provided you do not need atomic operations. You need them 
> neither for reading nor for writing as there is just one thread writing and 
> and anoth one thread reading and value being read may be safely re-read many 
> times. :)
> Well, if also depends on the contents of 'else' clause of readed function as 
> it may allow (or may not) the compiler to optimize entire function out 
> completely.
> 
> If you still want to bother yourself with atomics ;) look at 
> #include _NTO_CPU_HDR_(smpxchg.h)
> and find 
> int _smp_cmpxchg(volatile unsigned *__dst, unsigned __cmp, unsigned __new);
> int _smp_xchg(volatile unsigned *__dst, unsigned __src);
> in it.


Re: atomic_read() equivalent mechanism in QNX  
> Also, you can always use atomic_add_value(&var, 0) for the same purpose if you do not want to dig in system includes.
> 
> > For the example provided you do not need atomic operations. You need them 
> > neither for reading nor for writing as there is just one thread writing and 
> > and anoth one thread reading and value being read may be safely re-read many 
> > times. :)
> > Well, if also depends on the contents of 'else' clause of readed function as 
> > it may allow (or may not) the compiler to optimize entire function out 
> > completely.
> > 
> > If you still want to bother yourself with atomics ;) look at 
> > #include _NTO_CPU_HDR_(smpxchg.h)
> > and find 
> > int _smp_cmpxchg(volatile unsigned *__dst, unsigned __cmp, unsigned __new);
> > int _smp_xchg(volatile unsigned *__dst, unsigned __src);
> > in it.
> 
> 


Thanks Oleh for quick reply.

Using atomic_add_value(&var, 0) is certainly a solution to read value of a variable atomically.
 
But, as you said value may be safely re-read many times without using any atomic function... I am just wondering, why is
 there function atomic_read() in Linux to "Read" value atomically?

Thanks
Apurva



Re: atomic_read() equivalent mechanism in QNX  
> Using atomic_add_value(&var, 0) is certainly a solution to read value of a 
> variable atomically.
>  
> But, as you said value may be safely re-read many times without using any 
> atomic function... I am just wondering, why is there function atomic_read() in
>  Linux to "Read" value atomically?
> 

My answer in no meaning pretends to be authoritative but my personal impression is that in application programming with 
proper algorithm structure, with proper coding and proper data alignment only write needs to be atomic. Atomic reads 
could be necessary only for low level programming if a variable is queried in a loop without a delay (in spin style). 
And even in those rare cases atomic read would be used it is more intended is to combine memory fencing instruction with
 reading in a single operation rather than provide atomicity. For a properly aligned variable  both reading and writing 
are atomic even without any special means.
Re: atomic_read() equivalent mechanism in QNX  
Oleh Derevenko wrote:
>> Using atomic_add_value(&var, 0) is certainly a solution to read value of a
>> variable atomically.
>>
>> But, as you said value may be safely re-read many times without using any
>> atomic function... I am just wondering, why is there function atomic_read() in
>>   Linux to "Read" value atomically?
>>
> My answer in no meaning pretends to be authoritative but my personal impression is that in application programming 
with proper algorithm structure, with proper coding and proper data alignment only write needs to be atomic.


No ... there are a lot of cases where atomic read is necessary. The 
simplest case is reading a 32bit variable which is constantly updated by 
second task ... and this happens not only in low level code.

--Armin



>   Atomic reads could be necessary only for low level programming if a variable is queried in a loop without a delay 
(in spin style). And even in those rare cases atomic read would be used it is more intended is to combine memory fencing
 instruction with reading in a single operation rather than provide atomicity. For a properly aligned variable  both 
reading and writing are atomic even without any special means.
>
>
>
> _______________________________________________
>
> OSTech
> http://community.qnx.com/sf/go/post72578
>
>
Re: atomic_read() equivalent mechanism in QNX  
> > My answer in no meaning pretends to be authoritative but my personal 
> impression is that in application programming with proper algorithm structure,
>  with proper coding and proper data alignment only write needs to be atomic.
> 
> 
> No ... there are a lot of cases where atomic read is necessary. The 
> simplest case is reading a 32bit variable which is constantly updated by 
> second task ... and this happens not only in low level code.
> 

Well, and what about that? Let it be updated as frequently as it would like. Anyway, if you do a simple memory read or 
you do locked cmpxchg you'll get the same result. Memory access within a single cache line is atimic by default. Just 
simply reading a memory variable and taking no other actions is senseless with no regard to which reading method you use
. The atomic operation usage is always related to code executed before it or code that is going to follow it. And 
atomicity for pure reading could only be used to provide separation and synchronization with neighbour code, not for the
 reading operation itself.
Re: atomic_read() equivalent mechanism in QNX  
Oleh Derevenko wrote:
>>> My answer in no meaning pretends to be authoritative but my personal
>> impression is that in application programming with proper algorithm structure,
>>   with proper coding and proper data alignment only write needs to be atomic.
>>
>>
>> No ... there are a lot of cases where atomic read is necessary. The
>> simplest case is reading a 32bit variable which is constantly updated by
>> second task ... and this happens not only in low level code.
>>
> Well, and what about that? Let it be updated as frequently as it would like. Anyway, if you do a simple memory read or
 you do locked cmpxchg you'll get the same result. Memory access within a single cache line is atimic by default. Just 
simply reading a memory variable and taking no other actions is senseless with no regard to which reading method you use
. The atomic operation usage is always related to code executed before it or code that is going to follow it. And 
atomicity for pure reading could only be used to provide separation and synchronization with neighbour code, not for the
 reading operation itself.

We are not talking about assembler code. The motivation to use an 
atomic_read in C code is about concurrency!

--Armin

>
>
> _______________________________________________
>
> OSTech
> http://community.qnx.com/sf/go/post72581
>
>
Re: atomic_read() equivalent mechanism in QNX  
If you want it to work properly across multiple architectures, you need both. 

----- Original Message -----
From: Oleh Derevenko [mailto:community-noreply@qnx.com]
Sent: Wednesday, October 27, 2010 03:46 AM
To: ostech-core_os <post72581@community.qnx.com>
Subject: Re: atomic_read() equivalent mechanism in QNX

> > My answer in no meaning pretends to be authoritative but my personal 
> impression is that in application programming with proper algorithm structure,
>  with proper coding and proper data alignment only write needs to be atomic.
> 
> 
> No ... there are a lot of cases where atomic read is necessary. The 
> simplest case is reading a 32bit variable which is constantly updated by 
> second task ... and this happens not only in low level code.
> 

Well, and what about that? Let it be updated as frequently as it would like. Anyway, if you do a simple memory read or 
you do locked cmpxchg you'll get the same result. Memory access within a single cache line is atimic by default. Just 
simply reading a memory variable and taking no other actions is senseless with no regard to which reading method you use
. The atomic operation usage is always related to code executed before it or code that is going to follow it. And 
atomicity for pure reading could only be used to provide separation and synchronization with neighbour code, not for the
 reading operation itself.



_______________________________________________

OSTech
http://community.qnx.com/sf/go/post72581
Re: atomic_read() equivalent mechanism in QNX  
Sure, I know, I need atomic function for code to work the same way on all the architectures. But I'm just saying that 
atomic_read() is atomic not because the simple assignment operator would not be atomic without it, but rather to aid 
synchronization with other memory access operations. 
That is, 
res = atomic_read(&val);
could always be safely replaced with sequence
__cpu_membarrier();
res = val;

> If you want it to work properly across multiple architectures, you need both. 
> 
> 
> ----- Original Message -----
> From: Oleh Derevenko [mailto:community-noreply@qnx.com]
> Sent: Wednesday, October 27, 2010 03:46 AM
> To: ostech-core_os <post72581@community.qnx.com>
> Subject: Re: atomic_read() equivalent mechanism in QNX
> 
> > > My answer in no meaning pretends to be authoritative but my personal 
> > impression is that in application programming with proper algorithm 
> structure,
> >  with proper coding and proper data alignment only write needs to be atomic.
> 
> > 
> > 
> > No ... there are a lot of cases where atomic read is necessary. The 
> > simplest case is reading a 32bit variable which is constantly updated by 
> > second task ... and this happens not only in low level code.
> > 
> 
> Well, and what about that? Let it be updated as frequently as it would like. 
> Anyway, if you do a simple memory read or you do locked cmpxchg you'll get the
>  same result. Memory access within a single cache line is atimic by default. 
> Just simply reading a memory variable and taking no other actions is senseless
>  with no regard to which reading method you use. The atomic operation usage is
>  always related to code executed before it or code that is going to follow it.
>  And atomicity for pure reading could only be used to provide separation and 
> synchronization with neighbour code, not for the reading operation itself.
> 
Re: atomic_read() equivalent mechanism in QNX  
Well, 
> __cpu_membarrier();
> res = *(const volatile int *)&val;
of course. 


> That is, 
> res = atomic_read(&val);
> could always be safely replaced with sequence
> __cpu_membarrier();
> res = val;
> 
> > If you want it to work properly across multiple architectures, you need both
> . 
> > 
Re: atomic_read() equivalent mechanism in QNX  
> That is, 
> res = atomic_read(&var);
> could always be safely replaced with sequence
> __cpu_membarrier();
> res = *(const volatile int *)&var;

OK. If there are no objections, let's continue the explanation.

Similarly, atomic write can be substituted like this:
atomic_write(&var, src);
with
*(volatile int *)&var = src;
__cpu_membarrier();

Now, if to consider pure atomic read, there could be following possible options:

1) Memory barrier is not necessary by itself (as in orininal topic-poster's example) and atomic read could be replaced 
with a  simple assignment.

2) Atomic read is typically used in a bundle with atomic write like this
atomic_write(&var1, src);
res = atomic_read(&var2);

which can be expanded
*(volatile int *)&var1 = src;
__cpu_membarrier();
__cpu_membarrier();
res = *(const volatile int *)&var2;

then extra __cpu_membarrier() can be canceled
*(volatile int *)&var1 = src;
__cpu_membarrier();
res = *(const volatile int *)&var2;

and this can be wrapped back into
atomic_write(&var1, src);
res = *(const volatile int *)&var2;

which shows that with proper coding and memory alignment atomic read could be avoided altogether and is unnecessary 
(note: I'm still talking about application level code where quick spin-style checks are not used).

Also keep in mind that it needs not be atomic write operation only that would contain implicit memory barrier before 
reading. That could also be any mutex locking/unlocking operations, condvar waitiing, any kernel calls.
Re: atomic_read() equivalent mechanism in QNX  
Oleh Derevenko wrote:
>> That is,
>> res = atomic_read(&var);
>> could always be safely replaced with sequence
>> __cpu_membarrier();
>> res = *(const volatile int *)&var;
> OK. If there are no objections, let's continue the explanation.
>
> Similarly, atomic write can be substituted like this:
> atomic_write(&var, src);
> with
> *(volatile int *)&var = src;
> __cpu_membarrier();
>
> Now, if to consider pure atomic read, there could be following possible options:
>
> 1) Memory barrier is not necessary by itself (as in orininal topic-poster's example) and atomic read could be replaced
 with a  simple assignment.
>
> 2) Atomic read is typically used in a bundle with atomic write like this
> atomic_write(&var1, src);
> res = atomic_read(&var2);

    This make no sense ...
    No one would use the atomic calls in this way, the typical use is:

    Task or thread A:    atomic_write(&var, src);

    Task or thread B:    atomic_read(&var);

--Armin




> which can be expanded
> *(volatile int *)&var1 = src;
> __cpu_membarrier();
> __cpu_membarrier();
> res = *(const volatile int *)&var2;
>
> then extra __cpu_membarrier() can be canceled
> *(volatile int *)&var1 = src;
> __cpu_membarrier();
> res = *(const volatile int *)&var2;
>
> and this can be wrapped back into
> atomic_write(&var1, src);
> res = *(const volatile int *)&var2;
>
> which shows that with proper coding and memory alignment atomic read could be avoided altogether and is unnecessary 
(note: I'm still talking about application level code where quick spin-style checks are not used).
>
> Also keep in mind that it needs not be atomic write operation only that would contain implicit memory barrier before 
reading. That could also be any mutex locking/unlocking operations, condvar waitiing, any kernel calls.
>
>
>
> _______________________________________________
>
> OSTech
> http://community.qnx.com/sf/go/post72750
>
>
Re: atomic_read() equivalent mechanism in QNX  
> > 2) Atomic read is typically used in a bundle with atomic write like this
> > atomic_write(&var1, src);
> > res = atomic_read(&var2);
> 
>     This make no sense ...
>     No one would use the atomic calls in this way, the typical use is:
> 
>     Task or thread A:    atomic_write(&var, src);
> 
>     Task or thread B:    atomic_read(&var);
> 

Do you read what I write? Memory access within a single cache line is atomic by default. Or you can point to an 
architecture where it is not the case?
You do not need atomic operations for your example at all. There may be processor caches out of sync and you'll not get 
the data you are writing in other task at once but sooner or later they will get synchronized and from application level
 programming's point of view few more empty loops and few more extra variable checks do not matter (if not to mention 
that at application level checking a variable in a loop without delays is inacceptable way of programming at all).
Re: atomic_read() equivalent mechanism in QNX  
Oleh Derevenko wrote:
>>> 2) Atomic read is typically used in a bundle with atomic write like this
>>> atomic_write(&var1, src);
>>> res = atomic_read(&var2);
>>      This make no sense ...
>>      No one would use the atomic calls in this way, the typical use is:
>>
>>      Task or thread A:    atomic_write(&var, src);
>>
>>      Task or thread B:    atomic_read(&var);
>>
> Do you read what I write?

   Yes, but not from a cache line :)

> Memory access within a single cache line is atomic by default. Or you can point to an architecture where it is not the
 case?

   atamic_read/write are referencing normal memory and not locations of 
a CPU cache. In general not all access to memory go through the CPU cache.
   So it make sense to have the atomic_read ...

   --Armin


> You do not need atomic operations for your example at all. There may be processor caches out of sync and you'll not 
get the data you are writing in other task at once but sooner or later they will get synchronized and from application 
level programming's point of view few more empty loops and few more extra variable checks do not matter (if not to 
mention that at application level checking a variable in a loop without delays is inacceptable way of programming at 
all).
>
>
>
> _______________________________________________
>
> OSTech
> http://community.qnx.com/sf/go/post72937
>
>