OSDN Git Service

(none)
[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-2006 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{ミューテックスのロック獲得} */
24 ER loc_mtx(ID mtxid)
25 {
26         /* %jp{pol_mtxやtloc_mtxと共通処理とする} */
27         return _kernel_loc_mtx(mtxid, TMO_FEVR);
28 }
29
30 #else
31
32 /** %jp{ミューテックスのロック獲得} */
33 ER loc_mtx(ID mtxid)
34 {
35         _KERNEL_T_MTXCB_RO_PTR  mtxcb_ro;
36         _KERNEL_T_MTXCB_PTR             mtxcb;
37         _KERNEL_T_MTXHDL                mtxhdl;
38         _KERNEL_T_TCB_PTR               tcb;
39         _KERNEL_T_TSKHDL                tskhdl;
40         _KERNEL_T_TSKHDL                tskhdl_lock;
41         ER                                              ercd;
42                 
43         /* %jp{コンテキストチェック} */
44 #if _KERNEL_SPT_LOC_MTX_E_CTX
45         if ( _KERNEL_SYS_SNS_DPN() )
46         {
47                 return E_CTX;                   /* %jp{コンテキストエラー}%en{Context error} */
48         }
49 #endif
50
51         /* %jp{ID のチェック} */
52 #if _KERNEL_SPT_LOC_MTX_E_ID
53         if ( !_KERNEL_MTX_CHECK_MTXID(mtxid) )
54         {
55                 return E_ID;    /* %jp{不正ID番号}%en{Invalid ID number} */
56         }
57 #endif
58         
59         _KERNEL_ENTER_SVC();            /* %jp{サービスコールに入る}%en{enter service-call} */
60         
61         /* %jp{オブジェクト存在チェック} */
62 #if _KERNEL_SPT_LOC_MTX_E_NOEXS
63         if ( !_KERNEL_MTX_CHECK_EXS(mtxid) )
64         {
65                 _KERNEL_LEAVE_SVC();    /* %jp{サービスコールから出る}%en{leave service-call} */
66                 return E_NOEXS;                 /* %jp{オブジェクト未生成}%en{Non-existant object} */
67         }
68 #endif
69
70         /* %jp{ミューテックスコントロールブロック取得} */
71         mtxcb    = _KERNEL_MTX_ID2MTXCB(mtxid);
72         mtxcb_ro = _KERNEL_MTX_GET_MTXCB_RO(mtxid, mtxcb);
73
74         /* %jp{実行中のタスクハンドルを取得} */
75         tskhdl = _KERNEL_SYS_GET_RUNTSK();
76         tcb    = _KERNEL_TSK_TSKHDL2TCB(tskhdl);
77         
78         /* ロック中のタスクハンドル取得 */
79         tskhdl_lock = _KERNEL_MTX_GET_TSKHDL(mtxcb);
80
81         if ( _KERNEL_MTX_GET_TSKHDL(mtxcb) == _KERNEL_TSKHDL_NULL )
82         {
83                 /* %jp{所有タスクが居なければミューテックスをロック} */
84                 _KERNEL_MTX_SET_TSKHDL(mtxcb, tskhdl);          /* %jp{ミューテックス資源の獲得} */
85
86                 /* %jp{ミューテックスをTCBに接続} */
87                 mtxhdl = _KERNEL_MTX_GET_MTXHDL(mtxid, mtxcb);
88                 _kernel_add_mtx(mtxcb, mtxhdl, tcb);
89                         
90 #if _KERNEL_SPT_MTX_TA_CEILING
91                 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_CEILING )
92                 {
93                         /* %jp{タスクの優先度をシーリング値まで引き上げ} */
94                         if ( _KERNEL_TSK_GET_TSKPRI(tcb) < _KERNEL_MTX_GET_CEILPRI(mtxcb_ro) )
95                         {
96                                 _KERNEL_TSK_SET_TSKPRI(tcb, _KERNEL_MTX_GET_CEILPRI(mtxcb_ro));
97                         }
98                 }
99 #endif
100                 
101                 ercd = E_OK;
102         }
103         else
104         {
105                 /* %jp{タスクを待ち状態にする} */
106                 _KERNEL_TSK_SET_TSKWAIT(tcb, _KERNEL_TTW_MTX);
107                 _KERNEL_TSK_SET_WOBJID(tcb, mtxid);
108                 _KERNEL_DSP_WAI_TSK(tskhdl);
109                 _KERNEL_MTX_ADD_QUE(mtxcb, _KERNEL_MTX_GET_MTXCB_RO(mtxid, mtxcb), tskhdl);                     /* %jp{待ち行列に追加} */
110
111 #if _KERNEL_SPT_MTX_TA_INHERIT
112                 /* %jp{優先度継承} */
113                 if ( _KERNEL_MTX_GET_MTXATR(mtxcb_ro) == TA_INHERIT )
114                 {
115                         _KERNEL_T_TCB_PTR tcb_lock;
116
117                         /* %jp{ロック中タスクのTCB取得} */
118                         tcb_lock = _KERNEL_TSK_TSKHDL2TCB(tskhdl_lock);
119
120                         /* %jp{優先度継承} */
121                         if ( _KERNEL_TSK_GET_TSKPRI(tcb_lock) > _KERNEL_TSK_GET_TSKPRI(tcb) )
122                         {
123                                 _KERNEL_TSK_SET_TSKPRI(tcb_lock, _KERNEL_TSK_GET_TSKPRI(tcb));
124                                 if ( _KERNEL_TSK_GET_TSKSTAT(tcb) == TTS_RDY )
125                                 {
126                                         _KERNEL_SYS_RMV_RDQ(tskhdl);
127                                         _KERNEL_SYS_ADD_RDQ(tskhdl);
128                                 }
129                         }
130                 }
131 #endif
132
133                 /* %jp{タスクディスパッチの実行} */
134                 _KERNEL_DSP_TSK();
135
136                 /* %jp{エラーコードの取得} */
137                 ercd = _KERNEL_TSK_GET_ERCD(tcb);
138         }
139         
140         _KERNEL_LEAVE_SVC();    /* %jp{オブジェクト未生成}%en{Non-existant object} */
141         
142         return ercd;
143 }
144
145 #endif
146
147
148 #else   /* _KERNEL_SPT_LOC_MTX */
149
150
151 #if _KERNEL_SPT_LOC_MTX_E_NOSPT
152
153 /** %jp{ミューテックス資源の獲得}%en{Acquire Mutex Resource}
154  * @param  mtxid    %jp{資源獲得対象のミューテックスID番号}%en{ID number of the mutex from which resource is acquired}
155  * @retval E_NOSPT  %jp{未サポート機能}%en{Unsupported function}
156  */
157 ER loc_mtx(ID mtxid)
158 {
159         return E_NOSPT;
160 }
161
162 #endif
163
164
165 #endif  /* _KERNEL_SPT_LOC_MTX */
166
167
168
169 /* end of file */