Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/threads/atomic.h

Go to the documentation of this file.
00001 /*
00002  * lib/threads/atomic.h
00003  * 
00004  * Atomic counters for threaded applications. 
00005  * 
00006  * Copyright (c) 2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00007  * 
00008  * This file may be distributed and/or modified under the terms of the 
00009  * GNU General Public License version 2 as published by the Free Software 
00010  * Foundation. (See COPYING.GPL for details.)
00011  * 
00012  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014  * 
00015  */
00016 
00017 #ifndef _ThreadLibrary_Atomic_H_
00018 #define _ThreadLibrary_Atomic_H_ 1
00019 
00037 #include <lib/sconfig.h>    /* MUST be first */
00038 
00039 /* See if we have an asm/atomic.h and can use fast atomic operations. */
00040 #if USE_PRIVATE__ATOMIC
00041 # if HAVE_ASM_ATOMIC_H
00042 #  include <asm/atomic.h>
00043 # elif HAVE_ATOMIC_H
00044 #  include <atomic.h>
00045 # endif
00046 #else
00047 #include <lib/threads/mutex.h>
00048 #include <glib/gthread.h>
00049 #endif
00050 
00051 
00052 // Atomic integer with atomic operations that C can't guarantee us. 
00053 // Useful for resource counting etc...
00063 class _packed_ AtomicInt
00064 {
00065     private:
00066 #if USE_PRIVATE__ATOMIC
00067         atomic_t v;
00068 #else
00069         // It seems, the GLib people somehow forgot to provide 
00070         // this functionality. Or I simply have no clue on how to 
00071         // properly exploit the exchange functions. 
00072         // So, we need a mutex in these cases. 
00073         FastMutex m;
00074         gint v;  
00075 #endif
00076         
00077     public:
00079         inline AtomicInt(int initial=0)
00080 #if USE_PRIVATE__ATOMIC
00081             {  atomic_set(&v,initial);  }
00082 #else
00083             : m()  {  v=initial;  }
00084 #endif
00085         inline ~AtomicInt() {}
00086         
00088         inline int val() const
00089 #if USE_PRIVATE__ATOMIC
00090             {  return(atomic_read(&v));  }
00091 #else
00092             {  return(g_atomic_int_get(&v));  }
00093 #endif
00094         inline operator int() const  {  return(val());  }
00095         
00097         inline void set(int i)
00098 #if USE_PRIVATE__ATOMIC
00099             {  atomic_set(&v,i);  }
00100 #else
00101             {  m.lock();  v=i;  m.unlock();  }
00102 #endif
00103         inline void operator=(int i)  {  set(i);  }
00104         
00106         inline void inc()
00107 #if USE_PRIVATE__ATOMIC
00108             {  atomic_inc(&v);  }
00109 #else
00110             //{  g_atomic_int_add(&v,1);  }
00111             {  m.lock();  ++v;  m.unlock();  }
00112 #endif
00113         inline void operator++()  {  inc();  }
00114         
00116         inline void dec()
00117 #if USE_PRIVATE__ATOMIC
00118             {  atomic_dec(&v);  }
00119 #else
00120             //{  g_atomic_int_add(&v,-1);  }
00121             {  m.lock();  --v;  m.unlock();  }
00122 #endif
00123         inline void operator--()  {  dec();  }
00124         
00127         inline bool DecAndTest()
00128 #if USE_PRIVATE__ATOMIC
00129             {  return(atomic_dec_and_test(&v));  }
00130 #else
00131             {  m.lock();  bool rv=--v==0;  m.unlock();  return(rv);  }
00132 #endif
00133         
00135         inline void add(int i)
00136 #if USE_PRIVATE__ATOMIC
00137             {  atomic_add(i,&v);  }
00138 #else
00139             //{  g_atomic_int_add(&v,i);  }
00140             {  m.lock();  v+=i;  m.unlock();  }
00141 #endif
00142         inline void operator+=(int i)  {  add(i);  }
00143         
00145         inline void sub(int i)
00146 #if USE_PRIVATE__ATOMIC
00147             {  atomic_sub(i,&v);  }
00148 #else
00149             {  add(-i);  }
00150 #endif
00151         inline void operator-=(int i)  {  sub(i);  }
00152         
00155         inline bool SubAndTest(int i)
00156 #if USE_PRIVATE__ATOMIC
00157             {  return(atomic_sub_and_test(i,&v));  }
00158 #else
00159             {  m.lock();  v-=i;  bool rv=v==0;  m.unlock();  return(rv);  }
00160 #endif
00161         
00162 };
00163 
00164 #endif  /* _ThreadLibrary_Atomic_H_ */

Generated on Sat Feb 19 22:33:46 2005 for Ray by doxygen 1.3.5