/sparrowhawk/foundation/ESFSharedCounter.h
C Header | 157 lines | 93 code | 36 blank | 28 comment | 1 complexity | f4db596c085c5b474fdcb34f2a711a06 MD5 | raw file
1/** @file ESFSharedCounter.h 2 * @brief A threadsafe counter 3 * 4 * Copyright (c) 2011 Yahoo! Inc. 5 * The copyrights embodied in the content of this file are licensed by Yahoo! Inc. 6 * under the BSD (revised) open source license. 7 * 8 * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both 9 * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/). 10 * 11 * $Author: blattj $ 12 * $Date: 2009/05/25 21:51:08 $ 13 * $Name: $ 14 * $Revision: 1.3 $ 15 */ 16 17#ifndef ESF_SHARED_COUNTER_H 18#define ESF_SHARED_COUNTER_H 19 20#ifndef ESF_CONFIG_H 21#include <ESFConfig.h> 22#endif 23 24#ifndef ESF_ALLOCATOR_H 25#include <ESFAllocator.h> 26#endif 27 28#ifndef HAVE_X86_ASM 29 30#ifndef ESF_MUTEX_H 31#include <ESFMutex.h> 32#endif 33 34#endif 35 36/** @defgroup counter Counters */ 37 38/** ESFSharedCounter is an integer type that can be safely accessed by 39 * multiple threads. 40 * 41 * @ingroup counter 42 */ 43class ESFSharedCounter { 44public: 45 /** Default constructor. */ 46 ESFSharedCounter(); 47 48 ESFSharedCounter(ESFSharedCounter &counter); 49 50 virtual ~ESFSharedCounter(); 51 52 ESFSharedCounter &operator=(ESFSharedCounter &counter); 53 54 inline void set(int value) { 55 _counter = value; 56 } 57 58 inline int get() const { 59 return _counter; 60 } 61 62 inline int inc() { 63 unsigned int counter = 0; 64 65#ifdef HAVE_X86_ASM 66 __asm__ __volatile__("lock; incl %0; movl %0, %1" 67 :"=m" (_counter), "=r" (counter) 68 :"m" (_counter) 69 : "memory"); 70#else 71 _lock.writeAcquire(); 72 73 counter = _counter++; 74 75 _lock.writeRelease(); 76#endif 77 78 return counter; 79 } 80 81 inline int dec() { 82 unsigned int counter = 0; 83 84#ifdef HAVE_X86_ASM 85 __asm__ __volatile__("lock; decl %0; movl %0, %1" 86 :"=m" (_counter), "=r" (counter) 87 :"m" (_counter) 88 : "memory"); 89#else 90 _lock.writeAcquire(); 91 92 counter = _counter--; 93 94 _lock.writeRelease(); 95#endif 96 97 return counter; 98 } 99 100 inline void add(int value) { 101#ifdef HAVE_X86_ASM 102 __asm__ __volatile__("lock ; addl %1,%0" 103 :"=m" (_counter) 104 :"ir" (value), "m" (_counter)); 105#else 106 _lock.writeAcquire(); 107 108 _counter += value; 109 110 _lock.writeRelease(); 111#endif 112 } 113 114 inline void sub(int value) { 115#ifdef HAVE_X86_ASM 116 __asm__ __volatile__("lock ; subl %1,%0" 117 :"=m" (_counter) 118 :"ir" (value), "m" (_counter)); 119#else 120 _lock.writeAcquire(); 121 122 _counter -= value; 123 124 _lock.writeRelease(); 125#endif 126 } 127 128 inline bool decAndTest() { 129 unsigned char c; 130 131 __asm__ __volatile__("lock ; decl %0; sete %1" 132 :"=m" (_counter), "=qm" (c) 133 :"m" (_counter) 134 : "memory"); 135 return c != 0; 136 } 137 138 /** Placement new. 139 * 140 * @param size The size of the object. 141 * @param allocator The source of the object's memory. 142 * @return The new object or NULL of the memory allocation failed. 143 */ 144 inline void *operator new(size_t size, ESFAllocator *allocator) { 145 return allocator->allocate(size); 146 } 147 148private: 149 150#ifndef HAVE_X86_ASM 151 ESFMutex _lock; 152#endif 153 154 volatile int _counter; 155}; 156 157#endif /* ! ESF_SHARED_COUNTER_H */