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
00051 #ifndef TOPPERS_TASKEXCEPTION_HPP_
00052 #define TOPPERS_TASKEXCEPTION_HPP_
00053
00054 #include <toppers/context.hpp>
00055
00056 namespace toppers
00057 {
00058
00059 template <class Body> void taskexception_entry(TEXPTN texptn, VP_INT exinf);
00060
00061 template <ID Id, class Diagnostics, class Stub> class task;
00062 template <class Diagnostics, class Stub> class taskexception_body;
00063
00077 template <class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS,
00078 class Stub = TOPPERS_DEFAULT_STUB >
00079 class taskexception : Diagnostics
00080 {
00081 public:
00083 typedef t_dtex definition;
00085 typedef t_rtex reference;
00087 typedef taskexception_body<Diagnostics, Stub> body;
00088
00091
00092
00093 template <ID Id, class Diagnostics2, class Stub2>
00094 static ER define(const task<Id, Diagnostics2, Stub2>& host, definition* pk_dobj)
00095 {
00096 ER ercd = Stub::stub_def_tex(get_unsafe_id(host), pk_dobj);
00097 return static_handle_error(ercd);
00098 }
00100 template <ID Id, class Diagnostics2, class Stub2>
00101 static ER define(const task<Id, Diagnostics2, Stub2>& host, const definition* pk_dobj)
00102 {
00103 ER ercd = Stub::stub_def_tex(get_unsafe_id(host), pk_dobj);
00104 return static_handle_error(ercd);
00105 }
00107 template <ID Id, class Diagnostics2, class Stub2>
00108 static ER define(const task<Id, Diagnostics2, Stub2>& host, ATR texatr, void (*texrtn)(TEXPTN, VP_INT))
00109 {
00110 definition packet;
00111 packet.texatr = texatr;
00112 packet.texrtn = FP(texrtn);
00113 return define(host, &packet);
00114 }
00116 template <class Body, ID Id, class Diagnostics2, class Stub2>
00117 static ER define(const task<Id, Diagnostics2, Stub2>& host, ATR texatr = 0)
00118 {
00119 return define(host, texatr & ~TA_ASM | TA_HLNG, &taskexception_entry<Body>);
00120 }
00121
00122
00123 static ER define(definition* pk_dobj)
00124 {
00125 ER ercd = Stub::stub_def_tex(TSK_SELF, pk_dobj);
00126 return static_handle_error(ercd);
00127 }
00129 static ER define(const definition* pk_cobj)
00130 {
00131 ER ercd = Stub::stub_def_tex(TSK_SELF, pk_dobj);
00132 return static_handle_error(ercd);
00133 }
00135 static ER define(ATR texatr, void (*texrtn)(TEXPTN, VP_INT))
00136 {
00137 definition packet;
00138 packet.texatr = texatr;
00139 packet.texrtn = FP(texrtn);
00140 return define(&packet);
00141 }
00143 template <class Body>
00144 static ER define(ATR texatr = 0)
00145 {
00146 return define(texatr & ~TA_ASM | TA_HLNG, &taskexception_entry<Body>);
00147 }
00148
00150 template <ID Id, class Diagnostics2, class Stub2>
00151 static ER undefine(const task<Id, Diagnostics2, Stub2>& host)
00152 {
00153 return define(host, static_cast<definition*>(0));
00154 }
00156 static ER undefine()
00157 {
00158 return define(static_cast<definition*>(0));
00159 }
00160
00162
00165
00167 template <ID Id, class Diagnostics2, class Stub2>
00168 static ER refer(const task<Id, Diagnostics2, Stub2>& host, reference* pk_robj)
00169 {
00170 ER ercd = Stub::stub_ref_tex(get_unsafe_id(host), pk_robj);
00171 return static_handle_error(ercd);
00172 }
00174 static ER refer(reference* pk_robj)
00175 {
00176 ER ercd = Stub::stub_ref_tex(TSK_SELF, pk_robj);
00177 return static_handle_error(ercd);
00178 }
00179
00181
00184
00186 template <ID Id, class Diagnostics2, class Stub2>
00187 static ER raise(const task<Id, Diagnostics2, Stub2>& host, TEXPTN rasptn, task_context_tag = task_context)
00188 {
00189 ER ercd = Stub::stub_ras_tex(get_unsafe_id(host), rasptn);
00190 return static_handle_error(ercd);
00191 }
00193 template <ID Id, class Diagnostics2, class Stub2>
00194 static ER raise(const task<Id, Diagnostics2, Stub2>& host, TEXPTN rasptn, non_task_context_tag)
00195 {
00196 ER ercd = Stub::stub_iras_tex(get_unsafe_id(host), rasptn);
00197 return static_handle_error(ercd);
00198 }
00200 template <ID Id, class Diagnostics2, class Stub2>
00201 static ER raise(const task<Id, Diagnostics2, Stub2>& host, TEXPTN rasptn, context_independent_tag)
00202 {
00203 ER ercd;
00204 if (Stub::stub_sns_ctx())
00205 ercd = Stub::stub_iras_tex(get_unsafe_id(host), rasptn);
00206 else
00207 ercd = Stub::stub_ras_tex(get_unsafe_id(host), rasptn);
00208 return static_handle_error(ercd);
00209 }
00210
00212 static ER raise(TEXPTN rasptn, task_context_tag = task_context)
00213 {
00214 ER ercd = Stub::stub_ras_tex(TSK_SELF, rasptn);
00215 return static_handle_error(ercd);
00216 }
00218 static ER raise(TEXPTN rasptn, non_task_context_tag)
00219 {
00220 ER ercd = Stub::stub_iras_tex(TSK_SELF, rasptn);
00221 return static_handle_error(ercd);
00222 }
00224 static ER raise(TEXPTN rasptn, context_independent_tag)
00225 {
00226 ER ercd;
00227 if (Stub::stub_sns_ctx())
00228 ercd = Stub::stub_iras_tex(TSK_SELF, rasptn);
00229 else
00230 ercd = Stub::stub_ras_tex(TSK_SELF, rasptn);
00231 return static_handle_error(ercd);
00232 }
00233
00235
00238
00240 static ER disable()
00241 {
00242 ER ercd = Stub::stub_dis_tex();
00243 return static_handle_error(ercd);
00244 }
00246 static ER enable()
00247 {
00248 ER ercd = Stub::stub_ena_tex();
00249 return static_handle_error(ercd);
00250 }
00252 static bool sense()
00253 {
00254 return Stub::stub_sns_tex();
00255 }
00256
00258 };
00259
00260 namespace detail
00261 {
00262
00263 template <bool SenseKernel, class LockObj> class lock_helper;
00264
00265 template <bool SenseKernel, class Diagnostics, class Stub>
00266 class lock_helper<SenseKernel, taskexception<Diagnostics, Stub> >
00267 {
00268 public:
00269 typedef taskexception<Diagnostics, Stub> sync_type;
00270
00271 static bool sense(const sync_type& sync)
00272 {
00273 return sense_kernel<SenseKernel>() ? true : sync_type::sense();
00274 }
00275 static ER lock(const sync_type& sync)
00276 {
00277 return sense_kernel<SenseKernel>() ? E_OK : sync_type::disable();
00278 }
00279 static ER unlock(const sync_type& sync)
00280 {
00281 return sense_kernel<SenseKernel>() ? E_OK : sync_type::enable();
00282 }
00283 };
00284
00285 }
00286
00298 template <class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS,
00299 class Stub = TOPPERS_DEFAULT_STUB >
00300 class taskexception_body : public task_context_body<Diagnostics, Stub>
00301 {
00302 TOPPERS_STATIC_ASSERT(!Diagnostics::use_exception);
00303 TEXPTN texptn_;
00304 task<0, Diagnostics, Stub> task_;
00305 static TEXPTN texmask_;
00306
00307 protected:
00309 ~taskexception_body() {}
00310
00311 public:
00313 taskexception_body(TEXPTN texptn, VP_INT exinf)
00314 : task_context_body<Diagnostics, Stub>(exinf), texptn_(texptn), task_(get_task_id())
00315 {
00316 }
00317
00319 const task<0, Diagnostics, Stub>& get_task() const
00320 {
00321 return task_;
00322 }
00323
00324 TEXPTN get_pattern() const
00325 {
00326 return texptn_;
00327 }
00328
00330
00334 static bool filter(TEXPTN texptn)
00335 {
00336 return texmask_ & texptn;
00337 }
00339 static ER change_mask(TEXPTN mask)
00340 {
00341 texmask_ = mask;
00342 return E_OK;
00343 }
00345 static ER get_mask(TEXPTN* p_mask)
00346 {
00347 if (p_mask == 0)
00348 return E_PAR;
00349 *p_mask = texmask_;
00350 return E_OK;
00351 }
00352 };
00353
00354 template <class Diagnostics, class Stub>
00355 TEXPTN taskexception_body<Diagnostics, Stub>::texmask_ = ~TEXPTN(0);
00356
00357
00368 template <class Body>
00369 inline void taskexception_entry(TEXPTN texptn, VP_INT exinf)
00370 {
00371 if (Body::filter(texptn))
00372 {
00373 Body body(texptn, exinf);
00374 body.run();
00375 }
00376 }
00377
00378 }
00379
00380 #endif // ! TOPPERS_TASKEXCEPTION_HPP_