source: rubycfg_asp/trunk/asp_dcre/kernel/semaphore.c@ 313

Last change on this file since 313 was 313, checked in by coas-nagasima, 7 years ago

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.9 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 * 上記著作権者
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 313 2017-07-23 04:50:32Z coas-nagasima $
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_ACRE_SEM_ENTER
72#define LOG_ACRE_SEM_ENTER(pk_csem)
73#endif /* LOG_ACRE_SEM_ENTER */
74
75#ifndef LOG_ACRE_SEM_LEAVE
76#define LOG_ACRE_SEM_LEAVE(ercd)
77#endif /* LOG_ACRE_SEM_LEAVE */
78
79#ifndef LOG_DEL_SEM_ENTER
80#define LOG_DEL_SEM_ENTER(semid)
81#endif /* LOG_DEL_SEM_ENTER */
82
83#ifndef LOG_DEL_SEM_LEAVE
84#define LOG_DEL_SEM_LEAVE(ercd)
85#endif /* LOG_DEL_SEM_LEAVE */
86
87#ifndef LOG_SIG_SEM_ENTER
88#define LOG_SIG_SEM_ENTER(semid)
89#endif /* LOG_SIG_SEM_ENTER */
90
91#ifndef LOG_SIG_SEM_LEAVE
92#define LOG_SIG_SEM_LEAVE(ercd)
93#endif /* LOG_SIG_SEM_LEAVE */
94
95#ifndef LOG_ISIG_SEM_ENTER
96#define LOG_ISIG_SEM_ENTER(semid)
97#endif /* LOG_ISIG_SEM_ENTER */
98
99#ifndef LOG_ISIG_SEM_LEAVE
100#define LOG_ISIG_SEM_LEAVE(ercd)
101#endif /* LOG_ISIG_SEM_LEAVE */
102
103#ifndef LOG_WAI_SEM_ENTER
104#define LOG_WAI_SEM_ENTER(semid)
105#endif /* LOG_WAI_SEM_ENTER */
106
107#ifndef LOG_WAI_SEM_LEAVE
108#define LOG_WAI_SEM_LEAVE(ercd)
109#endif /* LOG_WAI_SEM_LEAVE */
110
111#ifndef LOG_POL_SEM_ENTER
112#define LOG_POL_SEM_ENTER(semid)
113#endif /* LOG_POL_SEM_ENTER */
114
115#ifndef LOG_POL_SEM_LEAVE
116#define LOG_POL_SEM_LEAVE(ercd)
117#endif /* LOG_POL_SEM_LEAVE */
118
119#ifndef LOG_TWAI_SEM_ENTER
120#define LOG_TWAI_SEM_ENTER(semid, tmout)
121#endif /* LOG_TWAI_SEM_ENTER */
122
123#ifndef LOG_TWAI_SEM_LEAVE
124#define LOG_TWAI_SEM_LEAVE(ercd)
125#endif /* LOG_TWAI_SEM_LEAVE */
126
127#ifndef LOG_INI_SEM_ENTER
128#define LOG_INI_SEM_ENTER(semid)
129#endif /* LOG_INI_SEM_ENTER */
130
131#ifndef LOG_INI_SEM_LEAVE
132#define LOG_INI_SEM_LEAVE(ercd)
133#endif /* LOG_INI_SEM_LEAVE */
134
135#ifndef LOG_REF_SEM_ENTER
136#define LOG_REF_SEM_ENTER(semid, pk_rsem)
137#endif /* LOG_REF_SEM_ENTER */
138
139#ifndef LOG_REF_SEM_LEAVE
140#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
141#endif /* LOG_REF_SEM_LEAVE */
142
143/*
144 * セマフォの数
145 */
146#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
147#define tnum_ssem ((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
148
149/*
150 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ
151 */
152#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
153#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
154
155#ifdef TOPPERS_semini
156
157/*
158 * 使用していないセマフォ管理ブロックのリスト
159 */
160QUEUE free_semcb;
161
162/*
163 * セマフォ機能の初期化
164 */
165void
166initialize_semaphore(void)
167{
168 uint_t i, j;
169 SEMCB *p_semcb;
170 SEMINIB *p_seminib;
171
172 for (i = 0; i < tnum_ssem; i++) {
173 p_semcb = &(semcb_table[i]);
174 queue_initialize(&(p_semcb->wait_queue));
175 p_semcb->p_seminib = &(seminib_table[i]);
176 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
177 }
178 queue_initialize(&free_semcb);
179 for (j = 0; i < tnum_sem; i++, j++) {
180 p_semcb = &(semcb_table[i]);
181 p_seminib = &(aseminib_table[j]);
182 p_seminib->sematr = TA_NOEXS;
183 p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
184 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
185 }
186}
187
188#endif /* TOPPERS_semini */
189
190/*
191 * セマフォの生成
192 */
193#ifdef TOPPERS_acre_sem
194
195ER_UINT
196acre_sem(const T_CSEM *pk_csem)
197{
198 SEMCB *p_semcb;
199 SEMINIB *p_seminib;
200 ER ercd;
201
202 LOG_ACRE_SEM_ENTER(pk_csem);
203 CHECK_TSKCTX_UNL();
204 CHECK_RSATR(pk_csem->sematr, TA_TPRI);
205 CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
206 CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
207
208 t_lock_cpu();
209 if (tnum_sem == 0 || queue_empty(&free_semcb)) {
210 ercd = E_NOID;
211 }
212 else {
213 p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
214 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
215 p_seminib->sematr = pk_csem->sematr;
216 p_seminib->isemcnt = pk_csem->isemcnt;
217 p_seminib->maxsem = pk_csem->maxsem;
218
219 queue_initialize(&(p_semcb->wait_queue));
220 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
221 ercd = SEMID(p_semcb);
222 }
223 t_unlock_cpu();
224
225 error_exit:
226 LOG_ACRE_SEM_LEAVE(ercd);
227 return(ercd);
228}
229
230#endif /* TOPPERS_acre_sem */
231
232/*
233 * セマフォの削除
234 */
235#ifdef TOPPERS_del_sem
236
237ER
238del_sem(ID semid)
239{
240 SEMCB *p_semcb;
241 SEMINIB *p_seminib;
242 bool_t dspreq;
243 ER ercd;
244
245 LOG_DEL_SEM_ENTER(semid);
246 CHECK_TSKCTX_UNL();
247 CHECK_SEMID(semid);
248 p_semcb = get_semcb(semid);
249
250 t_lock_cpu();
251 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
252 ercd = E_NOEXS;
253 }
254 else if (SEMID(p_semcb) > tmax_ssemid) {
255 dspreq = init_wait_queue(&(p_semcb->wait_queue));
256 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
257 p_seminib->sematr = TA_NOEXS;
258 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
259 if (dspreq) {
260 dispatch();
261 }
262 ercd = E_OK;
263 }
264 else {
265 ercd = E_OBJ;
266 }
267 t_unlock_cpu();
268
269 error_exit:
270 LOG_DEL_SEM_LEAVE(ercd);
271 return(ercd);
272}
273
274#endif /* TOPPERS_del_sem */
275
276/*
277 * セマフォ資源の返却
278 */
279#ifdef TOPPERS_sig_sem
280
281ER
282sig_sem(ID semid)
283{
284 SEMCB *p_semcb;
285 TCB *p_tcb;
286 ER ercd;
287
288 LOG_SIG_SEM_ENTER(semid);
289 CHECK_TSKCTX_UNL();
290 CHECK_SEMID(semid);
291 p_semcb = get_semcb(semid);
292
293 t_lock_cpu();
294 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
295 ercd = E_NOEXS;
296 }
297 else if (!queue_empty(&(p_semcb->wait_queue))) {
298 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
299 if (wait_complete(p_tcb)) {
300 dispatch();
301 }
302 ercd = E_OK;
303 }
304 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
305 p_semcb->semcnt += 1;
306 ercd = E_OK;
307 }
308 else {
309 ercd = E_QOVR;
310 }
311 t_unlock_cpu();
312
313 error_exit:
314 LOG_SIG_SEM_LEAVE(ercd);
315 return(ercd);
316}
317
318#endif /* TOPPERS_sig_sem */
319
320/*
321 * セマフォ資源の返却(非タスクコンテキスト用)
322 */
323#ifdef TOPPERS_isig_sem
324
325ER
326isig_sem(ID semid)
327{
328 SEMCB *p_semcb;
329 TCB *p_tcb;
330 ER ercd;
331
332 LOG_ISIG_SEM_ENTER(semid);
333 CHECK_INTCTX_UNL();
334 CHECK_SEMID(semid);
335 p_semcb = get_semcb(semid);
336
337 i_lock_cpu();
338 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
339 ercd = E_NOEXS;
340 }
341 else if (!queue_empty(&(p_semcb->wait_queue))) {
342 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
343 if (wait_complete(p_tcb)) {
344 reqflg = true;
345 }
346 ercd = E_OK;
347 }
348 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
349 p_semcb->semcnt += 1;
350 ercd = E_OK;
351 }
352 else {
353 ercd = E_QOVR;
354 }
355 i_unlock_cpu();
356
357 error_exit:
358 LOG_ISIG_SEM_LEAVE(ercd);
359 return(ercd);
360}
361
362#endif /* TOPPERS_isig_sem */
363
364/*
365 * セマフォ資源の獲得
366 */
367#ifdef TOPPERS_wai_sem
368
369ER
370wai_sem(ID semid)
371{
372 SEMCB *p_semcb;
373 WINFO_SEM winfo_sem;
374 ER ercd;
375
376 LOG_WAI_SEM_ENTER(semid);
377 CHECK_DISPATCH();
378 CHECK_SEMID(semid);
379 p_semcb = get_semcb(semid);
380
381 t_lock_cpu();
382 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
383 ercd = E_NOEXS;
384 }
385 else if (p_semcb->semcnt >= 1) {
386 p_semcb->semcnt -= 1;
387 ercd = E_OK;
388 }
389 else {
390 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
391 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
392 dispatch();
393 ercd = winfo_sem.winfo.wercd;
394 }
395 t_unlock_cpu();
396
397 error_exit:
398 LOG_WAI_SEM_LEAVE(ercd);
399 return(ercd);
400}
401
402#endif /* TOPPERS_wai_sem */
403
404/*
405 * セマフォ資源の獲得(ポーリング)
406 */
407#ifdef TOPPERS_pol_sem
408
409ER
410pol_sem(ID semid)
411{
412 SEMCB *p_semcb;
413 ER ercd;
414
415 LOG_POL_SEM_ENTER(semid);
416 CHECK_TSKCTX_UNL();
417 CHECK_SEMID(semid);
418 p_semcb = get_semcb(semid);
419
420 t_lock_cpu();
421 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
422 ercd = E_NOEXS;
423 }
424 else if (p_semcb->semcnt >= 1) {
425 p_semcb->semcnt -= 1;
426 ercd = E_OK;
427 }
428 else {
429 ercd = E_TMOUT;
430 }
431 t_unlock_cpu();
432
433 error_exit:
434 LOG_POL_SEM_LEAVE(ercd);
435 return(ercd);
436}
437
438#endif /* TOPPERS_pol_sem */
439
440/*
441 * セマフォ資源の獲得(タイムアウトあり)
442 */
443#ifdef TOPPERS_twai_sem
444
445ER
446twai_sem(ID semid, TMO tmout)
447{
448 SEMCB *p_semcb;
449 WINFO_SEM winfo_sem;
450 TMEVTB tmevtb;
451 ER ercd;
452
453 LOG_TWAI_SEM_ENTER(semid, tmout);
454 CHECK_DISPATCH();
455 CHECK_SEMID(semid);
456 CHECK_TMOUT(tmout);
457 p_semcb = get_semcb(semid);
458
459 t_lock_cpu();
460 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
461 ercd = E_NOEXS;
462 }
463 else if (p_semcb->semcnt >= 1) {
464 p_semcb->semcnt -= 1;
465 ercd = E_OK;
466 }
467 else if (tmout == TMO_POL) {
468 ercd = E_TMOUT;
469 }
470 else {
471 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
472 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
473 &tmevtb, tmout);
474 dispatch();
475 ercd = winfo_sem.winfo.wercd;
476 }
477 t_unlock_cpu();
478
479 error_exit:
480 LOG_TWAI_SEM_LEAVE(ercd);
481 return(ercd);
482}
483
484#endif /* TOPPERS_twai_sem */
485
486/*
487 * セマフォの再初期化
488 */
489#ifdef TOPPERS_ini_sem
490
491ER
492ini_sem(ID semid)
493{
494 SEMCB *p_semcb;
495 bool_t dspreq;
496 ER ercd;
497
498 LOG_INI_SEM_ENTER(semid);
499 CHECK_TSKCTX_UNL();
500 CHECK_SEMID(semid);
501 p_semcb = get_semcb(semid);
502
503 t_lock_cpu();
504 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
505 ercd = E_NOEXS;
506 }
507 else {
508 dspreq = init_wait_queue(&(p_semcb->wait_queue));
509 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
510 if (dspreq) {
511 dispatch();
512 }
513 ercd = E_OK;
514 }
515 t_unlock_cpu();
516
517 error_exit:
518 LOG_INI_SEM_LEAVE(ercd);
519 return(ercd);
520}
521
522#endif /* TOPPERS_ini_sem */
523
524/*
525 * セマフォの状æ…
526‹å‚ç…
527§
528 */
529#ifdef TOPPERS_ref_sem
530
531ER
532ref_sem(ID semid, T_RSEM *pk_rsem)
533{
534 SEMCB *p_semcb;
535 ER ercd;
536
537 LOG_REF_SEM_ENTER(semid, pk_rsem);
538 CHECK_TSKCTX_UNL();
539 CHECK_SEMID(semid);
540 p_semcb = get_semcb(semid);
541
542 t_lock_cpu();
543 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
544 ercd = E_NOEXS;
545 }
546 else {
547 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
548 pk_rsem->semcnt = p_semcb->semcnt;
549 ercd = E_OK;
550 }
551 t_unlock_cpu();
552
553 error_exit:
554 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
555 return(ercd);
556}
557
558#endif /* TOPPERS_ref_sem */
Note: See TracBrowser for help on using the repository browser.