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
00049 #ifndef TOPPERS_SEMAPHORE_HPP_
00050 #define TOPPERS_SEMAPHORE_HPP_
00051
00052 #include <toppers/object.hpp>
00053
00054 namespace toppers
00055 {
00056
00069 template <ID Id = 0,
00070 class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS,
00071 class Stub = TOPPERS_DEFAULT_STUB >
00072 class semaphore : Diagnostics
00073 {
00074 typedef object_controller<Id, obj_semaphore, Stub> controller;
00075 object_id<Id> objid_;
00076
00077 public:
00079 typedef t_csem creation;
00081 typedef t_rsem reference;
00082
00085
00087 semaphore() {}
00089 explicit semaphore(ID id) : objid_(id) {}
00090
00092 template <ID Id2, class Diagnostics2, class Stub2>
00093 semaphore(const semaphore<Id2, Diagnostics2, Stub2>& other)
00094 : objid_(get_unsafe_id(other))
00095 {
00096 TOPPERS_STATIC_ASSERT(Id == 0);
00097 }
00098
00100
00103
00104
00105 ER create(creation* pk_cobj)
00106 {
00107 ER ercd = controller::create(objid_, pk_cobj);
00108 return handle_error(ercd);
00109 }
00111 ER create(const creation* pk_cobj)
00112 {
00113 ER ercd = controller::create(objid_, pk_cobj);
00114 return handle_error(ercd);
00115 }
00117 ER create(ATR sematr = TA_TFIFO, UINT isemcnt = 1, UINT maxsem = 1)
00118 {
00119 creation packet;
00120 packet.sematr = sematr;
00121 packet.isemcnt = isemcnt;
00122 packet.maxsem = maxsem;
00123 return create(&packet);
00124 }
00126 ER destroy()
00127 {
00128 ER ercd = controller::destroy(objid_);
00129 return handle_error(ercd);
00130 }
00131
00133
00136
00138 ER refer(reference* pk_robj) const
00139 {
00140 ER ercd = controller::refer(objid_, pk_robj);
00141 return handle_error(ercd);
00142 }
00143
00145
00148
00150 ER signal(task_context_tag = task_context) const
00151 {
00152 ER ercd = Stub::stub_sig_sem(objid_.id());
00153 return handle_error(ercd);
00154 }
00156 ER signal(non_task_context_tag) const
00157 {
00158 ER ercd = Stub::stub_isig_sem(objid_.id());
00159 return handle_error(ercd);
00160 }
00162 ER signal(context_independent_tag) const
00163 {
00164 ER ercd;
00165 if (Stub::stub_sns_ctx())
00166 ercd = Stub::stub_isig_sem(objid_.id());
00167 else
00168 ercd = Stub::stub_sig_sem(objid_.id());
00169 return handle_error(ercd);
00170 }
00171
00173 ER wait(forever_tag = forever) const
00174 {
00175 ER ercd = Stub::stub_wai_sem(objid_.id());
00176 return handle_error(ercd);
00177 }
00179 ER wait(polling_tag) const
00180 {
00181 ER ercd = Stub::stub_pol_sem(objid_.id());
00182 return handle_error(ercd);
00183 }
00185 ER wait(TMO tmout) const
00186 {
00187 ER ercd = Stub::stub_twai_sem(objid_.id(), tmout);
00188 return handle_error(ercd);
00189 }
00190
00192
00194 friend ID get_unsafe_id(const semaphore<Id, Diagnostics, Stub>& obj)
00195 {
00196 return obj.objid_.id();
00197 }
00198 };
00199
00200 namespace detail
00201 {
00202
00203 template <bool SenseKernel, class LockObj> class lock_helper;
00204
00205 template <bool SenseKernel, ID Id, class Diagnostics, class Stub>
00206 class lock_helper<SenseKernel, semaphore<Id, Diagnostics, Stub> >
00207 {
00208 public:
00209 typedef semaphore<Id, Diagnostics, Stub> sync_type;
00210
00211 static ER lock(const sync_type& sync)
00212 {
00213 return sense_kernel<SenseKernel>() ? E_OK : sync.wait();
00214 }
00215 static ER unlock(const sync_type& sync)
00216 {
00217 return sense_kernel<SenseKernel>() ? E_OK : sync.signal();
00218 }
00219 };
00220
00221 }
00222
00223 }
00224
00225 #endif // ! TOPPERS_SEMAPHORE_HPP_