2 * Hyper Operating System V4 Advance
5 * @brief %jp{ミューテックスのロック獲得}%en{Lock Mutex}
7 * Copyright (C) 1998-2009 by Project HOS
8 * http://sourceforge.jp/projects/hos/
13 #include "core/core.h"
14 #include "object/mtxobj.h"
18 #if _KERNEL_SPT_LOC_MTX
21 #if _KERNEL_SPT_KLOC_MTX && (_KERNEL_OPT_CODE_SIZE <= _KERNEL_OPT_SPEED) /* %jp{コードサイズ優先で統合ありなら} */
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)}
35 /* %jp{pol_mtxやtloc_mtxと共通処理とする} */
36 return _kernel_loc_mtx(mtxid, TMO_FEVR);
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)}
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;
62 #if _KERNEL_SPT_LOC_MTX_E_CTX
63 if ( _KERNEL_SYS_SNS_DPN() )
65 return E_CTX; /* %jp{コンテキストエラー}%en{Context error} */
70 #if _KERNEL_SPT_LOC_MTX_E_ID
71 if ( !_KERNEL_MTX_CHECK_MTXID(mtxid) )
73 return E_ID; /* %jp{不正ID番号}%en{Invalid ID number} */
77 _KERNEL_ENTER_SVC(); /* %jp{サービスコールに入る}%en{enter service-call} */
79 /* %jp{オブジェクト存在チェック} */
80 #if _KERNEL_SPT_LOC_MTX_E_NOEXS
81 if ( !_KERNEL_MTX_CHECK_EXS(mtxid) )
83 _KERNEL_LEAVE_SVC(); /* %jp{サービスコールから出る}%en{leave service-call} */
84 return E_NOEXS; /* %jp{オブジェクト未生成}%en{Non-existant object} */
88 /* %jp{ミューテックスコントロールブロック取得} */
89 mtxcb = _KERNEL_MTX_ID2MTXCB(mtxid);
90 mtxcb_ro = _KERNEL_MTX_GET_MTXCB_RO(mtxid, mtxcb);
92 /* %jp{実行中のタスクハンドルを取得} */
93 tskhdl = _KERNEL_SYS_GET_RUNTSK();
94 tcb = _KERNEL_TSK_TSKHDL2TCB(tskhdl);
96 /* %jp{ロック中のタスクハンドル取得} */
97 tskhdl_lock = _KERNEL_MTX_GET_TSKHDL(mtxcb);
99 if ( _KERNEL_MTX_GET_TSKHDL(mtxcb) == _KERNEL_TSKHDL_NULL )
101 /* %jp{所有タスクが居なければミューテックスをロック} */
102 _KERNEL_MTX_SET_TSKHDL(mtxcb, tskhdl); /* %jp{ミューテックス資源の獲得} */
104 /* %jp{ミューテックスをTCBに接続} */
105 mtxhdl = _KERNEL_MTX_GET_MTXHDL(mtxid, mtxcb);
106 _kernel_add_mtx(mtxhdl, tskhdl);
108 #if _KERNEL_SPT_MTX_TA_CEILING
109 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_CEILING )
111 /* %jp{タスクの優先度をシーリング値まで引き上げ} */
112 if ( _KERNEL_TSK_GET_TSKPRI(tcb) < _KERNEL_MTX_GET_CEILPRI(mtxcb_ro) )
114 _KERNEL_TSK_SET_TSKPRI(tcb, _KERNEL_MTX_GET_CEILPRI(mtxcb_ro));
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{待ち行列に追加} */
129 #if _KERNEL_SPT_MTX_TA_INHERIT
131 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_INHERIT )
133 _KERNEL_T_TCB_PTR tcb_lock;
135 /* %jp{ロック中タスクのTCB取得} */
136 tcb_lock = _KERNEL_TSK_TSKHDL2TCB(tskhdl_lock);
139 if ( _KERNEL_TSK_GET_TSKPRI(tcb_lock) > _KERNEL_TSK_GET_TSKPRI(tcb) )
141 _KERNEL_TSK_SET_TSKPRI(tcb_lock, _KERNEL_TSK_GET_TSKPRI(tcb));
142 if ( _KERNEL_TSK_GET_TSKSTAT(tcb_lock) == TTS_RDY )
144 _KERNEL_SYS_RMV_RDQ(tskhdl_lock);
145 _KERNEL_SYS_ADD_RDQ(tskhdl_lock);
151 /* %jp{タスクディスパッチの実行} */
155 ercd = _KERNEL_TSK_GET_ERCD(tcb);
158 _KERNEL_LEAVE_SVC(); /* %jp{オブジェクト未生成}%en{Non-existant object} */
166 #else /* _KERNEL_SPT_LOC_MTX */
169 #if _KERNEL_SPT_LOC_MTX_E_NOSPT
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}
183 #endif /* _KERNEL_SPT_LOC_MTX */