OSDN Git Service

update jelly sample (MIPS)
[hos/hos-v4a.git] / kernel / source / object / mtx / loc_mtx.c
1 /** 
2  *  Hyper Operating System V4 Advance
3  *
4  * @file  loc_mtx.c
5  * @brief %jp{ミューテックスのロック獲得}%en{Lock Mutex}
6  *
7  * Copyright (C) 1998-2009 by Project HOS
8  * http://sourceforge.jp/projects/hos/
9  */
10
11
12
13 #include "core/core.h"
14 #include "object/mtxobj.h"
15
16
17
18 #if _KERNEL_SPT_LOC_MTX
19
20
21 #if _KERNEL_SPT_KLOC_MTX && (_KERNEL_OPT_CODE_SIZE <= _KERNEL_OPT_SPEED)        /* %jp{コードサイズ優先で統合ありなら} */
22
23 /** %jp{ミューテックスのロック獲得}%en{Lock Mutex}
24  * @param  mtxid    %jp{ロック対象のミューテックスID番号}%en{ID number of the mutex to be locked}
25  * @retval E_OK     %jp{正常終了}%en{Normal completion}
26  * @retval E_ID     %jp{不正ID番号(mtxidが不正あるいは使用できない)}%en{Invalid ID number(mtxid is invalid or unusable)}
27  * @retval E_CTX    %jp{コンテキストエラー}%en{Context error}
28  * @retval E_NOEXS  %jp{オブジェクト未生成(対象ミューテックスが未登録)}%en{Non-existant object(specified mutex is not registerd)}
29  * @retval E_ILUSE  %jp{サービスコール不正使用(ミューテックスの多重ロック,上限優先度の違反)}%en{Illegal service call use(multiple locking of a mutex, ceiling priority violation)}
30  * @retval E_RLWAI  %jp{待ち状態の強制解除(待ち状態の間にrel_waiを受付)}%en{Forced release from waiting(accept rel_wai while waiting)}
31  * @retval E_DLT    %jp{待ちオブジェクトの削除(待ち状態の間に対象ミューテックスが削除)}%en{Waiting object deleted(mutex is deleted waiting)}
32  */
33 ER loc_mtx(ID mtxid)
34 {
35         /* %jp{pol_mtxやtloc_mtxと共通処理とする} */
36         return _kernel_loc_mtx(mtxid, TMO_FEVR);
37 }
38
39 #else
40
41 /** %jp{ミューテックスのロック獲得}%en{Lock Mutex}
42  * @param  mtxid    %jp{ロック対象のミューテックスID番号}%en{ID number of the mutex to be locked}
43  * @retval E_OK     %jp{正常終了}%en{Normal completion}
44  * @retval E_ID     %jp{不正ID番号(mtxidが不正あるいは使用できない)}%en{Invalid ID number(mtxid is invalid or unusable)}
45  * @retval E_CTX    %jp{コンテキストエラー}%en{Context error}
46  * @retval E_NOEXS  %jp{オブジェクト未生成(対象ミューテックスが未登録)}%en{Non-existant object(specified mutex is not registerd)}
47  * @retval E_ILUSE  %jp{サービスコール不正使用(ミューテックスの多重ロック,上限優先度の違反)}%en{Illegal service call use(multiple locking of a mutex, ceiling priority violation)}
48  * @retval E_RLWAI  %jp{待ち状態の強制解除(待ち状態の間にrel_waiを受付)}%en{Forced release from waiting(accept rel_wai while waiting)}
49  * @retval E_DLT    %jp{待ちオブジェクトの削除(待ち状態の間に対象ミューテックスが削除)}%en{Waiting object deleted(mutex is deleted waiting)}
50  */
51 ER loc_mtx(ID mtxid)
52 {
53         _KERNEL_T_MTXCB_RO_PTR  mtxcb_ro;
54         _KERNEL_T_MTXCB_PTR             mtxcb;
55         _KERNEL_T_MTXHDL                mtxhdl;
56         _KERNEL_T_TCB_PTR               tcb;
57         _KERNEL_T_TSKHDL                tskhdl;
58         _KERNEL_T_TSKHDL                tskhdl_lock;
59         ER                                              ercd;
60         
61         /* %jp{コンテキストチェック} */
62 #if _KERNEL_SPT_LOC_MTX_E_CTX
63         if ( _KERNEL_SYS_SNS_DPN() )
64         {
65                 return E_CTX;                   /* %jp{コンテキストエラー}%en{Context error} */
66         }
67 #endif
68         
69         /* %jp{ID のチェック} */
70 #if _KERNEL_SPT_LOC_MTX_E_ID
71         if ( !_KERNEL_MTX_CHECK_MTXID(mtxid) )
72         {
73                 return E_ID;                    /* %jp{不正ID番号}%en{Invalid ID number} */
74         }
75 #endif
76         
77         _KERNEL_ENTER_SVC();            /* %jp{サービスコールに入る}%en{enter service-call} */
78         
79         /* %jp{オブジェクト存在チェック} */
80 #if _KERNEL_SPT_LOC_MTX_E_NOEXS
81         if ( !_KERNEL_MTX_CHECK_EXS(mtxid) )
82         {
83                 _KERNEL_LEAVE_SVC();    /* %jp{サービスコールから出る}%en{leave service-call} */
84                 return E_NOEXS;                 /* %jp{オブジェクト未生成}%en{Non-existant object} */
85         }
86 #endif
87
88         /* %jp{ミューテックスコントロールブロック取得} */
89         mtxcb    = _KERNEL_MTX_ID2MTXCB(mtxid);
90         mtxcb_ro = _KERNEL_MTX_GET_MTXCB_RO(mtxid, mtxcb);
91
92         /* %jp{実行中のタスクハンドルを取得} */
93         tskhdl = _KERNEL_SYS_GET_RUNTSK();
94         tcb    = _KERNEL_TSK_TSKHDL2TCB(tskhdl);
95         
96         /* %jp{ロック中のタスクハンドル取得} */
97         tskhdl_lock = _KERNEL_MTX_GET_TSKHDL(mtxcb);
98
99         if ( _KERNEL_MTX_GET_TSKHDL(mtxcb) == _KERNEL_TSKHDL_NULL )
100         {
101                 /* %jp{所有タスクが居なければミューテックスをロック} */
102                 _KERNEL_MTX_SET_TSKHDL(mtxcb, tskhdl);          /* %jp{ミューテックス資源の獲得} */
103
104                 /* %jp{ミューテックスをTCBに接続} */
105                 mtxhdl = _KERNEL_MTX_GET_MTXHDL(mtxid, mtxcb);
106                 _kernel_add_mtx(mtxhdl, tskhdl);
107                 
108 #if _KERNEL_SPT_MTX_TA_CEILING
109                 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_CEILING )
110                 {
111                         /* %jp{タスクの優先度をシーリング値まで引き上げ} */
112                         if ( _KERNEL_TSK_GET_TSKPRI(tcb) < _KERNEL_MTX_GET_CEILPRI(mtxcb_ro) )
113                         {
114                                 _KERNEL_TSK_SET_TSKPRI(tcb, _KERNEL_MTX_GET_CEILPRI(mtxcb_ro));
115                         }
116                 }
117 #endif
118                 
119                 ercd = E_OK;
120         }
121         else
122         {
123                 /* %jp{タスクを待ち状態にする} */
124                 _KERNEL_TSK_SET_TSKWAIT(tcb, _KERNEL_TTW_MTX);
125                 _KERNEL_TSK_SET_WOBJID(tcb, mtxid);
126                 _KERNEL_DSP_WAI_TSK(tskhdl);
127                 _KERNEL_MTX_ADD_QUE(mtxcb, _KERNEL_MTX_GET_MTXCB_RO(mtxid, mtxcb), tskhdl);                     /* %jp{待ち行列に追加} */
128
129 #if _KERNEL_SPT_MTX_TA_INHERIT
130                 /* %jp{優先度継承} */
131                 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_INHERIT )
132                 {
133                         _KERNEL_T_TCB_PTR tcb_lock;
134
135                         /* %jp{ロック中タスクのTCB取得} */
136                         tcb_lock = _KERNEL_TSK_TSKHDL2TCB(tskhdl_lock);
137
138                         /* %jp{優先度継承} */
139                         if ( _KERNEL_TSK_GET_TSKPRI(tcb_lock) > _KERNEL_TSK_GET_TSKPRI(tcb) )
140                         {
141                                 _KERNEL_TSK_SET_TSKPRI(tcb_lock, _KERNEL_TSK_GET_TSKPRI(tcb));
142                                 if ( _KERNEL_TSK_GET_TSKSTAT(tcb_lock) == TTS_RDY )
143                                 {
144                                         _KERNEL_SYS_RMV_RDQ(tskhdl_lock);
145                                         _KERNEL_SYS_ADD_RDQ(tskhdl_lock);
146                                 }
147                         }
148                 }
149 #endif
150
151                 /* %jp{タスクディスパッチの実行} */
152                 _KERNEL_DSP_TSK();
153
154                 /* %jp{エラーコードの取得} */
155                 ercd = _KERNEL_TSK_GET_ERCD(tcb);
156         }
157         
158         _KERNEL_LEAVE_SVC();    /* %jp{オブジェクト未生成}%en{Non-existant object} */
159         
160         return ercd;
161 }
162
163 #endif
164
165
166 #else   /* _KERNEL_SPT_LOC_MTX */
167
168
169 #if _KERNEL_SPT_LOC_MTX_E_NOSPT
170
171 /** %jp{ミューテックスのロック獲得}%en{Lock Mutex}
172  * @param  mtxid    %jp{ロック対象のミューテックスID番号}%en{ID number of the mutex to be locked}
173  * @retval E_NOSPT  %jp{未サポート機能}%en{Unsupported function}
174  */
175 ER loc_mtx(ID mtxid)
176 {
177         return E_NOSPT;
178 }
179
180 #endif
181
182
183 #endif  /* _KERNEL_SPT_LOC_MTX */
184
185
186
187 /* end of file */