3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * @(#) $Id: semaphore.c 748 2008-03-07 17:18:06Z hiro $
47 #include "kernel_impl.h"
51 #include "semaphore.h"
56 #ifndef LOG_SIG_SEM_ENTER
57 #define LOG_SIG_SEM_ENTER(semid)
58 #endif /* LOG_SIG_SEM_ENTER */
60 #ifndef LOG_SIG_SEM_LEAVE
61 #define LOG_SIG_SEM_LEAVE(ercd)
62 #endif /* LOG_SIG_SEM_LEAVE */
64 #ifndef LOG_ISIG_SEM_ENTER
65 #define LOG_ISIG_SEM_ENTER(semid)
66 #endif /* LOG_ISIG_SEM_ENTER */
68 #ifndef LOG_ISIG_SEM_LEAVE
69 #define LOG_ISIG_SEM_LEAVE(ercd)
70 #endif /* LOG_ISIG_SEM_LEAVE */
72 #ifndef LOG_WAI_SEM_ENTER
73 #define LOG_WAI_SEM_ENTER(semid)
74 #endif /* LOG_WAI_SEM_ENTER */
76 #ifndef LOG_WAI_SEM_LEAVE
77 #define LOG_WAI_SEM_LEAVE(ercd)
78 #endif /* LOG_WAI_SEM_LEAVE */
80 #ifndef LOG_POL_SEM_ENTER
81 #define LOG_POL_SEM_ENTER(semid)
82 #endif /* LOG_POL_SEM_ENTER */
84 #ifndef LOG_POL_SEM_LEAVE
85 #define LOG_POL_SEM_LEAVE(ercd)
86 #endif /* LOG_POL_SEM_LEAVE */
88 #ifndef LOG_TWAI_SEM_ENTER
89 #define LOG_TWAI_SEM_ENTER(semid, tmout)
90 #endif /* LOG_TWAI_SEM_ENTER */
92 #ifndef LOG_TWAI_SEM_LEAVE
93 #define LOG_TWAI_SEM_LEAVE(ercd)
94 #endif /* LOG_TWAI_SEM_LEAVE */
96 #ifndef LOG_INI_SEM_ENTER
97 #define LOG_INI_SEM_ENTER(semid)
98 #endif /* LOG_INI_SEM_ENTER */
100 #ifndef LOG_INI_SEM_LEAVE
101 #define LOG_INI_SEM_LEAVE(ercd)
102 #endif /* LOG_INI_SEM_LEAVE */
104 #ifndef LOG_REF_SEM_ENTER
105 #define LOG_REF_SEM_ENTER(semid, pk_rsem)
106 #endif /* LOG_REF_SEM_ENTER */
108 #ifndef LOG_REF_SEM_LEAVE
109 #define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
110 #endif /* LOG_REF_SEM_LEAVE */
115 #define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
118 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
120 #define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
121 #define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
126 #ifdef TOPPERS_semini
129 initialize_semaphore(void)
134 for (p_semcb = semcb_table, i = 0; i < tnum_sem; p_semcb++, i++) {
135 queue_initialize(&(p_semcb->wait_queue));
136 p_semcb->p_seminib = &(seminib_table[i]);
137 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
141 #endif /* TOPPERS_semini */
146 #ifdef TOPPERS_sig_sem
155 LOG_SIG_SEM_ENTER(semid);
158 p_semcb = get_semcb(semid);
161 if (!queue_empty(&(p_semcb->wait_queue))) {
162 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
163 if (wait_complete(p_tcb)) {
168 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
169 p_semcb->semcnt += 1;
178 LOG_SIG_SEM_LEAVE(ercd);
182 #endif /* TOPPERS_sig_sem */
185 * セマフォ資源の返却(非タスクコンテキスト用)
187 #ifdef TOPPERS_isig_sem
196 LOG_ISIG_SEM_ENTER(semid);
199 p_semcb = get_semcb(semid);
202 if (!queue_empty(&(p_semcb->wait_queue))) {
203 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
204 if (wait_complete(p_tcb)) {
209 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
210 p_semcb->semcnt += 1;
219 LOG_ISIG_SEM_LEAVE(ercd);
223 #endif /* TOPPERS_isig_sem */
228 #ifdef TOPPERS_wai_sem
237 LOG_WAI_SEM_ENTER(semid);
240 p_semcb = get_semcb(semid);
243 if (p_semcb->semcnt >= 1) {
244 p_semcb->semcnt -= 1;
248 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
249 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
251 ercd = winfo_sem.winfo.wercd;
256 LOG_WAI_SEM_LEAVE(ercd);
260 #endif /* TOPPERS_wai_sem */
265 #ifdef TOPPERS_pol_sem
273 LOG_POL_SEM_ENTER(semid);
276 p_semcb = get_semcb(semid);
279 if (p_semcb->semcnt >= 1) {
280 p_semcb->semcnt -= 1;
289 LOG_POL_SEM_LEAVE(ercd);
293 #endif /* TOPPERS_pol_sem */
296 * セマフォ資源の獲得(タイムアウトあり)
298 #ifdef TOPPERS_twai_sem
301 twai_sem(ID semid, TMO tmout)
308 LOG_TWAI_SEM_ENTER(semid, tmout);
312 p_semcb = get_semcb(semid);
315 if (p_semcb->semcnt >= 1) {
316 p_semcb->semcnt -= 1;
319 else if (tmout == TMO_POL) {
323 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
324 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
327 ercd = winfo_sem.winfo.wercd;
332 LOG_TWAI_SEM_LEAVE(ercd);
336 #endif /* TOPPERS_twai_sem */
341 #ifdef TOPPERS_ini_sem
350 LOG_INI_SEM_ENTER(semid);
353 p_semcb = get_semcb(semid);
356 dspreq = init_wait_queue(&(p_semcb->wait_queue));
357 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
365 LOG_INI_SEM_LEAVE(ercd);
369 #endif /* TOPPERS_ini_sem */
374 #ifdef TOPPERS_ref_sem
377 ref_sem(ID semid, T_RSEM *pk_rsem)
382 LOG_REF_SEM_ENTER(semid, pk_rsem);
385 p_semcb = get_semcb(semid);
388 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
389 pk_rsem->semcnt = p_semcb->semcnt;
394 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
398 #endif /* TOPPERS_ref_sem */