Changeset 48d9187 in mainline
- Timestamp:
- 2018-07-05T21:41:19Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1df0165
- Parents:
- ee51635
- git-author:
- Dzejrou <dzejrou@…> (2018-03-01 22:20:05)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:19)
- Location:
- uspace/lib/cpp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/thread.hpp
ree51635 r48d9187 41 41 } 42 42 43 namespace aux 44 { 45 template<class Callable> 46 int thread_main(void*); 47 48 /** 49 * Fibrils in HelenOS are not joinable. They were 50 * in the past, but that functionality was removed from them 51 * so we created a workaround using a conditional variable that 52 * comprises the following two wrapper classes. 53 */ 54 class joinable_wrapper 55 { 56 public: 57 joinable_wrapper() 58 : join_mtx_{}, join_cv_{}, 59 finished_{false}, detached_{false} 60 { 61 fibril_mutex_initialize(&join_mtx_); 62 fibril_condvar_initialize(&join_cv_); 63 } 64 65 void join() 66 { 67 fibril_mutex_lock(&join_mtx_); 68 while (!finished_) 69 fibril_condvar_wait(&join_cv_, &join_mtx_); 70 fibril_mutex_unlock(&join_mtx_); 71 } 72 73 bool finished() const 74 { 75 return finished_; 76 } 77 78 void detach() 79 { 80 detached_ = true; 81 } 82 83 bool detached() const 84 { 85 return detached_; 86 } 87 88 protected: 89 fibril_mutex_t join_mtx_; 90 fibril_condvar_t join_cv_; 91 bool finished_; 92 bool detached_; 93 }; 94 95 template<class Callable> 96 class callable_wrapper: public joinable_wrapper 97 { 98 public: 99 callable_wrapper(Callable&& clbl) 100 : joinable_wrapper{}, callable_{forward<Callable>(clbl)} 101 { /* DUMMY BODY */ } 102 103 void operator()() 104 { 105 callable_(); 106 107 fibril_mutex_lock(&join_mtx_); 108 finished_ = true; 109 fibril_mutex_unlock(&join_mtx_); 110 111 fibril_condvar_broadcast(&join_cv_); 112 } 113 114 private: 115 Callable callable_; 116 }; 117 } 118 43 119 /** 44 120 * 30.3.1, class thread: … … 65 141 template<class F, class... Args> 66 142 explicit thread(F&& f, Args&&... args) 143 : id_{} 67 144 { 68 // TODO: create std::function out of f and args, 69 // then use fibril_create with that as 70 // the argument and call it? 71 id_ = fibril_create(f, nullptr); 145 auto callable = [&](){ 146 return f(forward<Args>(args)...); 147 }; 148 149 auto callable_wrapper = new aux::callable_wrapper<decltype(callable)>{move(callable)}; 150 joinable_wrapper_ = static_cast<aux::joinable_wrapper*>(callable_wrapper); 151 152 id_ = fibril_create( 153 aux::thread_main<decltype(callable_wrapper)>, 154 static_cast<void*>(callable_wrapper) 155 ); 72 156 fibril_add_ready(id_); 73 157 } … … 99 183 private: 100 184 fid_t id_; 185 aux::joinable_wrapper* joinable_wrapper_{nullptr}; 186 187 template<class Callable> 188 friend int aux::thread_main(void*); 101 189 }; 190 191 namespace aux 192 { 193 template<class CallablePtr> 194 int thread_main(void* clbl) 195 { 196 if (!clbl) 197 return 1; 198 199 auto callable = static_cast<CallablePtr>(clbl); 200 (*callable)(); 201 202 if (callable->detached()) // No thread owns the wrapper. 203 delete callable; 204 205 return 0; 206 } 207 } 102 208 103 209 void swap(thread& x, thread& y) noexcept; -
uspace/lib/cpp/src/thread.cpp
ree51635 r48d9187 42 42 if (joinable()) 43 43 { 44 if (joinable_wrapper_) 45 { 46 joinable_wrapper_->join(); 47 delete joinable_wrapper_; 48 } 49 44 50 // TODO: this crashes :( 45 51 /* fibril_teardown((fibril_t*)id_, false); */ … … 69 75 bool thread::joinable() const noexcept 70 76 { 71 return get_id() != id{};77 return id_ != fid_t{}; 72 78 } 73 79 74 80 void thread::join() 75 81 { 76 // TODO: 82 if (joinable_wrapper_) 83 { 84 printf("JOINING\n"); 85 joinable_wrapper_->join(); 86 printf("JOIN ENDED\n"); 87 } 77 88 } 78 89 … … 80 91 { 81 92 id_ = fid_t{}; 93 94 if (joinable_wrapper_) 95 { 96 joinable_wrapper_->detach(); 97 joinable_wrapper_ = nullptr; 98 } 82 99 } 83 100
Note:
See TracChangeset
for help on using the changeset viewer.