メインページ | モジュール | 名前空間一覧 | クラス階層 | 構成 | ファイル一覧 | 名前空間メンバ | 構成メンバ | ファイルメンバ | 関連ページ

toppers/task.hpp

解説を見る。
00001 /*
00002  *  TOPPERS/C++ API Template Library
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      C++ API Template Library
00005  *
00006  *  Copyright (C) 2004 by TAKAGI Nobuhisa
00007  *
00008  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
00009  *  によって公表されている GNU General Public License の Version 2 に記
00010  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00011  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00012  *  利用と呼ぶ)することを無償で許諾する.
00013  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00014  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00015  *      スコード中に含まれていること.
00016  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00017  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00018  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00019  *      の無保証規定を掲載すること.
00020  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00021  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00022  *      と.
00023  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00024  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00025  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00026  *        報告すること.
00027  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00028  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00029  *
00030  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00031  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00032  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00033  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00034  *
00035  *  @(#) $Id: task.hpp,v 1.1.1.1 2004/04/14 09:30:31 takagi-n Exp $
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_