/* counter.h -*-C++-*- * by Will Wagner * last updated 11 Aug 1997, 22:22:25 wwagner * * This file contains a counter primitive. All that can be done to * this object is incrementation and reading, nothing else. The * counter is also transparently protected with a spinlock, for * purposes of multithreading. * * This object supports both prefix and postfix incrementation * operators, for no particular reason. Some people like one, some * like the other, so it's best to support everything. * * USE_THREADS controls what gets compiled here; if it is defined, * then thread-safe counters are produced. Otherwise, we just get an * unprotected counter. * * HIGH_RESOLUTION controls how many bits of counting we get. If it * is defined, we get a 64-bit unsigned integer; if not, we only get * 32 unsigned bits. * * Changes * 29 Jul 1997 * - Created the file. * * 11 Aug 1997 * - Added high-resolution counting ability, with definition of * HIGH_RESOLUTION; unfortunately it only works with GNU * compilers. * * Things to do * - Portability! This is pretty tightly tied to Linux; consider * changing the low-level spinlock to a pthread_mutex. * */ #ifndef __INC_COUNTER_H__ #define __INC_COUNTER_H__ #ifndef USE_THREADS #include #endif #ifdef HIGH_RESOLUTION typedef unsigned long long counter_type; #else typedef unsigned long counter_type; #endif class Counter { private: counter_type value; #ifdef USE_THREADS int spinlock; #endif public: Counter(counter_type v = 0L) { value = v; #ifdef USE_THREADS spinlock = 0; #endif }; ~Counter(); inline counter_type operator++(void) { #ifdef USE_THREADS counter_type tmp; while (test_and_set_bit(0, &spinlock)); tmp = ++value; clear_bit(0, &spinlock); return tmp; #else return ++value; #endif }; inline counter_type operator++(int) { #ifdef USE_THREADS counter_type tmp; while (test_and_set_bit(0, &spinlock)); tmp = value++; clear_bit(0, &spinlock); return tmp; #else return value++; #endif }; inline operator int(void) { #ifdef USE_THREADS counter_type tmp; while (test_and_set_bit(0, &spinlock)); tmp = value; clear_bit(0, &spinlock); return tmp; #else return value; #endif }; }; #endif /* __INC_COUNTER_H__ */