Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
threads.hpp
00001 #ifndef _KERNEL_THREADS_H_
00002 #define _KERNEL_THREADS_H_
00003 
00004 #include <boost/thread/thread.hpp>
00005 #include <boost/thread/mutex.hpp>
00006 #include <boost/interprocess/sync/interprocess_semaphore.hpp>
00007 #include <boost/thread/condition_variable.hpp>
00008 #include <boost/lambda/lambda.hpp>
00009 
00010 namespace boost {
00011   typedef interprocess::interprocess_semaphore semaphore;
00012 }
00013 
00014 namespace jafar {
00015 namespace kernel {
00016   
00022   class FifoMutex: public boost::noncopyable
00023   {
00024     private:
00025       boost::mutex m;
00026       typedef std::pair<boost::semaphore*,bool> SemWait;
00027       typedef std::pair<boost::thread::id, SemWait> SemThread;
00028       typedef std::map<boost::thread::id, SemWait> SemsMap;
00029       SemsMap allSems;
00030       typedef std::list<SemsMap::iterator> SemsList;
00031       SemsList waitingSems;
00032       boost::optional<SemsMap::iterator> computingSem;
00033       
00034       bool lock_(bool try_);
00035       
00036     public:
00037       
00038       void lock()
00039       {
00040         lock_(false);
00041       }
00042       bool try_lock()
00043       {
00044         return lock_(true);
00045       }
00046       
00047       void unlock();
00048       
00049       bool own_lock()
00050       {
00051         boost::thread::id id = boost::this_thread::get_id();
00052         return (computingSem && (*computingSem)->first == id);
00053       }
00054 
00055       ~FifoMutex()
00056       {
00057         for(SemsMap::iterator it = allSems.begin(); it != allSems.end(); ++it)
00058           delete it->second.first;
00059       }
00060 
00061   };
00062   
00068   int setThreadPriority(boost::thread &t, int prio);
00069   
00074   void setCurrentThreadPriority(int prio, bool warn = true);
00075 
00081   void setCurrentThreadScheduler(int policy, int priority, bool warn = true);
00082 
00088   void setProcessScheduler(int policy, int priority, bool warn = true);
00089 
00090   
00096   template<typename T>
00097   class VariableMutex
00098   {
00099     public:
00100       T var; 
00101       
00102     protected:
00103       boost::mutex m;
00104       
00105     public:
00106       VariableMutex(const T &val_init): var(val_init) {}
00107       
00108       T get() { boost::unique_lock<boost::mutex> l(m); return var; }
00109       template<typename Assign> void apply(Assign assign) { boost::unique_lock<boost::mutex> l(m); assign(var); }
00110       void set(const T &val) { apply(boost::lambda::_1 = val); }
00111       T operator()() { return get(); }
00112       void operator()(const T &val) { set(val); }
00113       
00114       void lock() { m.lock(); }
00115       bool try_lock() { return m.try_lock(); }
00116       void unlock() { m.unlock(); }
00117   };
00118 
00124   template<typename T>
00125   class VariableCondition: public VariableMutex<T>
00126   {
00127     protected:
00128       boost::condition_variable c;
00129 
00130     public:
00131       VariableCondition(const T &val_init): VariableMutex<T>(val_init) {}
00132       
00141       template<typename Pred>
00142       void wait(Pred pred, bool unlock = true)
00143       {
00144         boost::unique_lock<boost::mutex> l(VariableMutex<T>::m);
00145         while(!pred(VariableMutex<T>::var)) c.wait(l);
00146         if (!unlock) l.release();
00147       }
00148       template<typename Pred, typename duration_type>
00149       bool timed_wait(Pred pred, duration_type const & rel_time, bool unlock = true)
00150       {
00151         boost::unique_lock<boost::mutex> l(VariableMutex<T>::m);
00152         while(!pred(VariableMutex<T>::var))
00153           if(!c.timed_wait(l, rel_time)) return pred(VariableMutex<T>::var);
00154         return true;
00155       }
00156       void notify() { c.notify_all(); }
00157       template<typename Assign> void applyAndNotify(Assign assign) { 
00158         VariableMutex<T>::apply(assign); notify(); 
00159       }
00160       void setAndNotify(const T &val) { applyAndNotify(boost::lambda::_1 = val); }
00161   };
00162 
00163 }}
00164 
00165 #endif
00166 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:24 for Jafar by doxygen 1.7.6.1
LAAS-CNRS