summaryrefslogblamecommitdiffstats
path: root/cpukit/score/inline/rtems/score/atomic.inl
blob: 313366c79fae544e5d674cf64d7112bb23f83b65 (plain) (tree)
1
2
3
4
5
6
7
8







                                                           


   








                                                                                

                                                                                

















                                                                                              
                                       






                                                   
                                               
                                              
                                        






                                                     
                                               
                                             
                                       






                                                  
                                               
                                            
                                      






                                                  
                                               
                                            
                                      








                                            
                                               
                                                     
                                               







                                             
                                               
                                                      
                                                







                                            
                                               
                                                     
                                               







                                           
                                               
                                                    
                                              







                                           
                                               
                                                    
                                              







                                                
                                               
                                                         
                                                    










                                                         
                                               
                                                          
                                                    










                                                          
                                               
                                                         
                                                    










                                                         
                                               
                                                        
                                                    










                                                        
                                               
                                                        
                                                    










                                                        
                                               
                                                         
                                                    










                                                         
                                               
                                                          
                                                    










                                                          
                                               
                                                         
                                                    










                                                         
                                               
                                                        
                                                    










                                                        
                                               
                                                        
                                                    










                                                        
                                               
                                                        
                                                    










                                                        
                                               
                                                         
                                                    










                                                         
                                               
                                                        
                                                    










                                                        
                                               
                                                       
                                                    










                                                       
                                               
                                                       
                                                    










                                                       
                                               
                                                         
                                                    










                                                         
                                               
                                                          
                                                    










                                                          
                                               
                                                         
                                                    










                                                         
                                               
                                                        
                                                    










                                                        
                                               
                                                        
                                                    











                                                        
                                               
                                                                               
                                                    











                                                                               
                                               
                                                                                
                                                    











                                                                                
                                               
                                                                               
                                                    











                                                                               
                                               
                                                                              
                                                    











                                                                              
                                               
                                                                              
                                                    






                                                                              
/*
 *  Atomic Manager
 *
 *  COPYRIGHT (c) 2012 Deng Hengyi.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 */

/*
 *
 *  The functions in this file implement the API to the RTEMS Atomic Manager and
 *  The API is designed to be compatable with C1X atomic definition as far as
 *  possible. And its implementation reuses the FreeBSD kernel atomic operation.
 *  The functions below are implemented with CPU dependent inline routines
 *  found in the path
 *
 *  rtems/cpukit/score/cpu/xxx/rtems/score/cpuatomic.h
 *
 *  In the event that a CPU does not support a specific atomic function it has, 
 *  the CPU dependent routine does nothing (but does exist).
 */

#ifndef _RTEMS_SCORE_ATOMIC_H
# error "Never use <rtems/score/atomic.inl> directly; include <rtems/score/atomic.h> instead."
#endif

#include <rtems/score/types.h>

#ifndef _RTEMS_SCORE_ATOMIC_INL
#define _RTEMS_SCORE_ATOMIC_INL

RTEMS_INLINE_ROUTINE Atomic_Int _Atomic_Load_int(
  volatile Atomic_Int *address,
  Atomic_Memory_barrier memory_barrier
)
{
  if(ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Load_acq_int(address);
  return _CPU_Atomic_Load_int(address);
}

RTEMS_INLINE_ROUTINE Atomic_Long _Atomic_Load_long(
  volatile Atomic_Long *address,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Load_acq_long(address);
  return _CPU_Atomic_Load_long(address);
}

RTEMS_INLINE_ROUTINE Atomic_Pointer _Atomic_Load_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Load_acq_ptr(address);
  return _CPU_Atomic_Load_ptr(address);
}

RTEMS_INLINE_ROUTINE Atomic_Int32 _Atomic_Load_32(
  volatile Atomic_Int32 *address,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Load_acq_32(address);
  return _CPU_Atomic_Load_32(address);
}

RTEMS_INLINE_ROUTINE Atomic_Int64 _Atomic_Load_64(
  volatile Atomic_Int64 *address,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Load_acq_64(address);
  return _CPU_Atomic_Load_64(address);
}


RTEMS_INLINE_ROUTINE void _Atomic_Store_int(
  volatile Atomic_Int *address,
  Atomic_Int value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Store_rel_int(address, value);
  return _CPU_Atomic_Store_int(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Store_long(
  volatile Atomic_Long *address,
  Atomic_Long value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Store_rel_long(address, value);
  return _CPU_Atomic_Store_long(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Store_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Store_rel_ptr(address, value);
  return _CPU_Atomic_Store_ptr(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Store_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Store_rel_32(address, value);
  return _CPU_Atomic_Store_32(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Store_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Store_rel_64(address, value);
  return _CPU_Atomic_Store_64(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_int(
  volatile Atomic_Int *address,
  Atomic_Int value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_acq_int(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_rel_int(address, value);
  else
    return _CPU_Atomic_Fetch_add_int(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_long(
  volatile Atomic_Long *address,
  Atomic_Long value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_acq_long(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_rel_long(address, value);
  else
    return _CPU_Atomic_Fetch_add_long(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_acq_ptr(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_rel_ptr(address, value);
  else
    return _CPU_Atomic_Fetch_add_ptr(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_acq_32(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_rel_32(address, value);
  else
    return _CPU_Atomic_Fetch_add_32(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_add_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_acq_64(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_add_rel_64(address, value);
  else
    return _CPU_Atomic_Fetch_add_64(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_int(
  volatile Atomic_Int *address,
  Atomic_Int value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_acq_int(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_rel_int(address, value);
  else
    return _CPU_Atomic_Fetch_sub_int(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_long(
  volatile Atomic_Long *address,
  Atomic_Long value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_acq_long(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_rel_long(address, value);
  else
    return _CPU_Atomic_Fetch_sub_long(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_acq_ptr(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_rel_ptr(address, value);
  else
    return _CPU_Atomic_Fetch_sub_ptr(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_acq_32(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_rel_32(address, value);
  else
    return _CPU_Atomic_Fetch_sub_32(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_sub_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_acq_64(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_sub_rel_64(address, value);
  else
    return _CPU_Atomic_Fetch_sub_64(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_int(
  volatile Atomic_Int *address,
  Atomic_Int value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_acq_int(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_rel_int(address, value);
  else
    return _CPU_Atomic_Fetch_or_int(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_long(
  volatile Atomic_Long *address,
  Atomic_Long value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_acq_long(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_rel_long(address, value);
  else
    return _CPU_Atomic_Fetch_or_long(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_acq_ptr(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_rel_ptr(address, value);
  else
    return _CPU_Atomic_Fetch_or_ptr(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_acq_32(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_rel_32(address, value);
  else
    return _CPU_Atomic_Fetch_or_32(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_or_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_acq_64(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_or_rel_64(address, value);
  else
    return _CPU_Atomic_Fetch_or_64(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_int(
  volatile Atomic_Int *address,
  Atomic_Int value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_acq_int(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_rel_int(address, value);
  else
    return _CPU_Atomic_Fetch_and_int(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_long(
  volatile Atomic_Long *address,
  Atomic_Long value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_acq_long(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_rel_long(address, value);
  else
    return _CPU_Atomic_Fetch_and_long(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_acq_ptr(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_rel_ptr(address, value);
  else
    return _CPU_Atomic_Fetch_and_ptr(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_acq_32(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_rel_32(address, value);
  else
    return _CPU_Atomic_Fetch_and_32(address, value);
}

RTEMS_INLINE_ROUTINE void _Atomic_Fetch_and_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_acq_64(address, value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Fetch_and_rel_64(address, value);
  else
    return _CPU_Atomic_Fetch_and_64(address, value);
}

RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_int(
  volatile Atomic_Int *address,
  Atomic_Int old_value,
  Atomic_Int new_value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_acq_int(address, old_value, new_value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_rel_int(address, old_value, new_value);
  else
    return _CPU_Atomic_Compare_exchange_int(address, old_value, new_value);
}

RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_long(
  volatile Atomic_Long *address,
  Atomic_Long old_value,
  Atomic_Long new_value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_acq_long(address, old_value, new_value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_rel_long(address, old_value, new_value);
  else
    return _CPU_Atomic_Compare_exchange_long(address, old_value, new_value);
}

RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_ptr(
  volatile Atomic_Pointer *address,
  Atomic_Pointer old_value,
  Atomic_Pointer new_value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_acq_ptr(address, old_value, new_value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_rel_ptr(address, old_value, new_value);
  else
    return _CPU_Atomic_Compare_exchange_ptr(address, old_value, new_value);
}

RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_32(
  volatile Atomic_Int32 *address,
  Atomic_Int32 old_value,  
  Atomic_Int32 new_value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_acq_32(address, old_value, new_value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_rel_32(address, old_value, new_value);
  else
    return _CPU_Atomic_Compare_exchange_32(address, old_value, new_value);
}

RTEMS_INLINE_ROUTINE int _Atomic_Compare_exchange_64(
  volatile Atomic_Int64 *address,
  Atomic_Int64 old_value,
  Atomic_Int64 new_value,
  Atomic_Memory_barrier memory_barrier
)
{
  if (ATOMIC_ACQUIRE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_acq_64(address, old_value, new_value);
  else if (ATOMIC_RELEASE_BARRIER == memory_barrier)
    return _CPU_Atomic_Compare_exchange_rel_64(address, old_value, new_value);
  else
    return _CPU_Atomic_Compare_exchange_64(address, old_value, new_value);
}

#endif
/* end of include file */