source: asp3_wo_tecs/trunk/extension/dcre/kernel/semaphore.c@ 302

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

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

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