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_TASK_HPP_
00052 #define TOPPERS_TASK_HPP_
00053
00054 #include <exception>
00055 #include <toppers/context.hpp>
00056
00057 #ifdef STACKSIZE
00058 #define TOPPERS_STACKSIZE STACKSIZE
00059 #elif STACK_SIZE
00060 #define TOPPERS_STACKSIZE STACK_SIZE
00061 #else
00062 #define TOPPERS_STACKSIZE 1024
00063 #endif
00064
00065 namespace toppers
00066 {
00067
00068 template <class Body> void task_entry(VP_INT);
00069
00070 template <class Diagnostics, class Stub> class task_body;
00071
00084 template <ID Id = 0,
00085 class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS,
00086 class Stub = TOPPERS_DEFAULT_STUB >
00087 class task : Diagnostics
00088 {
00089 typedef object_controller<Id, obj_task, Stub> controller;
00090 object_id<Id> objid_;
00091
00092 public:
00094 typedef t_ctsk creation;
00096 typedef t_rtsk reference;
00098 typedef t_rtst easy_reference;
00100 typedef task_body<Diagnostics, Stub> body;
00101
00104
00106 task() {}
00108 explicit task(ID id) : objid_(id) {}
00109
00111 template <ID Id2, class Diagnostics2, class Stub2>
00112 task(const task<Id2, Diagnostics2, Stub2>& other)
00113 : objid_(get_unsafe_id(other))
00114 {
00115 TOPPERS_STATIC_ASSERT(Id == 0);
00116 }
00117
00119
00122
00123
00124 ER create(creation* pk_cobj)
00125 {
00126 ER ercd = controller::create(objid_, pk_cobj);
00127 return handle_error(ercd);
00128 }
00130 ER create(const creation* pk_cobj)
00131 {
00132 ER ercd = controller::create(objid_, pk_cobj);
00133 return handle_error(ercd);
00134 }
00136 ER create(ATR tskatr, VP_INT exinf, void (*entry)(VP_INT), PRI itskpri = 0, SIZE stksz = TOPPERS_STACKSIZE, VP stk = 0)
00137 {
00138 creation packet;
00139 packet.tskatr = tskatr;
00140 packet.exinf = exinf;
00141 packet.task = FP(entry);
00142 if (itskpri == 0)
00143 Stub::stub_get_pri(TSK_SELF, &itskpri);
00144 packet.itskpri = itskpri;
00145 packet.stksz = stksz;
00146 packet.stk = stk;
00147 return create(&packet);
00148 }
00150 template <class Body>
00151 ER create(ATR tskatr = TA_ACT, VP_INT exinf = 0, PRI itskpri = 0, SIZE stksz = TOPPERS_STACKSIZE, VP stk = 0)
00152 {
00153 return create(tskatr & ~TA_ASM | TA_HLNG, exinf, &task_entry<Body>, itskpri, stksz, stk);
00154 }
00156 ER destroy()
00157 {
00158 ER ercd = controller::destroy(objid_);
00159 return handle_error(ercd);
00160 }
00161
00163
00166
00168 ER refer(reference* pk_robj) const
00169 {
00170 ER ercd = controller::refer(objid_, pk_robj);
00171 return handle_error(ercd);
00172 }
00174 ER refer(easy_reference* pk_robj) const
00175 {
00176 ER ercd = Stub::stub_ref_tst(objid_.id(), pk_robj);
00177 return handle_error(ercd);
00178 }
00179
00181
00184
00186 ER activate(task_context_tag = task_context) const
00187 {
00188 ER ercd = Stub::stub_act_tsk(objid_.id());
00189 return handle_error(ercd);
00190 }
00192 ER activate(non_task_context_tag) const
00193 {
00194 ER ercd = Stub::stub_iact_tsk(objid_.id());
00195 return handle_error(ercd);
00196 }
00198 ER activate(context_independent_tag) const
00199 {
00200 ER ercd;
00201 if (Stub::stub_sns_ctx())
00202 ercd = Stub::stub_iact_tsk(objid_.id());
00203 else
00204 ercd = Stub::stub_act_tsk(objid_.id());
00205 return handle_error(ercd);
00206 }
00208 ER activate(VP_INT exinf) const
00209 {
00210 ER ercd = Stub::stub_sta_tsk(objid_.id(), exinf);
00211 return handle_error(ercd);
00212 }
00214 ER start(VP_INT exinf) const
00215 {
00216 return activate(exinf);
00217 }
00219 ER_UINT cancel_activation() const
00220 {
00221 ER_UINT ercd = Stub::stub_can_act(objid_.id());
00222 return handle_error(ercd);
00223 }
00224
00226 ER terminate() const
00227 {
00228 ER ercd = Stub::stub_ter_tsk(objid_.id());
00229 return handle_error(ercd);
00230 }
00231
00233 ER change_priority(PRI tskpri) const
00234 {
00235 ER ercd = Stub::stub_chg_pri(objid_.id(), tskpri);
00236 return handle_error(ercd);
00237 }
00239 ER get_priority(PRI* p_tskpri) const
00240 {
00241 ER ercd = Stub::stub_get_pri(objid_.id(), p_tskpri);
00242 return handle_error(ercd);
00243 }
00244
00246
00249
00251 ER wakeup(task_context_tag = task_context) const
00252 {
00253 ER ercd = Stub::stub_wup_tsk(objid_.id());
00254 return handle_error(ercd);
00255 }
00257 ER wakeup(non_task_context_tag) const
00258 {
00259 ER ercd = Stub::stub_iwup_tsk(objid_.id());
00260 return handle_error(ercd);
00261 }
00263 ER wakeup(context_independent_tag) const
00264 {
00265 ER ercd;
00266 if (Stub::stub_sns_ctx())
00267 ercd = Stub::stub_iwup_tsk(objid_.id());
00268 else
00269 ercd = Stub::stub_wup_tsk(objid_.id());
00270 return handle_error(ercd);
00271 }
00273 ER_UINT cancel_wakeup() const
00274 {
00275 ER_UINT ercd = Stub::stub_can_wup(objid_.id());
00276 return handle_error(ercd);
00277 }
00278
00280 ER release_wait(task_context_tag = task_context) const
00281 {
00282 ER ercd = Stub::stub_rel_wai(objid_.id());
00283 return handle_error(ercd);
00284 }
00286 ER release_wait(non_task_context_tag) const
00287 {
00288 ER ercd = Stub::stub_irel_wai(objid_.id());
00289 return handle_error(ercd);
00290 }
00292 ER release_wait(context_independent_tag) const
00293 {
00294 ER ercd;
00295 if (Stub::stub_sns_ctx())
00296 ercd = Stub::stub_irel_wai(objid_.id());
00297 else
00298 ercd = Stub::stub_rel_wai(objid_.id());
00299 return handle_error(ercd);
00300 }
00301
00303 ER suspend() const
00304 {
00305 ER ercd = Stub::stub_sus_tsk(objid_.id());
00306 return handle_error(ercd);
00307 }
00309 ER resume(normal_tag = normal) const
00310 {
00311 ER ercd = Stub::stub_rsm_tsk(objid_.id());
00312 return handle_error(ercd);
00313 }
00315 ER resume(forced_tag) const
00316 {
00317 ER ercd = Stub::stub_frsm_tsk(objid_.id());
00318 return handle_error(ercd);
00319 }
00320
00322
00324 friend ID get_unsafe_id(const task<Id, Diagnostics, Stub>& obj)
00325 {
00326 return obj.objid_.id();
00327 }
00328 };
00329
00344 template <class Diagnostics = TOPPERS_DEFAULT_DIAGNOSTICS,
00345 class Stub = TOPPERS_DEFAULT_STUB >
00346 class task_body : public task_context_body<Diagnostics, Stub>
00347 {
00348 task<0, Diagnostics, Stub> task_;
00349
00350 protected:
00352 ~task_body() {}
00353
00354 public:
00355 class terminator;
00356
00358 explicit task_body(VP_INT exinf)
00359 : task_context_body<Diagnostics, Stub>(exinf), task_(get_task_id())
00360 {
00361 }
00362
00364 const task<0, Diagnostics, Stub>& get_task() const
00365 {
00366 return task_;
00367 }
00368
00382 static void exit()
00383 {
00384 terminator term(Stub::stub_ext_tsk);
00385 throw term;
00386 }
00400 static void exit_and_destroy()
00401 {
00402 terminator term(Stub::stub_exd_tsk);
00403 throw term;
00404 }
00405 };
00406
00418 template <class Diagnostics, class Stub>
00419 class task_body<Diagnostics, Stub>::terminator
00420 {
00421 public:
00423 explicit terminator(FP exit_proc, int x = 0)
00424 : exit_proc_(exit_proc)
00425 {
00426 }
00427
00429 FP get_exit_proc() const
00430 {
00431 return exit_proc_;
00432 }
00433
00434 private:
00435 FP exit_proc_;
00436 };
00437
00438 #ifndef TOPPERS_TASK_INITIALIZE
00439 #define TOPPERS_TASK_INITIALIZE() ((void)0)
00440 #endif
00441
00452 template <class Body>
00453 inline void task_entry(VP_INT exinf)
00454 {
00455 TOPPERS_TASK_INITIALIZE();
00456 void (*exit_proc)() = 0;
00457 try
00458 {
00459 Body body(exinf);
00460 body.run();
00461 }
00462 catch (typename Body::terminator& e)
00463 {
00464 exit_proc = (void(*)())e.get_exit_proc();
00465 }
00466 catch (...)
00467 {
00468 std::terminate();
00469 }
00470 if (exit_proc != 0)
00471 (*exit_proc)();
00472 }
00473
00474 }
00475
00476 #endif // ! TOPPERS_TASK_HPP_