00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00053 #ifndef TOPPERS_SYNC_HPP_
00054 #define TOPPERS_SYNC_HPP_
00055
00056 #include <toppers/kernel.hpp>
00057 #include <toppers/assert.hpp>
00058
00059 namespace toppers
00060 {
00061
00062 namespace detail
00063 {
00064 template <bool SenseKernel, class LockObj> class lock_helper;
00065 }
00066
00067 template <ID Id, class Diagnostics, class Stub> class semaphore;
00068 template <ID Id, class Diagnostics, class Stub> class mutex;
00069
00090 template <class LockObj, bool SenseKernel = false>
00091 class lock
00092 {
00093 LockObj lock_;
00094
00095 public:
00097 lock()
00098 {
00099 detail::lock_helper<SenseKernel, LockObj>::lock(lock_);
00100 }
00102 template <typename T>
00103 explicit lock(T arg)
00104 : lock_(arg)
00105 {
00106 detail::lock_helper<SenseKernel, LockObj>::lock(lock_);
00107 }
00109 ~lock() throw()
00110 {
00111 detail::lock_helper<SenseKernel, LockObj>::unlock(lock_);
00112 }
00113 };
00114
00115 template <bool SenseKernel>
00116 class lock<void, SenseKernel>
00117 {
00118 lock()
00119 {
00120 }
00121 template <typename T>
00122 explicit lock(T arg)
00123 {
00124 }
00125 };
00126
00148 template <class LockObj, bool SenseKernel = false>
00149 class recursive_lock
00150 {
00151 bool state_;
00152 LockObj lock_;
00153
00154 public:
00156 recursive_lock()
00157 {
00158 state_ = detail::lock_helper<SenseKernel, LockObj>::sense(lock_);
00159 if (!state_)
00160 detail::lock_helper<SenseKernel, LockObj>::lock(lock_);
00161 }
00163 template <typename T>
00164 explicit recursive_lock(T arg)
00165 : lock_(arg)
00166 {
00167 state_ = detail::lock_helper<SenseKernel, LockObj>::sense(lock_);
00168 if (!state_)
00169 detail::lock_helper<SenseKernel, LockObj>::lock(lock_);
00170 }
00172 ~recursive_lock() throw()
00173 {
00174 if (!state_)
00175 detail::lock_helper<SenseKernel, LockObj>::unlock(lock_);
00176 }
00177 };
00178
00179 template <bool SenseKernel>
00180 class recursive_lock<void, SenseKernel>
00181 {
00182 recursive_lock()
00183 {
00184 }
00185 template <typename T>
00186 explicit recursive_lock(T arg)
00187 {
00188 }
00189 };
00190
00191 namespace detail
00192 {
00193
00194 template <class LockObj, ID Id, class Stub, bool SenseKernel>
00195 class recursive_lock_helper
00196 {
00197 TOPPERS_STATIC_ASSERT(Id > 0);
00198 LockObj lock_;
00199 static ID holder_;
00200 static UINT counter_;
00201
00202 public:
00203 recursive_lock_helper()
00204 {
00205 if (!sense_kernel<SenseKernel>() && !Stub::stub_sns_dsp())
00206 {
00207 ID tskid;
00208 Stub::stub_get_tid(&tskid);
00209 if (holder_ != tskid)
00210 {
00211 detail::lock_helper<false, LockObj>::lock(lock_);
00212 holder_ = tskid;
00213 }
00214 ++counter_;
00215 }
00216 }
00217 ~recursive_lock_helper() throw()
00218 {
00219 if (!sense_kernel<SenseKernel>() && !Stub::stub_sns_dsp())
00220 {
00221 if (--counter_ == 0)
00222 {
00223 holder_ = 0;
00224 detail::lock_helper<false, LockObj>::unlock(lock_);
00225 }
00226 }
00227 }
00228 };
00229
00230 template <class LockObj, ID Id, class Stub, bool SenseKernel>
00231 ID recursive_lock_helper<LockObj, Id, Stub, SenseKernel>::holder_ = 0;
00232
00233 template <class LockObj, ID Id, class Stub, bool SenseKernel>
00234 UINT recursive_lock_helper<LockObj, Id, Stub, SenseKernel>::counter_ = 0;
00235
00236 }
00237
00238 template <ID Id, class Diagnostics, class Stub, bool SenseKernel>
00239 class recursive_lock<semaphore<Id, Diagnostics, Stub>, SenseKernel>
00240 : detail::recursive_lock_helper<semaphore<Id, Diagnostics, Stub>, Id, Stub, SenseKernel>
00241 {
00242 };
00243
00244 template <ID Id, class Diagnostics, class Stub, bool SenseKernel>
00245 class recursive_lock<mutex<Id, Diagnostics, Stub>, SenseKernel>
00246 : detail::recursive_lock_helper<mutex<Id, Diagnostics, Stub>, Id, Stub, SenseKernel>
00247 {
00248 };
00249
00264 template <class LockObj, typename T>
00265 inline T& sync_increment(T& x)
00266 {
00267 lock<LockObj> loc;
00268 return ++x;
00269 }
00270
00285 template <class LockObj, typename T>
00286 inline T& sync_decrement(T& x)
00287 {
00288 lock<LockObj> loc;
00289 return --x;
00290 }
00291
00307 template <class LockObj, typename T>
00308 inline void sync_swap(T& x, T& y)
00309 {
00310 lock<LockObj> loc;
00311 T t = x;
00312 x = y;
00313 y = t;
00314 }
00315
00316 }
00317
00318 #endif // ! TOPPERS_SYNC_HPP_