OSDN Git Service

Doxygenコメントを追加した。
[uzume/uzume_bfin.git] / uzumeapp / kernel / kernel / semaphore.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
13  *  利用と呼ぶ)することを無償で許諾する.
14  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16  *      スコード中に含まれていること.
17  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20  *      の無保証規定を掲載すること.
21  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23  *      と.
24  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
26  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27  *        報告すること.
28  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30  * 
31  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: semaphore.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39 /*
40  *  セマフォ機能
41  */
42
43 #include "jsp_kernel.h"
44 #include "check.h"
45 #include "task.h"
46 #include "wait.h"
47 #include "semaphore.h"
48
49 /*
50  *  セマフォIDの最大値(kernel_cfg.c)
51  */
52 extern const ID tmax_semid;
53
54 /*
55  *  セマフォ初期化ブロックのエリア(kernel_cfg.c)
56  */
57 extern const SEMINIB    seminib_table[];
58
59 /*
60  *  セマフォ管理ブロックのエリア(kernel_cfg.c)
61  */
62 extern SEMCB    semcb_table[];
63
64 /*
65  *  セマフォの数
66  */
67 #define TNUM_SEM    ((UINT)(tmax_semid - TMIN_SEMID + 1))
68
69 /*
70  *  セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
71  */
72 #define INDEX_SEM(semid)    ((UINT)((semid) - TMIN_SEMID))
73 #define get_semcb(semid)    (&(semcb_table[INDEX_SEM(semid)]))
74
75 /* 
76  *  セマフォ機能の初期化
77  */
78 #ifdef __semini
79
80 void
81 semaphore_initialize()
82 {
83     UINT    i;
84     SEMCB   *semcb;
85
86     for (semcb = semcb_table, i = 0; i < TNUM_SEM; semcb++, i++) {
87         queue_initialize(&(semcb->wait_queue));
88         semcb->seminib = &(seminib_table[i]);
89         semcb->semcnt = semcb->seminib->isemcnt;
90     }
91 }
92
93 #endif /* __semini */
94
95 /*
96  *  セマフォ資源の返却
97  */
98 #ifdef __sig_sem
99
100 SYSCALL ER
101 sig_sem(ID semid)
102 {
103     SEMCB   *semcb;
104     TCB *tcb;
105     ER  ercd;
106     
107     LOG_SIG_SEM_ENTER(semid);
108     CHECK_TSKCTX_UNL();
109     CHECK_SEMID(semid);
110     semcb = get_semcb(semid);
111
112     t_lock_cpu();
113     if (!(queue_empty(&(semcb->wait_queue)))) {
114         tcb = (TCB *) queue_delete_next(&(semcb->wait_queue));
115         if (wait_complete(tcb)) {
116             dispatch();
117         }
118         ercd = E_OK;
119     }
120     else if (semcb->semcnt < semcb->seminib->maxsem) {
121         semcb->semcnt += 1;
122         ercd = E_OK;
123     }
124     else {
125         ercd = E_QOVR;
126     }
127     t_unlock_cpu();
128
129     exit:
130     LOG_SIG_SEM_LEAVE(ercd);
131     return(ercd);
132 }
133
134 #endif /* __sig_sem */
135
136 /*
137  *  セマフォ資源の返却(非タスクコンテキスト用)
138  */
139 #ifdef __isig_sem
140
141 SYSCALL ER
142 isig_sem(ID semid)
143 {
144     SEMCB   *semcb;
145     TCB *tcb;
146     ER  ercd;
147     
148     LOG_ISIG_SEM_ENTER(semid);
149     CHECK_INTCTX_UNL();
150     CHECK_SEMID(semid);
151     semcb = get_semcb(semid);
152
153     i_lock_cpu();
154     if (!queue_empty(&(semcb->wait_queue))) {
155         tcb = (TCB *) queue_delete_next(&(semcb->wait_queue));
156         if (wait_complete(tcb)) {
157             reqflg = TRUE;
158         }
159         ercd = E_OK;
160     }
161     else if (semcb->semcnt < semcb->seminib->maxsem) {
162         semcb->semcnt += 1;
163         ercd = E_OK;
164     }
165     else {
166         ercd = E_QOVR;
167     }
168     i_unlock_cpu();
169
170     exit:
171     LOG_ISIG_SEM_LEAVE(ercd);
172     return(ercd);
173 }
174
175 #endif /* __isig_sem */
176
177 /*
178  *  セマフォ資源の獲得
179  */
180 #ifdef __wai_sem
181
182 SYSCALL ER
183 wai_sem(ID semid)
184 {
185     SEMCB   *semcb;
186     WINFO_WOBJ winfo;
187     ER  ercd;
188
189     LOG_WAI_SEM_ENTER(semid);
190     CHECK_DISPATCH();
191     CHECK_SEMID(semid);
192     semcb = get_semcb(semid);
193
194     t_lock_cpu();
195     if (semcb->semcnt >= 1) {
196         semcb->semcnt -= 1;
197         ercd = E_OK;
198     }
199     else {
200         wobj_make_wait((WOBJCB *) semcb, &winfo);
201         dispatch();
202         ercd = winfo.winfo.wercd;
203     }
204     t_unlock_cpu();
205
206     exit:
207     LOG_WAI_SEM_LEAVE(ercd);
208     return(ercd);
209 }
210
211 #endif /* __wai_sem */
212
213 /*
214  *  セマフォ資源の獲得(ポーリング)
215  */
216 #ifdef __pol_sem
217
218 SYSCALL ER
219 pol_sem(ID semid)
220 {
221     SEMCB   *semcb;
222     ER  ercd;
223
224     LOG_POL_SEM_ENTER(semid);
225     CHECK_TSKCTX_UNL();
226     CHECK_SEMID(semid);
227     semcb = get_semcb(semid);
228
229     t_lock_cpu();
230     if (semcb->semcnt >= 1) {
231         semcb->semcnt -= 1;
232         ercd = E_OK;
233     }
234     else {
235         ercd = E_TMOUT;
236     }
237     t_unlock_cpu();
238
239     exit:
240     LOG_POL_SEM_LEAVE(ercd);
241     return(ercd);
242 }
243
244 #endif /* __pol_sem */
245
246 /*
247  *  セマフォ資源の獲得(タイムアウトあり)
248  */
249 #ifdef __twai_sem
250
251 SYSCALL ER
252 twai_sem(ID semid, TMO tmout)
253 {
254     SEMCB   *semcb;
255     WINFO_WOBJ winfo;
256     TMEVTB  tmevtb;
257     ER  ercd;
258
259     LOG_TWAI_SEM_ENTER(semid, tmout);
260     CHECK_DISPATCH();
261     CHECK_SEMID(semid);
262     CHECK_TMOUT(tmout);
263     semcb = get_semcb(semid);
264
265     t_lock_cpu();
266     if (semcb->semcnt >= 1) {
267         semcb->semcnt -= 1;
268         ercd = E_OK;
269     }
270     else if (tmout == TMO_POL) {
271         ercd = E_TMOUT;
272     }
273     else {
274         wobj_make_wait_tmout((WOBJCB *) semcb, &winfo, &tmevtb, tmout);
275         dispatch();
276         ercd = winfo.winfo.wercd;
277     }
278     t_unlock_cpu();
279
280     exit:
281     LOG_TWAI_SEM_LEAVE(ercd);
282     return(ercd);
283 }
284
285 #endif /* __twai_sem */