source: asp_wo_cfg/trunk/kernel/semaphore.c

Last change on this file was 49, checked in by ertl-hiro, 12 years ago

asp_wo_kernelをコミット。

  • Property svn:keywords set to Id
File size: 9.4 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
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 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * @(#) $Id: semaphore.c 49 2012-09-06 04:41:53Z ertl-hiro $
41 */
42
43/*
44 * セマフォ機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51#include "semaphore.h"
52
53/*
54 * トレースログマクロのデフォルト定義
55 */
56#ifndef LOG_CRE_SEM_ENTER
57#define LOG_CRE_SEM_ENTER(semid, pk_csem)
58#endif /* LOG_CRE_SEM_ENTER */
59
60#ifndef LOG_CRE_SEM_LEAVE
61#define LOG_CRE_SEM_LEAVE(ercd)
62#endif /* LOG_CRE_SEM_LEAVE */
63
64#ifndef LOG_SIG_SEM_ENTER
65#define LOG_SIG_SEM_ENTER(semid)
66#endif /* LOG_SIG_SEM_ENTER */
67
68#ifndef LOG_SIG_SEM_LEAVE
69#define LOG_SIG_SEM_LEAVE(ercd)
70#endif /* LOG_SIG_SEM_LEAVE */
71
72#ifndef LOG_ISIG_SEM_ENTER
73#define LOG_ISIG_SEM_ENTER(semid)
74#endif /* LOG_ISIG_SEM_ENTER */
75
76#ifndef LOG_ISIG_SEM_LEAVE
77#define LOG_ISIG_SEM_LEAVE(ercd)
78#endif /* LOG_ISIG_SEM_LEAVE */
79
80#ifndef LOG_WAI_SEM_ENTER
81#define LOG_WAI_SEM_ENTER(semid)
82#endif /* LOG_WAI_SEM_ENTER */
83
84#ifndef LOG_WAI_SEM_LEAVE
85#define LOG_WAI_SEM_LEAVE(ercd)
86#endif /* LOG_WAI_SEM_LEAVE */
87
88#ifndef LOG_POL_SEM_ENTER
89#define LOG_POL_SEM_ENTER(semid)
90#endif /* LOG_POL_SEM_ENTER */
91
92#ifndef LOG_POL_SEM_LEAVE
93#define LOG_POL_SEM_LEAVE(ercd)
94#endif /* LOG_POL_SEM_LEAVE */
95
96#ifndef LOG_TWAI_SEM_ENTER
97#define LOG_TWAI_SEM_ENTER(semid, tmout)
98#endif /* LOG_TWAI_SEM_ENTER */
99
100#ifndef LOG_TWAI_SEM_LEAVE
101#define LOG_TWAI_SEM_LEAVE(ercd)
102#endif /* LOG_TWAI_SEM_LEAVE */
103
104#ifndef LOG_INI_SEM_ENTER
105#define LOG_INI_SEM_ENTER(semid)
106#endif /* LOG_INI_SEM_ENTER */
107
108#ifndef LOG_INI_SEM_LEAVE
109#define LOG_INI_SEM_LEAVE(ercd)
110#endif /* LOG_INI_SEM_LEAVE */
111
112#ifndef LOG_REF_SEM_ENTER
113#define LOG_REF_SEM_ENTER(semid, pk_rsem)
114#endif /* LOG_REF_SEM_ENTER */
115
116#ifndef LOG_REF_SEM_LEAVE
117#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
118#endif /* LOG_REF_SEM_LEAVE */
119
120/*
121 * セマフォの数
122 */
123#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
124
125/*
126 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
127 */
128#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
129#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
130
131/*
132 * セマフォ機能の初期化
133 */
134#ifdef TOPPERS_semini
135
136void
137initialize_semaphore(void)
138{
139 uint_t i;
140 SEMCB *p_semcb;
141 SEMINIB *p_seminib;
142
143 for (i = 0; i < tnum_sem; i++) {
144 p_semcb = &(semcb_table[i]);
145 p_seminib = &(seminib_table[i]);
146 p_seminib->sematr = TA_NOEXS;
147 p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
148 }
149}
150
151#endif /* TOPPERS_semini */
152
153/*
154 * セマフォの生成
155 */
156#ifdef TOPPERS_cre_sem
157
158ER
159cre_sem(ID semid, const T_CSEM *pk_csem)
160{
161 SEMCB *p_semcb;
162 SEMINIB *p_seminib;
163 ER ercd;
164
165 LOG_CRE_SEM_ENTER(semid, pk_csem);
166 CHECK_INIRTN();
167 CHECK_SEMID(semid);
168 CHECK_RSATR(pk_csem->sematr, TA_TPRI);
169 CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
170 CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
171 p_semcb = get_semcb(semid);
172
173 if (p_semcb->p_seminib->sematr != TA_NOEXS) {
174 ercd = E_OBJ;
175 }
176 else {
177 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
178 p_seminib->sematr = pk_csem->sematr;
179 p_seminib->isemcnt = pk_csem->isemcnt;
180 p_seminib->maxsem = pk_csem->maxsem;
181
182 queue_initialize(&(p_semcb->wait_queue));
183 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
184 ercd = E_OK;
185 }
186
187 error_exit:
188 LOG_CRE_SEM_LEAVE(ercd);
189 return(ercd);
190}
191
192#endif /* TOPPERS_cre_sem */
193
194/*
195 * セマフォ資源の返却
196 */
197#ifdef TOPPERS_sig_sem
198
199ER
200sig_sem(ID semid)
201{
202 SEMCB *p_semcb;
203 TCB *p_tcb;
204 ER ercd;
205
206 LOG_SIG_SEM_ENTER(semid);
207 CHECK_TSKCTX_UNL();
208 CHECK_SEMID(semid);
209 p_semcb = get_semcb(semid);
210 CHECK_NOEXS(p_semcb->p_seminib->sematr);
211
212 t_lock_cpu();
213 if (!queue_empty(&(p_semcb->wait_queue))) {
214 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
215 if (wait_complete(p_tcb)) {
216 dispatch();
217 }
218 ercd = E_OK;
219 }
220 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
221 p_semcb->semcnt += 1;
222 ercd = E_OK;
223 }
224 else {
225 ercd = E_QOVR;
226 }
227 t_unlock_cpu();
228
229 error_exit:
230 LOG_SIG_SEM_LEAVE(ercd);
231 return(ercd);
232}
233
234#endif /* TOPPERS_sig_sem */
235
236/*
237 * セマフォ資源の返却(非タスクコンテキスト用)
238 */
239#ifdef TOPPERS_isig_sem
240
241ER
242isig_sem(ID semid)
243{
244 SEMCB *p_semcb;
245 TCB *p_tcb;
246 ER ercd;
247
248 LOG_ISIG_SEM_ENTER(semid);
249 CHECK_INTCTX_UNL();
250 CHECK_SEMID(semid);
251 p_semcb = get_semcb(semid);
252 CHECK_NOEXS(p_semcb->p_seminib->sematr);
253
254 i_lock_cpu();
255 if (!queue_empty(&(p_semcb->wait_queue))) {
256 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
257 if (wait_complete(p_tcb)) {
258 reqflg = true;
259 }
260 ercd = E_OK;
261 }
262 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
263 p_semcb->semcnt += 1;
264 ercd = E_OK;
265 }
266 else {
267 ercd = E_QOVR;
268 }
269 i_unlock_cpu();
270
271 error_exit:
272 LOG_ISIG_SEM_LEAVE(ercd);
273 return(ercd);
274}
275
276#endif /* TOPPERS_isig_sem */
277
278/*
279 * セマフォ資源の獲得
280 */
281#ifdef TOPPERS_wai_sem
282
283ER
284wai_sem(ID semid)
285{
286 SEMCB *p_semcb;
287 WINFO_SEM winfo_sem;
288 ER ercd;
289
290 LOG_WAI_SEM_ENTER(semid);
291 CHECK_DISPATCH();
292 CHECK_SEMID(semid);
293 p_semcb = get_semcb(semid);
294 CHECK_NOEXS(p_semcb->p_seminib->sematr);
295
296 t_lock_cpu();
297 if (p_semcb->semcnt >= 1) {
298 p_semcb->semcnt -= 1;
299 ercd = E_OK;
300 }
301 else {
302 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
303 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
304 dispatch();
305 ercd = winfo_sem.winfo.wercd;
306 }
307 t_unlock_cpu();
308
309 error_exit:
310 LOG_WAI_SEM_LEAVE(ercd);
311 return(ercd);
312}
313
314#endif /* TOPPERS_wai_sem */
315
316/*
317 * セマフォ資源の獲得(ポーリング)
318 */
319#ifdef TOPPERS_pol_sem
320
321ER
322pol_sem(ID semid)
323{
324 SEMCB *p_semcb;
325 ER ercd;
326
327 LOG_POL_SEM_ENTER(semid);
328 CHECK_TSKCTX_UNL();
329 CHECK_SEMID(semid);
330 p_semcb = get_semcb(semid);
331 CHECK_NOEXS(p_semcb->p_seminib->sematr);
332
333 t_lock_cpu();
334 if (p_semcb->semcnt >= 1) {
335 p_semcb->semcnt -= 1;
336 ercd = E_OK;
337 }
338 else {
339 ercd = E_TMOUT;
340 }
341 t_unlock_cpu();
342
343 error_exit:
344 LOG_POL_SEM_LEAVE(ercd);
345 return(ercd);
346}
347
348#endif /* TOPPERS_pol_sem */
349
350/*
351 * セマフォ資源の獲得(タイムアウトあり)
352 */
353#ifdef TOPPERS_twai_sem
354
355ER
356twai_sem(ID semid, TMO tmout)
357{
358 SEMCB *p_semcb;
359 WINFO_SEM winfo_sem;
360 TMEVTB tmevtb;
361 ER ercd;
362
363 LOG_TWAI_SEM_ENTER(semid, tmout);
364 CHECK_DISPATCH();
365 CHECK_SEMID(semid);
366 CHECK_TMOUT(tmout);
367 p_semcb = get_semcb(semid);
368 CHECK_NOEXS(p_semcb->p_seminib->sematr);
369
370 t_lock_cpu();
371 if (p_semcb->semcnt >= 1) {
372 p_semcb->semcnt -= 1;
373 ercd = E_OK;
374 }
375 else if (tmout == TMO_POL) {
376 ercd = E_TMOUT;
377 }
378 else {
379 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
380 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
381 &tmevtb, tmout);
382 dispatch();
383 ercd = winfo_sem.winfo.wercd;
384 }
385 t_unlock_cpu();
386
387 error_exit:
388 LOG_TWAI_SEM_LEAVE(ercd);
389 return(ercd);
390}
391
392#endif /* TOPPERS_twai_sem */
393
394/*
395 * セマフォの再初期化
396 */
397#ifdef TOPPERS_ini_sem
398
399ER
400ini_sem(ID semid)
401{
402 SEMCB *p_semcb;
403 bool_t dspreq;
404 ER ercd;
405
406 LOG_INI_SEM_ENTER(semid);
407 CHECK_TSKCTX_UNL();
408 CHECK_SEMID(semid);
409 p_semcb = get_semcb(semid);
410 CHECK_NOEXS(p_semcb->p_seminib->sematr);
411
412 t_lock_cpu();
413 dspreq = init_wait_queue(&(p_semcb->wait_queue));
414 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
415 if (dspreq) {
416 dispatch();
417 }
418 ercd = E_OK;
419 t_unlock_cpu();
420
421 error_exit:
422 LOG_INI_SEM_LEAVE(ercd);
423 return(ercd);
424}
425
426#endif /* TOPPERS_ini_sem */
427
428/*
429 * セマフォの状態参照
430 */
431#ifdef TOPPERS_ref_sem
432
433ER
434ref_sem(ID semid, T_RSEM *pk_rsem)
435{
436 SEMCB *p_semcb;
437 ER ercd;
438
439 LOG_REF_SEM_ENTER(semid, pk_rsem);
440 CHECK_TSKCTX_UNL();
441 CHECK_SEMID(semid);
442 p_semcb = get_semcb(semid);
443 CHECK_NOEXS(p_semcb->p_seminib->sematr);
444
445 t_lock_cpu();
446 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
447 pk_rsem->semcnt = p_semcb->semcnt;
448 ercd = E_OK;
449 t_unlock_cpu();
450
451 error_exit:
452 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
453 return(ercd);
454}
455
456#endif /* TOPPERS_ref_sem */
Note: See TracBrowser for help on using the repository browser.