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

toppers/taskexception.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: taskexception.hpp,v 1.1.1.1 2004/04/14 09:30:31 takagi-n Exp $
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_