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-2010 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 1966 2010-11-20 07:23:56Z ertl-hiro $
47 #include "kernel_impl.h"
51 #include "semaphore.h"
56 #ifndef LOG_ACRE_SEM_ENTER
57 #define LOG_ACRE_SEM_ENTER(pk_csem)
58 #endif /* LOG_ACRE_SEM_ENTER */
60 #ifndef LOG_ACRE_SEM_LEAVE
61 #define LOG_ACRE_SEM_LEAVE(ercd)
62 #endif /* LOG_ACRE_SEM_LEAVE */
64 #ifndef LOG_DEL_SEM_ENTER
65 #define LOG_DEL_SEM_ENTER(semid)
66 #endif /* LOG_DEL_SEM_ENTER */
68 #ifndef LOG_DEL_SEM_LEAVE
69 #define LOG_DEL_SEM_LEAVE(ercd)
70 #endif /* LOG_DEL_SEM_LEAVE */
72 #ifndef LOG_SIG_SEM_ENTER
73 #define LOG_SIG_SEM_ENTER(semid)
74 #endif /* LOG_SIG_SEM_ENTER */
76 #ifndef LOG_SIG_SEM_LEAVE
77 #define LOG_SIG_SEM_LEAVE(ercd)
78 #endif /* LOG_SIG_SEM_LEAVE */
80 #ifndef LOG_ISIG_SEM_ENTER
81 #define LOG_ISIG_SEM_ENTER(semid)
82 #endif /* LOG_ISIG_SEM_ENTER */
84 #ifndef LOG_ISIG_SEM_LEAVE
85 #define LOG_ISIG_SEM_LEAVE(ercd)
86 #endif /* LOG_ISIG_SEM_LEAVE */
88 #ifndef LOG_WAI_SEM_ENTER
89 #define LOG_WAI_SEM_ENTER(semid)
90 #endif /* LOG_WAI_SEM_ENTER */
92 #ifndef LOG_WAI_SEM_LEAVE
93 #define LOG_WAI_SEM_LEAVE(ercd)
94 #endif /* LOG_WAI_SEM_LEAVE */
96 #ifndef LOG_POL_SEM_ENTER
97 #define LOG_POL_SEM_ENTER(semid)
98 #endif /* LOG_POL_SEM_ENTER */
100 #ifndef LOG_POL_SEM_LEAVE
101 #define LOG_POL_SEM_LEAVE(ercd)
102 #endif /* LOG_POL_SEM_LEAVE */
104 #ifndef LOG_TWAI_SEM_ENTER
105 #define LOG_TWAI_SEM_ENTER(semid, tmout)
106 #endif /* LOG_TWAI_SEM_ENTER */
108 #ifndef LOG_TWAI_SEM_LEAVE
109 #define LOG_TWAI_SEM_LEAVE(ercd)
110 #endif /* LOG_TWAI_SEM_LEAVE */
112 #ifndef LOG_INI_SEM_ENTER
113 #define LOG_INI_SEM_ENTER(semid)
114 #endif /* LOG_INI_SEM_ENTER */
116 #ifndef LOG_INI_SEM_LEAVE
117 #define LOG_INI_SEM_LEAVE(ercd)
118 #endif /* LOG_INI_SEM_LEAVE */
120 #ifndef LOG_REF_SEM_ENTER
121 #define LOG_REF_SEM_ENTER(semid, pk_rsem)
122 #endif /* LOG_REF_SEM_ENTER */
124 #ifndef LOG_REF_SEM_LEAVE
125 #define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
126 #endif /* LOG_REF_SEM_LEAVE */
131 #define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
132 #define tnum_ssem ((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
135 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
137 #define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
138 #define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
140 #ifdef TOPPERS_semini
143 * 使用していないセマフォ管理ブロックのリスト
151 initialize_semaphore(void)
157 for (p_semcb = semcb_table, i = 0; i < tnum_ssem; p_semcb++, i++) {
158 queue_initialize(&(p_semcb->wait_queue));
159 p_semcb->p_seminib = &(seminib_table[i]);
160 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
162 queue_initialize(&free_semcb);
163 for (j = 0; i < tnum_sem; p_semcb++, i++, j++) {
164 p_seminib = &(aseminib_table[j]);
165 p_seminib->sematr = TA_NOEXS;
166 p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
167 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
171 #endif /* TOPPERS_semini */
176 #ifdef TOPPERS_acre_sem
179 acre_sem(const T_CSEM *pk_csem)
185 LOG_ACRE_SEM_ENTER(pk_csem);
187 CHECK_RSATR(pk_csem->sematr, TA_TPRI);
188 CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
189 CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
192 if (queue_empty(&free_semcb)) {
196 p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
197 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
198 p_seminib->sematr = pk_csem->sematr;
199 p_seminib->isemcnt = pk_csem->isemcnt;
200 p_seminib->maxsem = pk_csem->maxsem;
202 queue_initialize(&(p_semcb->wait_queue));
203 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
204 ercd = SEMID(p_semcb);
209 LOG_ACRE_SEM_LEAVE(ercd);
213 #endif /* TOPPERS_acre_sem */
218 #ifdef TOPPERS_del_sem
228 LOG_DEL_SEM_ENTER(semid);
231 p_semcb = get_semcb(semid);
234 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
237 else if (SEMID(p_semcb) > tmax_ssemid) {
238 dspreq = init_wait_queue(&(p_semcb->wait_queue));
239 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
240 p_seminib->sematr = TA_NOEXS;
241 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
253 LOG_DEL_SEM_LEAVE(ercd);
257 #endif /* TOPPERS_del_sem */
262 #ifdef TOPPERS_sig_sem
271 LOG_SIG_SEM_ENTER(semid);
274 p_semcb = get_semcb(semid);
277 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
280 else if (!queue_empty(&(p_semcb->wait_queue))) {
281 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
282 if (wait_complete(p_tcb)) {
287 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
288 p_semcb->semcnt += 1;
297 LOG_SIG_SEM_LEAVE(ercd);
301 #endif /* TOPPERS_sig_sem */
304 * セマフォ資源の返却(非タスクコンテキスト用)
306 #ifdef TOPPERS_isig_sem
315 LOG_ISIG_SEM_ENTER(semid);
318 p_semcb = get_semcb(semid);
321 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
324 else if (!queue_empty(&(p_semcb->wait_queue))) {
325 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
326 if (wait_complete(p_tcb)) {
331 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
332 p_semcb->semcnt += 1;
341 LOG_ISIG_SEM_LEAVE(ercd);
345 #endif /* TOPPERS_isig_sem */
350 #ifdef TOPPERS_wai_sem
359 LOG_WAI_SEM_ENTER(semid);
362 p_semcb = get_semcb(semid);
365 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
368 else if (p_semcb->semcnt >= 1) {
369 p_semcb->semcnt -= 1;
373 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
374 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
376 ercd = winfo_sem.winfo.wercd;
381 LOG_WAI_SEM_LEAVE(ercd);
385 #endif /* TOPPERS_wai_sem */
390 #ifdef TOPPERS_pol_sem
398 LOG_POL_SEM_ENTER(semid);
401 p_semcb = get_semcb(semid);
404 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
407 else if (p_semcb->semcnt >= 1) {
408 p_semcb->semcnt -= 1;
417 LOG_POL_SEM_LEAVE(ercd);
421 #endif /* TOPPERS_pol_sem */
424 * セマフォ資源の獲得(タイムアウトあり)
426 #ifdef TOPPERS_twai_sem
429 twai_sem(ID semid, TMO tmout)
436 LOG_TWAI_SEM_ENTER(semid, tmout);
440 p_semcb = get_semcb(semid);
443 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
446 else if (p_semcb->semcnt >= 1) {
447 p_semcb->semcnt -= 1;
450 else if (tmout == TMO_POL) {
454 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
455 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
458 ercd = winfo_sem.winfo.wercd;
463 LOG_TWAI_SEM_LEAVE(ercd);
467 #endif /* TOPPERS_twai_sem */
472 #ifdef TOPPERS_ini_sem
481 LOG_INI_SEM_ENTER(semid);
484 p_semcb = get_semcb(semid);
487 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
491 dspreq = init_wait_queue(&(p_semcb->wait_queue));
492 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
501 LOG_INI_SEM_LEAVE(ercd);
505 #endif /* TOPPERS_ini_sem */
510 #ifdef TOPPERS_ref_sem
513 ref_sem(ID semid, T_RSEM *pk_rsem)
518 LOG_REF_SEM_ENTER(semid, pk_rsem);
521 p_semcb = get_semcb(semid);
524 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
528 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
529 pk_rsem->semcnt = p_semcb->semcnt;
535 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
539 #endif /* TOPPERS_ref_sem */