MACE
1.0.0
|
00001 00004 #ifndef MACE_CMT_THREAD_HPP 00005 #define MACE_CMT_THREAD_HPP 00006 #include <mace/cmt/task.hpp> 00007 #include <boost/chrono.hpp> 00008 #include <mace/cmt/abstract_thread.hpp> 00009 00010 namespace mace { 00014 namespace cmt { 00015 using boost::chrono::microseconds; 00016 using boost::chrono::system_clock; 00017 00018 struct context; 00019 00020 priority current_priority(); 00021 inline void usleep( uint64_t us ); 00022 inline void sleep_until( const system_clock::time_point& tp ); 00023 00024 boost::posix_time::ptime to_system_time( const system_clock::time_point& t ); 00025 system_clock::time_point to_time_point( const boost::posix_time::ptime& from ); 00026 00044 class thread : public abstract_thread { 00045 public: 00049 static thread& current(); 00050 00054 const char* name()const; 00055 00059 void set_name( const char* n ); 00060 00067 static thread* create( const char* name = "" ); 00068 00069 00080 template<typename Functor> 00081 auto schedule( Functor&& f, const system_clock::time_point& when, 00082 priority prio = priority() ) -> future<decltype(f())> { 00083 typedef decltype(f()) Result; 00084 typename promise<Result>::ptr p(new promise<Result>()); 00085 task::ptr tsk( new rtask<Functor,Result>( std::forward<Functor>(f),p,when,std::max(current_priority(),prio)) ); 00086 p->set_task(tsk); 00087 async_task(tsk); 00088 return p; 00089 } 00090 00091 00100 template<typename Functor> 00101 auto async( Functor&& f, priority prio = priority()) -> future<decltype(f())> { 00102 typedef decltype(f()) Result; 00103 typename promise<Result>::ptr p(new promise<Result>()); 00104 task::ptr tsk( new rtask<Functor,Result>( std::forward<Functor>(f),p,std::max(current_priority(),prio)) ); 00105 p->set_task(tsk); 00106 async_task(tsk); 00107 return p; 00108 } 00109 00121 template<typename Functor> 00122 void post( Functor&& f, const system_clock::time_point& when, 00123 priority prio = priority()) { 00124 task::ptr tsk( new vtask<Functor>(std::forward<Functor>(f),when,std::max(current_priority(),prio)) ); 00125 async_task(tsk); 00126 } 00127 00134 template<typename Functor> 00135 void post( Functor&& f, priority p = priority() ) { 00136 task::ptr tsk( new vtask<Functor>(std::forward<Functor>(f),std::max(current_priority(),p)) ); 00137 async_task(tsk); 00138 } 00139 00152 void quit(); 00153 00157 void exec(); 00158 00162 bool is_running()const; 00163 00164 priority current_priority()const; 00165 ~thread(); 00166 00167 private: 00168 void set_boost_thread( boost::thread* t ); 00169 friend class thread_private; 00170 friend class mutex; 00171 00172 00173 friend void mace::cmt::yield(); 00174 friend void mace::cmt::usleep( uint64_t ); 00175 friend void mace::cmt::sleep_until( const system_clock::time_point& ); 00176 00177 // these methods may only be called from the current thread 00178 void yield( bool reschedule = true ); 00179 void yield_until( const system_clock::time_point& tp, bool reschedule = true ); 00180 void usleep( uint64_t us ); 00181 void sleep_until( const system_clock::time_point& tp ); 00182 00183 void wait( const promise_base::ptr& p, const microseconds& timeout_us ); 00184 void wait( const promise_base::ptr& p, const system_clock::time_point& timeout ); 00185 void notify( const promise_base::ptr& p ); 00186 00187 cmt::context* current_context()const; 00188 00189 void unblock( cmt::context* c ); 00190 00191 private: 00192 thread(); 00193 00194 friend class promise_base; 00195 void async_task( const task::ptr& t ); 00196 class thread_private* my; 00197 }; 00198 00199 template<typename Functor> 00200 auto async( Functor&& f, priority prio=priority()) -> cmt::future<decltype(f())> { 00201 return cmt::thread::current().async(std::forward<Functor>(f),(std::max)(current_priority(),prio)); 00202 } 00203 void async( const boost::function<void()>& t, priority prio=priority() ); 00204 00208 int exec(); 00209 00213 inline void usleep( uint64_t us ) { 00214 mace::cmt::thread::current().usleep(us); 00215 } 00219 inline void sleep_until( const system_clock::time_point& tp ) { 00220 mace::cmt::thread::current().sleep_until(tp); 00221 } 00225 void yield(); 00226 00228 inline void quit() { cmt::thread::current().quit(); } 00229 } } // mace::cmt 00230 00231 #endif // MACE_CMT_THREAD_HPP