Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
threadlib.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
00002 #ifndef __RAPICORN_THREADLIB_HH__
00003 #define __RAPICORN_THREADLIB_HH__
00004 
00005 #include <condition_variable>
00006 #include <rcore/cpuasm.hh>
00007 
00008 namespace Rapicorn {
00009 namespace Lib { // Namespace for implementation internals
00010 
00011 template<typename T> T    atomic_load  (T volatile *p)      { RAPICORN_CFENCE; T t = *p; RAPICORN_LFENCE; return t; }
00012 template<typename T> void atomic_store (T volatile *p, T i) { RAPICORN_SFENCE; *p = i;  RAPICORN_CFENCE; }
00013 
00014 template<typename T>
00015 class Atomic {
00016   T volatile v;
00017   /*ctor*/  Atomic    () = delete;
00018   /*ctor*/  Atomic    (T&&) = delete;
00019 protected:
00020   constexpr Atomic    (T i) : v (i) {}
00021   Atomic<T>& operator=(Atomic<T> &o) { store (o.load()); return *this; }
00022   Atomic<T> volatile& operator=(Atomic<T> &o) volatile { store (o.load()); return *this; }
00023 public:
00024   T         load      () const volatile { return atomic_load (&v); }
00025   void      store     (T i)    volatile { atomic_store (&v, i); }
00026   bool      cas  (T o, T n)    volatile { return __sync_bool_compare_and_swap (&v, o, n); }
00027   T         operator+=(T i)    volatile { return __sync_add_and_fetch (&v, i); }
00028   T         operator-=(T i)    volatile { return __sync_sub_and_fetch (&v, i); }
00029   T         operator&=(T i)    volatile { return __sync_and_and_fetch (&v, i); }
00030   T         operator^=(T i)    volatile { return __sync_xor_and_fetch (&v, i); }
00031   T         operator|=(T i)    volatile { return __sync_or_and_fetch  (&v, i); }
00032   T         operator++()       volatile { return __sync_add_and_fetch (&v, 1); }
00033   T         operator++(int)    volatile { return __sync_fetch_and_add (&v, 1); }
00034   T         operator--()       volatile { return __sync_sub_and_fetch (&v, 1); }
00035   T         operator--(int)    volatile { return __sync_fetch_and_sub (&v, 1); }
00036   void      operator= (T i)    volatile { store (i); }
00037   operator  T         () const volatile { return load(); }
00038 };
00039 
00040 // == Once Scope ==
00041 void once_list_enter  ();
00042 bool once_list_bounce (volatile void *ptr);
00043 bool once_list_leave  (volatile void *ptr);
00044 
00045 class OnceScope {
00046   /*ctor*/       OnceScope (const OnceScope&) = delete;
00047   OnceScope&     operator= (const OnceScope&) = delete;
00048   volatile char *volatile flagp;
00049   bool           entered_once;
00050 public:
00051   OnceScope (volatile char *volatile p) : flagp (p), entered_once (false) {}
00052   inline bool
00053   operator() ()
00054   {
00055     if (RAPICORN_LIKELY (*flagp != 0))
00056       return false;
00057     if (entered_once > 0)       // second or later invocation from for()
00058       {
00059         const bool is_first_initialization = __sync_bool_compare_and_swap (flagp, 0, 1);
00060         const bool found_and_removed = once_list_leave (flagp);
00061         if (!is_first_initialization || !found_and_removed)
00062           printerr ("__once: %s: assertion failed during leave: %d %d", __func__, is_first_initialization, found_and_removed);
00063       }
00064     entered_once = 1;           // mark first invocation
00065     once_list_enter();
00066     const bool initialized = atomic_load (flagp) != 0;
00067     const bool needs_init = once_list_bounce (initialized ? NULL : flagp);
00068     return needs_init;
00069   }
00070 };
00071 
00072 #define RAPICORN_ASECTION(bytes)    __attribute__ ((section (".data.aligned" #bytes), aligned (bytes)))
00073 #define RAPICORN_DO_ONCE_COUNTER    ({ static volatile char RAPICORN_ASECTION (1) __rapicorn_oncebyte_ = 0; &__rapicorn_oncebyte_; })
00074 #define RAPICORN_DO_ONCE   for (Rapicorn::Lib::OnceScope __rapicorn_oncescope_ (RAPICORN_DO_ONCE_COUNTER); __rapicorn_oncescope_(); )
00075 
00076 } // Lib
00077 } // Rapicorn
00078 
00079 
00080 #endif // __RAPICORN_THREADLIB_HH__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines