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