source: asp_ewarm/asp-1.7.0/extension/dcre/kernel/semaphore.c@ 61

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

ASP for EWARM のコミット.

File size: 11.6 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-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
12 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
13 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
14 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
15 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
16 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
17 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
18 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
19ƒƒ“ƒgi—˜—p
20 * ŽÒƒ}ƒjƒ…
21ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
22 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
23 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
24 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
25 * ‚ƁD
26 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
27ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
28ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
29 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
30 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
31 * •ñ‚·‚邱‚ƁD
32 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
33 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
34 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
35 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
36 * –Ɛӂ·‚邱‚ƁD
37 *
38 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
39 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
40 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
41 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
42 * ‚̐ӔC‚𕉂í‚È‚¢D
43 *
44 * @(#) $Id: semaphore.c 1966 2010-11-20 07:23:56Z ertl-hiro $
45 */
46
47/*
48 * ƒZƒ}ƒtƒH‹@”\
49 */
50
51#include "kernel_impl.h"
52#include "check.h"
53#include "task.h"
54#include "wait.h"
55#include "semaphore.h"
56
57/*
58 * ƒgƒŒ[ƒXƒƒOƒ}ƒNƒ‚̃fƒtƒHƒ‹ƒg’è‹`
59 */
60#ifndef LOG_ACRE_SEM_ENTER
61#define LOG_ACRE_SEM_ENTER(pk_csem)
62#endif /* LOG_ACRE_SEM_ENTER */
63
64#ifndef LOG_ACRE_SEM_LEAVE
65#define LOG_ACRE_SEM_LEAVE(ercd)
66#endif /* LOG_ACRE_SEM_LEAVE */
67
68#ifndef LOG_DEL_SEM_ENTER
69#define LOG_DEL_SEM_ENTER(semid)
70#endif /* LOG_DEL_SEM_ENTER */
71
72#ifndef LOG_DEL_SEM_LEAVE
73#define LOG_DEL_SEM_LEAVE(ercd)
74#endif /* LOG_DEL_SEM_LEAVE */
75
76#ifndef LOG_SIG_SEM_ENTER
77#define LOG_SIG_SEM_ENTER(semid)
78#endif /* LOG_SIG_SEM_ENTER */
79
80#ifndef LOG_SIG_SEM_LEAVE
81#define LOG_SIG_SEM_LEAVE(ercd)
82#endif /* LOG_SIG_SEM_LEAVE */
83
84#ifndef LOG_ISIG_SEM_ENTER
85#define LOG_ISIG_SEM_ENTER(semid)
86#endif /* LOG_ISIG_SEM_ENTER */
87
88#ifndef LOG_ISIG_SEM_LEAVE
89#define LOG_ISIG_SEM_LEAVE(ercd)
90#endif /* LOG_ISIG_SEM_LEAVE */
91
92#ifndef LOG_WAI_SEM_ENTER
93#define LOG_WAI_SEM_ENTER(semid)
94#endif /* LOG_WAI_SEM_ENTER */
95
96#ifndef LOG_WAI_SEM_LEAVE
97#define LOG_WAI_SEM_LEAVE(ercd)
98#endif /* LOG_WAI_SEM_LEAVE */
99
100#ifndef LOG_POL_SEM_ENTER
101#define LOG_POL_SEM_ENTER(semid)
102#endif /* LOG_POL_SEM_ENTER */
103
104#ifndef LOG_POL_SEM_LEAVE
105#define LOG_POL_SEM_LEAVE(ercd)
106#endif /* LOG_POL_SEM_LEAVE */
107
108#ifndef LOG_TWAI_SEM_ENTER
109#define LOG_TWAI_SEM_ENTER(semid, tmout)
110#endif /* LOG_TWAI_SEM_ENTER */
111
112#ifndef LOG_TWAI_SEM_LEAVE
113#define LOG_TWAI_SEM_LEAVE(ercd)
114#endif /* LOG_TWAI_SEM_LEAVE */
115
116#ifndef LOG_INI_SEM_ENTER
117#define LOG_INI_SEM_ENTER(semid)
118#endif /* LOG_INI_SEM_ENTER */
119
120#ifndef LOG_INI_SEM_LEAVE
121#define LOG_INI_SEM_LEAVE(ercd)
122#endif /* LOG_INI_SEM_LEAVE */
123
124#ifndef LOG_REF_SEM_ENTER
125#define LOG_REF_SEM_ENTER(semid, pk_rsem)
126#endif /* LOG_REF_SEM_ENTER */
127
128#ifndef LOG_REF_SEM_LEAVE
129#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
130#endif /* LOG_REF_SEM_LEAVE */
131
132/*
133 * ƒZƒ}ƒtƒH‚̐”
134 */
135#define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1))
136#define tnum_ssem ((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
137
138/*
139 * ƒZƒ}ƒtƒHID‚©‚çƒZƒ}ƒtƒHŠÇ—ƒuƒƒbƒN‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
140 */
141#define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID))
142#define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)]))
143
144#ifdef TOPPERS_semini
145
146/*
147 * Žg—p‚µ‚Ä‚¢‚È‚¢ƒZƒ}ƒtƒHŠÇ—ƒuƒƒbƒN‚̃ŠƒXƒg
148 */
149QUEUE free_semcb;
150
151/*
152 * ƒZƒ}ƒtƒH‹@”\‚̏‰Šú‰»
153 */
154void
155initialize_semaphore(void)
156{
157 uint_t i, j;
158 SEMCB *p_semcb;
159 SEMINIB *p_seminib;
160
161 for (p_semcb = semcb_table, i = 0; i < tnum_ssem; p_semcb++, i++) {
162 queue_initialize(&(p_semcb->wait_queue));
163 p_semcb->p_seminib = &(seminib_table[i]);
164 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
165 }
166 queue_initialize(&free_semcb);
167 for (j = 0; i < tnum_sem; p_semcb++, i++, j++) {
168 p_seminib = &(aseminib_table[j]);
169 p_seminib->sematr = TA_NOEXS;
170 p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
171 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
172 }
173}
174
175#endif /* TOPPERS_semini */
176
177/*
178 * ƒZƒ}ƒtƒH‚̐¶¬
179 */
180#ifdef TOPPERS_acre_sem
181
182ER_UINT
183acre_sem(const T_CSEM *pk_csem)
184{
185 SEMCB *p_semcb;
186 SEMINIB *p_seminib;
187 ER ercd;
188
189 LOG_ACRE_SEM_ENTER(pk_csem);
190 CHECK_TSKCTX_UNL();
191 CHECK_RSATR(pk_csem->sematr, TA_TPRI);
192 CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
193 CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
194
195 t_lock_cpu();
196 if (queue_empty(&free_semcb)) {
197 ercd = E_NOID;
198 }
199 else {
200 p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
201 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
202 p_seminib->sematr = pk_csem->sematr;
203 p_seminib->isemcnt = pk_csem->isemcnt;
204 p_seminib->maxsem = pk_csem->maxsem;
205
206 queue_initialize(&(p_semcb->wait_queue));
207 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
208 ercd = SEMID(p_semcb);
209 }
210 t_unlock_cpu();
211
212 error_exit:
213 LOG_ACRE_SEM_LEAVE(ercd);
214 return(ercd);
215}
216
217#endif /* TOPPERS_acre_sem */
218
219/*
220 * ƒZƒ}ƒtƒH‚̍폜
221 */
222#ifdef TOPPERS_del_sem
223
224ER
225del_sem(ID semid)
226{
227 SEMCB *p_semcb;
228 SEMINIB *p_seminib;
229 bool_t dspreq;
230 ER ercd;
231
232 LOG_DEL_SEM_ENTER(semid);
233 CHECK_TSKCTX_UNL();
234 CHECK_SEMID(semid);
235 p_semcb = get_semcb(semid);
236
237 t_lock_cpu();
238 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
239 ercd = E_NOEXS;
240 }
241 else if (SEMID(p_semcb) > tmax_ssemid) {
242 dspreq = init_wait_queue(&(p_semcb->wait_queue));
243 p_seminib = (SEMINIB *)(p_semcb->p_seminib);
244 p_seminib->sematr = TA_NOEXS;
245 queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
246 if (dspreq) {
247 dispatch();
248 }
249 ercd = E_OK;
250 }
251 else {
252 ercd = E_OBJ;
253 }
254 t_unlock_cpu();
255
256 error_exit:
257 LOG_DEL_SEM_LEAVE(ercd);
258 return(ercd);
259}
260
261#endif /* TOPPERS_del_sem */
262
263/*
264 * ƒZƒ}ƒtƒHŽ‘Œ¹‚Ì•Ô‹p
265 */
266#ifdef TOPPERS_sig_sem
267
268ER
269sig_sem(ID semid)
270{
271 SEMCB *p_semcb;
272 TCB *p_tcb;
273 ER ercd;
274
275 LOG_SIG_SEM_ENTER(semid);
276 CHECK_TSKCTX_UNL();
277 CHECK_SEMID(semid);
278 p_semcb = get_semcb(semid);
279
280 t_lock_cpu();
281 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
282 ercd = E_NOEXS;
283 }
284 else if (!queue_empty(&(p_semcb->wait_queue))) {
285 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
286 if (wait_complete(p_tcb)) {
287 dispatch();
288 }
289 ercd = E_OK;
290 }
291 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
292 p_semcb->semcnt += 1;
293 ercd = E_OK;
294 }
295 else {
296 ercd = E_QOVR;
297 }
298 t_unlock_cpu();
299
300 error_exit:
301 LOG_SIG_SEM_LEAVE(ercd);
302 return(ercd);
303}
304
305#endif /* TOPPERS_sig_sem */
306
307/*
308 * ƒZƒ}ƒtƒHŽ‘Œ¹‚Ì•Ô‹pi”ñƒ^ƒXƒNƒRƒ“ƒeƒLƒXƒg—pj
309 */
310#ifdef TOPPERS_isig_sem
311
312ER
313isig_sem(ID semid)
314{
315 SEMCB *p_semcb;
316 TCB *p_tcb;
317 ER ercd;
318
319 LOG_ISIG_SEM_ENTER(semid);
320 CHECK_INTCTX_UNL();
321 CHECK_SEMID(semid);
322 p_semcb = get_semcb(semid);
323
324 i_lock_cpu();
325 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
326 ercd = E_NOEXS;
327 }
328 else if (!queue_empty(&(p_semcb->wait_queue))) {
329 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
330 if (wait_complete(p_tcb)) {
331 reqflg = true;
332 }
333 ercd = E_OK;
334 }
335 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
336 p_semcb->semcnt += 1;
337 ercd = E_OK;
338 }
339 else {
340 ercd = E_QOVR;
341 }
342 i_unlock_cpu();
343
344 error_exit:
345 LOG_ISIG_SEM_LEAVE(ercd);
346 return(ercd);
347}
348
349#endif /* TOPPERS_isig_sem */
350
351/*
352 * ƒZƒ}ƒtƒHŽ‘Œ¹‚ÌŠl“¾
353 */
354#ifdef TOPPERS_wai_sem
355
356ER
357wai_sem(ID semid)
358{
359 SEMCB *p_semcb;
360 WINFO_SEM winfo_sem;
361 ER ercd;
362
363 LOG_WAI_SEM_ENTER(semid);
364 CHECK_DISPATCH();
365 CHECK_SEMID(semid);
366 p_semcb = get_semcb(semid);
367
368 t_lock_cpu();
369 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
370 ercd = E_NOEXS;
371 }
372 else if (p_semcb->semcnt >= 1) {
373 p_semcb->semcnt -= 1;
374 ercd = E_OK;
375 }
376 else {
377 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
378 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
379 dispatch();
380 ercd = winfo_sem.winfo.wercd;
381 }
382 t_unlock_cpu();
383
384 error_exit:
385 LOG_WAI_SEM_LEAVE(ercd);
386 return(ercd);
387}
388
389#endif /* TOPPERS_wai_sem */
390
391/*
392 * ƒZƒ}ƒtƒHŽ‘Œ¹‚ÌŠl“¾iƒ|[ƒŠƒ“ƒOj
393 */
394#ifdef TOPPERS_pol_sem
395
396ER
397pol_sem(ID semid)
398{
399 SEMCB *p_semcb;
400 ER ercd;
401
402 LOG_POL_SEM_ENTER(semid);
403 CHECK_TSKCTX_UNL();
404 CHECK_SEMID(semid);
405 p_semcb = get_semcb(semid);
406
407 t_lock_cpu();
408 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
409 ercd = E_NOEXS;
410 }
411 else if (p_semcb->semcnt >= 1) {
412 p_semcb->semcnt -= 1;
413 ercd = E_OK;
414 }
415 else {
416 ercd = E_TMOUT;
417 }
418 t_unlock_cpu();
419
420 error_exit:
421 LOG_POL_SEM_LEAVE(ercd);
422 return(ercd);
423}
424
425#endif /* TOPPERS_pol_sem */
426
427/*
428 * ƒZƒ}ƒtƒHŽ‘Œ¹‚ÌŠl“¾iƒ^ƒCƒ€ƒAƒEƒg‚ ‚èj
429 */
430#ifdef TOPPERS_twai_sem
431
432ER
433twai_sem(ID semid, TMO tmout)
434{
435 SEMCB *p_semcb;
436 WINFO_SEM winfo_sem;
437 TMEVTB tmevtb;
438 ER ercd;
439
440 LOG_TWAI_SEM_ENTER(semid, tmout);
441 CHECK_DISPATCH();
442 CHECK_SEMID(semid);
443 CHECK_TMOUT(tmout);
444 p_semcb = get_semcb(semid);
445
446 t_lock_cpu();
447 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
448 ercd = E_NOEXS;
449 }
450 else if (p_semcb->semcnt >= 1) {
451 p_semcb->semcnt -= 1;
452 ercd = E_OK;
453 }
454 else if (tmout == TMO_POL) {
455 ercd = E_TMOUT;
456 }
457 else {
458 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
459 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
460 &tmevtb, tmout);
461 dispatch();
462 ercd = winfo_sem.winfo.wercd;
463 }
464 t_unlock_cpu();
465
466 error_exit:
467 LOG_TWAI_SEM_LEAVE(ercd);
468 return(ercd);
469}
470
471#endif /* TOPPERS_twai_sem */
472
473/*
474 * ƒZƒ}ƒtƒH‚̍ú‰»
475 */
476#ifdef TOPPERS_ini_sem
477
478ER
479ini_sem(ID semid)
480{
481 SEMCB *p_semcb;
482 bool_t dspreq;
483 ER ercd;
484
485 LOG_INI_SEM_ENTER(semid);
486 CHECK_TSKCTX_UNL();
487 CHECK_SEMID(semid);
488 p_semcb = get_semcb(semid);
489
490 t_lock_cpu();
491 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
492 ercd = E_NOEXS;
493 }
494 else {
495 dspreq = init_wait_queue(&(p_semcb->wait_queue));
496 p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
497 if (dspreq) {
498 dispatch();
499 }
500 ercd = E_OK;
501 }
502 t_unlock_cpu();
503
504 error_exit:
505 LOG_INI_SEM_LEAVE(ercd);
506 return(ercd);
507}
508
509#endif /* TOPPERS_ini_sem */
510
511/*
512 * ƒZƒ}ƒtƒH‚̏ó‘ÔŽQÆ
513 */
514#ifdef TOPPERS_ref_sem
515
516ER
517ref_sem(ID semid, T_RSEM *pk_rsem)
518{
519 SEMCB *p_semcb;
520 ER ercd;
521
522 LOG_REF_SEM_ENTER(semid, pk_rsem);
523 CHECK_TSKCTX_UNL();
524 CHECK_SEMID(semid);
525 p_semcb = get_semcb(semid);
526
527 t_lock_cpu();
528 if (p_semcb->p_seminib->sematr == TA_NOEXS) {
529 ercd = E_NOEXS;
530 }
531 else {
532 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
533 pk_rsem->semcnt = p_semcb->semcnt;
534 ercd = E_OK;
535 }
536 t_unlock_cpu();
537
538 error_exit:
539 LOG_REF_SEM_LEAVE(ercd, pk_rsem);
540 return(ercd);
541}
542
543#endif /* TOPPERS_ref_sem */
Note: See TracBrowser for help on using the repository browser.