LCOV - code coverage report
Current view: top level - home/h/core/forks/m4-libzmq/src - atomic_ptr.hpp (source / functions) Hit Total Coverage
Test: zeromq-4.2.0 Code Coverage Lines: 7 7 100.0 %
Date: 2016-05-09 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :     Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
       3             : 
       4             :     This file is part of libzmq, the ZeroMQ core engine in C++.
       5             : 
       6             :     libzmq is free software; you can redistribute it and/or modify it under
       7             :     the terms of the GNU Lesser General Public License (LGPL) as published
       8             :     by the Free Software Foundation; either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     As a special exception, the Contributors give you permission to link
      12             :     this library with independent modules to produce an executable,
      13             :     regardless of the license terms of these independent modules, and to
      14             :     copy and distribute the resulting executable under terms of your choice,
      15             :     provided that you also meet, for each linked independent module, the
      16             :     terms and conditions of the license of that module. An independent
      17             :     module is a module which is not derived from or based on this library.
      18             :     If you modify this library, you must extend this exception to your
      19             :     version of the library.
      20             : 
      21             :     libzmq is distributed in the hope that it will be useful, but WITHOUT
      22             :     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      23             :     FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
      24             :     License for more details.
      25             : 
      26             :     You should have received a copy of the GNU Lesser General Public License
      27             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      28             : */
      29             : 
      30             : #ifndef __ZMQ_ATOMIC_PTR_HPP_INCLUDED__
      31             : #define __ZMQ_ATOMIC_PTR_HPP_INCLUDED__
      32             : 
      33             : #include "platform.hpp"
      34             : 
      35             : #if defined ZMQ_FORCE_MUTEXES
      36             : #define ZMQ_ATOMIC_PTR_MUTEX
      37             : #elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
      38             : #define ZMQ_ATOMIC_PTR_INTRINSIC
      39             : #elif (defined ZMQ_CXX11 && defined __cplusplus && __cplusplus >= 201103L)
      40             : #define ZMQ_ATOMIC_PTR_CXX11
      41             : #elif (defined __i386__ || defined __x86_64__) && defined __GNUC__
      42             : #define ZMQ_ATOMIC_PTR_X86
      43             : #elif defined __ARM_ARCH_7A__ && defined __GNUC__
      44             : #define ZMQ_ATOMIC_PTR_ARM
      45             : #elif defined __tile__
      46             : #define ZMQ_ATOMIC_PTR_TILE
      47             : #elif defined ZMQ_HAVE_WINDOWS
      48             : #define ZMQ_ATOMIC_PTR_WINDOWS
      49             : #elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_NETBSD || defined ZMQ_HAVE_GNU)
      50             : #define ZMQ_ATOMIC_PTR_ATOMIC_H
      51             : #else
      52             : #define ZMQ_ATOMIC_PTR_MUTEX
      53             : #endif
      54             : 
      55             : #if defined ZMQ_ATOMIC_PTR_MUTEX
      56             : #include "mutex.hpp"
      57             : #elif defined ZMQ_ATOMIC_PTR_CXX11
      58             : #include <atomic>
      59             : #elif defined ZMQ_ATOMIC_PTR_WINDOWS
      60             : #include "windows.hpp"
      61             : #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
      62             : #include <atomic.h>
      63             : #elif defined ZMQ_ATOMIC_PTR_TILE
      64             : #include <arch/atomic.h>
      65             : #endif
      66             : 
      67             : namespace zmq
      68             : {
      69             : 
      70             :     //  This class encapsulates several atomic operations on pointers.
      71             : 
      72             :     template <typename T> class atomic_ptr_t
      73             :     {
      74             :     public:
      75             : 
      76             :         //  Initialise atomic pointer
      77             :         inline atomic_ptr_t ()
      78             :         {
      79       56686 :             ptr = NULL;
      80             :         }
      81             : 
      82             :         //  Destroy atomic pointer
      83             :         inline ~atomic_ptr_t ()
      84             :         {
      85             :         }
      86             : 
      87             :         //  Set value of atomic pointer in a non-threadsafe way
      88             :         //  Use this function only when you are sure that at most one
      89             :         //  thread is accessing the pointer at the moment.
      90             :         inline void set (T *ptr_)
      91             :         {
      92       78516 :             this->ptr = ptr_;
      93             :         }
      94             : 
      95             :         //  Perform atomic 'exchange pointers' operation. Pointer is set
      96             :         //  to the 'val' value. Old value is returned.
      97             :         inline T *xchg (T *val_)
      98             :         {
      99             : #if defined ZMQ_ATOMIC_PTR_WINDOWS
     100             :             return (T*) InterlockedExchangePointer ((PVOID*) &ptr, val_);
     101             : #elif defined ZMQ_ATOMIC_PTR_INTRINSIC
     102       52843 :             return (T*) __atomic_exchange_n (&ptr, val_, __ATOMIC_ACQ_REL);
     103             : #elif defined ZMQ_ATOMIC_PTR_CXX11
     104             :             return ptr.exchange(val_, std::memory_order_acq_rel);
     105             : #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
     106             :             return (T*) atomic_swap_ptr (&ptr, val_);
     107             : #elif defined ZMQ_ATOMIC_PTR_TILE
     108             :             return (T*) arch_atomic_exchange (&ptr, val_);
     109             : #elif defined ZMQ_ATOMIC_PTR_X86
     110             :             T *old;
     111             :             __asm__ volatile (
     112             :                 "lock; xchg %0, %2"
     113             :                 : "=r" (old), "=m" (ptr)
     114             :                 : "m" (ptr), "0" (val_));
     115             :             return old;
     116             : #elif defined ZMQ_ATOMIC_PTR_ARM
     117             :             T* old;
     118             :             unsigned int flag;
     119             :             __asm__ volatile (
     120             :                 "       dmb     sy\n\t"
     121             :                 "1:     ldrex   %1, [%3]\n\t"
     122             :                 "       strex   %0, %4, [%3]\n\t"
     123             :                 "       teq     %0, #0\n\t"
     124             :                 "       bne     1b\n\t"
     125             :                 "       dmb     sy\n\t"
     126             :                 : "=&r"(flag), "=&r"(old), "+Qo"(ptr)
     127             :                 : "r"(&ptr), "r"(val_)
     128             :                 : "cc");
     129             :             return old;
     130             : #elif defined ZMQ_ATOMIC_PTR_MUTEX
     131             :             sync.lock ();
     132             :             T *old = (T*) ptr;
     133             :             ptr = val_;
     134             :             sync.unlock ();
     135             :             return old;
     136             : #else
     137             : #error atomic_ptr is not implemented for this platform
     138             : #endif
     139             :         }
     140             : 
     141             :         //  Perform atomic 'compare and swap' operation on the pointer.
     142             :         //  The pointer is compared to 'cmp' argument and if they are
     143             :         //  equal, its value is set to 'val'. Old value of the pointer
     144             :         //  is returned.
     145             :         inline T *cas (T *cmp_, T *val_)
     146             :         {
     147             : #if defined ZMQ_ATOMIC_PTR_WINDOWS
     148             :             return (T*) InterlockedCompareExchangePointer (
     149             :                 (volatile PVOID*) &ptr, val_, cmp_);
     150             : #elif defined ZMQ_ATOMIC_PTR_INTRINSIC
     151     1171046 :             T *old = cmp_;
     152     1171046 :             __atomic_compare_exchange_n (&ptr, (volatile T**) &old, val_, false,
     153     1171046 :                     __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
     154     1171046 :             return old;
     155             : #elif defined ZMQ_ATOMIC_PTR_CXX11
     156             :             ptr.compare_exchange_strong(cmp_, val_, std::memory_order_acq_rel);
     157             :             return cmp_;
     158             : #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
     159             :             return (T*) atomic_cas_ptr (&ptr, cmp_, val_);
     160             : #elif defined ZMQ_ATOMIC_PTR_TILE
     161             :             return (T*) arch_atomic_val_compare_and_exchange (&ptr, cmp_, val_);
     162             : #elif defined ZMQ_ATOMIC_PTR_X86
     163             :             T *old;
     164             :             __asm__ volatile (
     165             :                 "lock; cmpxchg %2, %3"
     166             :                 : "=a" (old), "=m" (ptr)
     167             :                 : "r" (val_), "m" (ptr), "0" (cmp_)
     168             :                 : "cc");
     169             :             return old;
     170             : #elif defined ZMQ_ATOMIC_PTR_ARM
     171             :             T *old;
     172             :             unsigned int flag;
     173             :             __asm__ volatile (
     174             :                 "       dmb     sy\n\t"
     175             :                 "1:     ldrex   %1, [%3]\n\t"
     176             :                 "       mov     %0, #0\n\t"
     177             :                 "       teq     %1, %4\n\t"
     178             :                 "       it      eq\n\t"
     179             :                 "       strexeq %0, %5, [%3]\n\t"
     180             :                 "       teq     %0, #0\n\t"
     181             :                 "       bne     1b\n\t"
     182             :                 "       dmb     sy\n\t"
     183             :                 : "=&r"(flag), "=&r"(old), "+Qo"(ptr)
     184             :                 : "r"(&ptr), "r"(cmp_), "r"(val_)
     185             :                 : "cc");
     186             :             return old;
     187             : #elif defined ZMQ_ATOMIC_PTR_MUTEX
     188             :             sync.lock ();
     189             :             T *old = (T*) ptr;
     190             :             if (ptr == cmp_)
     191             :                 ptr = val_;
     192             :             sync.unlock ();
     193             :             return old;
     194             : #else
     195             : #error atomic_ptr is not implemented for this platform
     196             : #endif
     197             :         }
     198             : 
     199             :     private:
     200             : 
     201             : #if defined ZMQ_ATOMIC_PTR_CXX11
     202             :         std::atomic<T*> ptr;
     203             : #else
     204             :         volatile T *ptr;
     205             : #endif
     206             : 
     207             : #if defined ZMQ_ATOMIC_PTR_MUTEX
     208             :         mutex_t sync;
     209             : #endif
     210             : 
     211             : #if ! defined ZMQ_ATOMIC_PTR_CXX11
     212             :         atomic_ptr_t (const atomic_ptr_t&);
     213             :         const atomic_ptr_t &operator = (const atomic_ptr_t&);
     214             : #endif
     215             :     };
     216             : 
     217             : }
     218             : 
     219             : //  Remove macros local to this file.
     220             : #undef ZMQ_ATOMIC_PTR_MUTEX
     221             : #undef ZMQ_ATOMIC_PTR_INTRINSIC
     222             : #undef ZMQ_ATOMIC_PTR_CXX11
     223             : #undef ZMQ_ATOMIC_PTR_X86
     224             : #undef ZMQ_ATOMIC_PTR_ARM
     225             : #undef ZMQ_ATOMIC_PTR_TILE
     226             : #undef ZMQ_ATOMIC_PTR_WINDOWS
     227             : #undef ZMQ_ATOMIC_PTR_ATOMIC_H
     228             : 
     229             : #endif

Generated by: LCOV version 1.10