source: rtos_arduino/trunk/asp_1.9.2/kernel/semaphore.c@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 9.0 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-2011 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * @(#) $Id: semaphore.c 2133 2011-06-26 03:14:51Z ertl-hiro $
56 */
57
58/*
59 * セマフォ機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "task.h"
65#include "wait.h"
66#include "semaphore.h"
67
68/*
69 * トレースログマクロのデフォルト定義
70 */
71#ifndef LOG_SIG_SEM_ENTER
72#define LOG_SIG_SEM_ENTER(semid)
73#endif /* LOG_SIG_SEM_ENTER */
74
75#ifndef LOG_SIG_SEM_LEAVE
76#define LOG_SIG_SEM_LEAVE(ercd)
77#endif /* LOG_SIG_SEM_LEAVE */
78
79#ifndef LOG_ISIG_SEM_ENTER
80#define LOG_ISIG_SEM_ENTER(semid)
81#endif /* LOG_ISIG_SEM_ENTER */
82
83#ifndef LOG_ISIG_SEM_LEAVE
84#define LOG_ISIG_SEM_LEAVE(ercd)
85#endif /* LOG_ISIG_SEM_LEAVE */
86
87#ifndef LOG_WAI_SEM_ENTER
88#define LOG_WAI_SEM_ENTER(semid)
89#endif /* LOG_WAI_SEM_ENTER */
90
91#ifndef LOG_WAI_SEM_LEAVE
92#define LOG_WAI_SEM_LEAVE(ercd)
93#endif /* LOG_WAI_SEM_LEAVE */
94
95#ifndef LOG_POL_SEM_ENTER
96#define LOG_POL_SEM_ENTER(semid)
97#endif /* LOG_POL_SEM_ENTER */
98
99#ifndef LOG_POL_SEM_LEAVE
100#define LOG_POL_SEM_LEAVE(ercd)
101#endif /* LOG_POL_SEM_LEAVE */
102
103#ifndef LOG_TWAI_SEM_ENTER
104#define LOG_TWAI_SEM_ENTER(semid, tmout)
105#endif /* LOG_TWAI_SEM_ENTER */
106
107#ifndef LOG_TWAI_SEM_LEAVE
108#define LOG_TWAI_SEM_LEAVE(ercd)
109#endif /* LOG_TWAI_SEM_LEAVE */
110
111#ifndef LOG_INI_SEM_ENTER
112#define LOG_INI_SEM_ENTER(semid)
113#endif /* LOG_INI_SEM_ENTER */
114
115#ifndef LOG_INI_SEM_LEAVE
116#define LOG_INI_SEM_LEAVE(ercd)
117#endif /* LOG_INI_SEM_LEAVE */
118
119#ifndef LOG_REF_SEM_ENTER
120#define LOG_REF_SEM_ENTER(semid, pk_rsem)
121#endif /* LOG_REF_SEM_ENTER */
122
123#ifndef LOG_REF_SEM_LEAVE
124#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
125#endif /* LOG_REF_SEM_LEAVE */
126
127/*
128 * セマフォの数
129 */
130#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
131
132/*
133 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
134 */
135#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
136#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
137
138/*
139 * セマフォ機能の初期化
140 */
141#ifdef TOPPERS_semini
142
143void
144initialize_semaphore(void)
145{
146 uint_t i;
147 SEMCB *p_semcb;
148
149 for (i = 0; i < tnum_sem; i++) {
150 p_semcb = &(semcb_table[i]);
151 queue_initialize(&(p_semcb->wait_queue));
152 p_semcb->p_seminib = &(seminib_table[i]);
153 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
154 }
155}
156
157#endif /* TOPPERS_semini */
158
159/*
160 * セマフォ資源の返却
161 */
162#ifdef TOPPERS_sig_sem
163
164ER
165sig_sem(ID semid)
166{
167 SEMCB *p_semcb;
168 TCB *p_tcb;
169 ER ercd;
170
171 LOG_SIG_SEM_ENTER(semid);
172 CHECK_TSKCTX_UNL();
173 CHECK_SEMID(semid);
174 p_semcb = get_semcb(semid);
175
176 t_lock_cpu();
177 if (!queue_empty(&(p_semcb->wait_queue))) {
178 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
179 if (wait_complete(p_tcb)) {
180 dispatch();
181 }
182 ercd = E_OK;
183 }
184 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
185 p_semcb->semcnt += 1;
186 ercd = E_OK;
187 }
188 else {
189 ercd = E_QOVR;
190 }
191 t_unlock_cpu();
192
193 error_exit:
194 LOG_SIG_SEM_LEAVE(ercd);
195 return(ercd);
196}
197
198#endif /* TOPPERS_sig_sem */
199
200/*
201 * セマフォ資源の返却(非タスクコンテキスト用)
202 */
203#ifdef TOPPERS_isig_sem
204
205ER
206isig_sem(ID semid)
207{
208 SEMCB *p_semcb;
209 TCB *p_tcb;
210 ER ercd;
211
212 LOG_ISIG_SEM_ENTER(semid);
213 CHECK_INTCTX_UNL();
214 CHECK_SEMID(semid);
215 p_semcb = get_semcb(semid);
216
217 i_lock_cpu();
218 if (!queue_empty(&(p_semcb->wait_queue))) {
219 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
220 if (wait_complete(p_tcb)) {
221 reqflg = true;
222 }
223 ercd = E_OK;
224 }
225 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
226 p_semcb->semcnt += 1;
227 ercd = E_OK;
228 }
229 else {
230 ercd = E_QOVR;
231 }
232 i_unlock_cpu();
233
234 error_exit:
235 LOG_ISIG_SEM_LEAVE(ercd);
236 return(ercd);
237}
238
239#endif /* TOPPERS_isig_sem */
240
241/*
242 * セマフォ資源の獲得
243 */
244#ifdef TOPPERS_wai_sem
245
246ER
247wai_sem(ID semid)
248{
249 SEMCB *p_semcb;
250 WINFO_SEM winfo_sem;
251 ER ercd;
252
253 LOG_WAI_SEM_ENTER(semid);
254 CHECK_DISPATCH();
255 CHECK_SEMID(semid);
256 p_semcb = get_semcb(semid);
257
258 t_lock_cpu();
259 if (p_semcb->semcnt >= 1) {
260 p_semcb->semcnt -= 1;
261 ercd = E_OK;
262 }
263 else {
264 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
265 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
266 dispatch();
267 ercd = winfo_sem.winfo.wercd;
268 }
269 t_unlock_cpu();
270
271 error_exit:
272 LOG_WAI_SEM_LEAVE(ercd);
273 return(ercd);
274}
275
276#endif /* TOPPERS_wai_sem */
277
278/*
279 * セマフォ資源の獲得(ポーリング)
280 */
281#ifdef TOPPERS_pol_sem
282
283ER
284pol_sem(ID semid)
285{
286 SEMCB *p_semcb;
287 ER ercd;
288
289 LOG_POL_SEM_ENTER(semid);
290 CHECK_TSKCTX_UNL();
291 CHECK_SEMID(semid);
292 p_semcb = get_semcb(semid);
293
294 t_lock_cpu();
295 if (p_semcb->semcnt >= 1) {
296 p_semcb->semcnt -= 1;
297 ercd = E_OK;
298 }
299 else {
300 ercd = E_TMOUT;
301 }
302 t_unlock_cpu();
303
304 error_exit:
305 LOG_POL_SEM_LEAVE(ercd);
306 return(ercd);
307}
308
309#endif /* TOPPERS_pol_sem */
310
311/*
312 * セマフォ資源の獲得(タイムアウトあり)
313 */
314#ifdef TOPPERS_twai_sem
315
316ER
317twai_sem(ID semid, TMO tmout)
318{
319 SEMCB *p_semcb;
320 WINFO_SEM winfo_sem;
321 TMEVTB tmevtb;
322 ER ercd;
323
324 LOG_TWAI_SEM_ENTER(semid, tmout);
325 CHECK_DISPATCH();
326 CHECK_SEMID(semid);
327 CHECK_TMOUT(tmout);
328 p_semcb = get_semcb(semid);
329
330 t_lock_cpu();
331 if (p_semcb->semcnt >= 1) {
332 p_semcb->semcnt -= 1;
333 ercd = E_OK;
334 }
335 else if (tmout == TMO_POL) {
336 ercd = E_TMOUT;
337 }
338 else {
339 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
340 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
341 &tmevtb, tmout);
342 dispatch();
343 ercd = winfo_sem.winfo.wercd;
344 }
345 t_unlock_cpu();
346
347 error_exit:
348 LOG_TWAI_SEM_LEAVE(ercd);
349 return(ercd);
350}
351
352#endif /* TOPPERS_twai_sem */
353
354/*
355 * セマフォの再初期化
356 */
357#ifdef TOPPERS_ini_sem
358
359ER
360ini_sem(ID semid)
361{
362 SEMCB *p_semcb;
363 bool_t dspreq;
364 ER ercd;
365
366 LOG_INI_SEM_ENTER(semid);
367 CHECK_TSKCTX_UNL();
368 CHECK_SEMID(semid);
369 p_semcb = get_semcb(semid);
370
371 t_lock_cpu();
372 dspreq = init_wait_queue(&(p_semcb->wait_queue));
373 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
374 if (dspreq) {
375 dispatch();
376 }
377 ercd = E_OK;
378 t_unlock_cpu();
379
380 error_exit:
381 LOG_INI_SEM_LEAVE(ercd);
382 return(ercd);
383}
384
385#endif /* TOPPERS_ini_sem */
386
387/*
388 * セマフォの状æ…
389‹å‚ç…
390§
391 */
392#ifdef TOPPERS_ref_sem
393
394ER
395ref_sem(ID semid, T_RSEM *pk_rsem)
396{
397 SEMCB *p_semcb;
398 ER ercd;
399
400 LOG_REF_SEM_ENTER(semid, pk_rsem);
401 CHECK_TSKCTX_UNL();
402 CHECK_SEMID(semid);
403 p_semcb = get_semcb(semid);
404
405 t_lock_cpu();
406 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
407 pk_rsem->semcnt = p_semcb->semcnt;
408 ercd = E_OK;
409 t_unlock_cpu();
410
411 error_exit:
412 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
413 return(ercd);
414}
415
416#endif /* TOPPERS_ref_sem */
Note: See TracBrowser for help on using the repository browser.