source: kernel/semaphore.c @ 7

このファイルの 7 以降における最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 8.1 KB
Rev 
[7]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 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
12 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
13 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
14 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
15 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
16 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
17 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
18 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
20 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
21 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
22 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
23 *      €È¡¥
24 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
25 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
26 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
27 *        Êó¹ð€¹€ë€³€È¡¥
28 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
29 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
30 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
31 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
32 *      ÌÈÀÕ€¹€ë€³€È¡¥
33 *
34 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
35 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
36 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
37 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
38 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
39 *
40 *  @(#) $Id$
41 */
42
43/*
44 *              ¥»¥Þ¥Õ¥©µ¡Çœ
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51#include "semaphore.h"
52
53/*
54 *  ¥È¥ì¡Œ¥¹¥í¥°¥Þ¥¯¥í€Î¥Ç¥Õ¥©¥ë¥ÈÄêµÁ
55 */
56#ifndef LOG_SIG_SEM_ENTER
57#define LOG_SIG_SEM_ENTER(semid)
58#endif /* LOG_SIG_SEM_ENTER */
59
60#ifndef LOG_SIG_SEM_LEAVE
61#define LOG_SIG_SEM_LEAVE(ercd)
62#endif /* LOG_SIG_SEM_LEAVE */
63
64#ifndef LOG_ISIG_SEM_ENTER
65#define LOG_ISIG_SEM_ENTER(semid)
66#endif /* LOG_ISIG_SEM_ENTER */
67
68#ifndef LOG_ISIG_SEM_LEAVE
69#define LOG_ISIG_SEM_LEAVE(ercd)
70#endif /* LOG_ISIG_SEM_LEAVE */
71
72#ifndef LOG_WAI_SEM_ENTER
73#define LOG_WAI_SEM_ENTER(semid)
74#endif /* LOG_WAI_SEM_ENTER */
75
76#ifndef LOG_WAI_SEM_LEAVE
77#define LOG_WAI_SEM_LEAVE(ercd)
78#endif /* LOG_WAI_SEM_LEAVE */
79
80#ifndef LOG_POL_SEM_ENTER
81#define LOG_POL_SEM_ENTER(semid)
82#endif /* LOG_POL_SEM_ENTER */
83
84#ifndef LOG_POL_SEM_LEAVE
85#define LOG_POL_SEM_LEAVE(ercd)
86#endif /* LOG_POL_SEM_LEAVE */
87
88#ifndef LOG_TWAI_SEM_ENTER
89#define LOG_TWAI_SEM_ENTER(semid, tmout)
90#endif /* LOG_TWAI_SEM_ENTER */
91
92#ifndef LOG_TWAI_SEM_LEAVE
93#define LOG_TWAI_SEM_LEAVE(ercd)
94#endif /* LOG_TWAI_SEM_LEAVE */
95
96#ifndef LOG_INI_SEM_ENTER
97#define LOG_INI_SEM_ENTER(semid)
98#endif /* LOG_INI_SEM_ENTER */
99
100#ifndef LOG_INI_SEM_LEAVE
101#define LOG_INI_SEM_LEAVE(ercd)
102#endif /* LOG_INI_SEM_LEAVE */
103
104#ifndef LOG_REF_SEM_ENTER
105#define LOG_REF_SEM_ENTER(semid, pk_rsem)
106#endif /* LOG_REF_SEM_ENTER */
107
108#ifndef LOG_REF_SEM_LEAVE
109#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
110#endif /* LOG_REF_SEM_LEAVE */
111
112/*
113 *  ¥»¥Þ¥Õ¥©€Î¿ô
114 */
115#define tnum_sem        ((uint_t)(tmax_semid - TMIN_SEMID + 1))
116
117/*
118 *  ¥»¥Þ¥Õ¥©ID€«€é¥»¥Þ¥Õ¥©ŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯¥í
119 */
120#define INDEX_SEM(semid)        ((uint_t)((semid) - TMIN_SEMID))
121#define get_semcb(semid)        (&(semcb_table[INDEX_SEM(semid)]))
122
123/*
124 *  ¥»¥Þ¥Õ¥©µ¡Çœ€ÎœéŽü²œ
125 */
126#ifdef TOPPERS_semini
127
128void
129initialize_semaphore(void)
130{
131        uint_t  i;
132        SEMCB   *p_semcb;
133
134        for (i = 0; i < tnum_sem; i++) {
135                p_semcb = &(semcb_table[i]);
136                queue_initialize(&(p_semcb->wait_queue));
137                p_semcb->p_seminib = &(seminib_table[i]);
138                p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
139        }
140}
141
142#endif /* TOPPERS_semini */
143
144/*
145 *  ¥»¥Þ¥Õ¥©»ñž»€ÎÊÖµÑ
146 */
147#ifdef TOPPERS_sig_sem
148
149ER
150sig_sem(ID semid)
151{
152        SEMCB   *p_semcb;
153        TCB             *p_tcb;
154        ER              ercd;
155   
156        LOG_SIG_SEM_ENTER(semid);
157        CHECK_TSKCTX_UNL();
158        CHECK_SEMID(semid);
159        p_semcb = get_semcb(semid);
160
161        t_lock_cpu();
162        if (!queue_empty(&(p_semcb->wait_queue))) {
163                p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
164                if (wait_complete(p_tcb)) {
165                        dispatch();
166                }
167                ercd = E_OK;
168        }
169        else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
170                p_semcb->semcnt += 1;
171                ercd = E_OK;
172        }
173        else {
174                ercd = E_QOVR;
175        }
176        t_unlock_cpu();
177
178  error_exit:
179        LOG_SIG_SEM_LEAVE(ercd);
180        return(ercd);
181}
182
183#endif /* TOPPERS_sig_sem */
184
185/*
186 *  ¥»¥Þ¥Õ¥©»ñž»€ÎÊֵѡÊÈ󥿥¹¥¯¥³¥ó¥Æ¥­¥¹¥ÈÍÑ¡Ë
187 */
188#ifdef TOPPERS_isig_sem
189
190ER
191isig_sem(ID semid)
192{
193        SEMCB   *p_semcb;
194        TCB             *p_tcb;
195        ER              ercd;
196   
197        LOG_ISIG_SEM_ENTER(semid);
198        CHECK_INTCTX_UNL();
199        CHECK_SEMID(semid);
200        p_semcb = get_semcb(semid);
201
202        i_lock_cpu();
203        if (!queue_empty(&(p_semcb->wait_queue))) {
204                p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
205                if (wait_complete(p_tcb)) {
206                        reqflg = true;
207                }
208                ercd = E_OK;
209        }
210        else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
211                p_semcb->semcnt += 1;
212                ercd = E_OK;
213        }
214        else {
215                ercd = E_QOVR;
216        }
217        i_unlock_cpu();
218
219  error_exit:
220        LOG_ISIG_SEM_LEAVE(ercd);
221        return(ercd);
222}
223
224#endif /* TOPPERS_isig_sem */
225
226/*
227 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ
228 */
229#ifdef TOPPERS_wai_sem
230
231ER
232wai_sem(ID semid)
233{
234        SEMCB   *p_semcb;
235        WINFO_SEM winfo_sem;
236        ER              ercd;
237
238        LOG_WAI_SEM_ENTER(semid);
239        CHECK_DISPATCH();
240        CHECK_SEMID(semid);
241        p_semcb = get_semcb(semid);
242
243        t_lock_cpu();
244        if (p_semcb->semcnt >= 1) {
245                p_semcb->semcnt -= 1;
246                ercd = E_OK;
247        }
248        else {
249                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
250                wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
251                dispatch();
252                ercd = winfo_sem.winfo.wercd;
253        }
254        t_unlock_cpu();
255
256  error_exit:
257        LOG_WAI_SEM_LEAVE(ercd);
258        return(ercd);
259}
260
261#endif /* TOPPERS_wai_sem */
262
263/*
264 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ¡Ê¥Ý¡Œ¥ê¥ó¥°¡Ë
265 */
266#ifdef TOPPERS_pol_sem
267
268ER
269pol_sem(ID semid)
270{
271        SEMCB   *p_semcb;
272        ER              ercd;
273
274        LOG_POL_SEM_ENTER(semid);
275        CHECK_TSKCTX_UNL();
276        CHECK_SEMID(semid);
277        p_semcb = get_semcb(semid);
278
279        t_lock_cpu();
280        if (p_semcb->semcnt >= 1) {
281                p_semcb->semcnt -= 1;
282                ercd = E_OK;
283        }
284        else {
285                ercd = E_TMOUT;
286        }
287        t_unlock_cpu();
288
289  error_exit:
290        LOG_POL_SEM_LEAVE(ercd);
291        return(ercd);
292}
293
294#endif /* TOPPERS_pol_sem */
295
296/*
297 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ¡Ê¥¿¥€¥à¥¢¥Š¥È€¢€ê¡Ë
298 */
299#ifdef TOPPERS_twai_sem
300
301ER
302twai_sem(ID semid, TMO tmout)
303{
304        SEMCB   *p_semcb;
305        WINFO_SEM winfo_sem;
306        TMEVTB  tmevtb;
307        ER              ercd;
308
309        LOG_TWAI_SEM_ENTER(semid, tmout);
310        CHECK_DISPATCH();
311        CHECK_SEMID(semid);
312        CHECK_TMOUT(tmout);
313        p_semcb = get_semcb(semid);
314
315        t_lock_cpu();
316        if (p_semcb->semcnt >= 1) {
317                p_semcb->semcnt -= 1;
318                ercd = E_OK;
319        }
320        else if (tmout == TMO_POL) {
321                ercd = E_TMOUT;
322        }
323        else {
324                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
325                wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
326                                                                                                                &tmevtb, tmout);
327                dispatch();
328                ercd = winfo_sem.winfo.wercd;
329        }
330        t_unlock_cpu();
331
332  error_exit:
333        LOG_TWAI_SEM_LEAVE(ercd);
334        return(ercd);
335}
336
337#endif /* TOPPERS_twai_sem */
338
339/*
340 *  ¥»¥Þ¥Õ¥©€ÎºÆœéŽü²œ
341 */
342#ifdef TOPPERS_ini_sem
343
344ER
345ini_sem(ID semid)
346{
347        SEMCB   *p_semcb;
348        bool_t  dspreq;
349        ER              ercd;
350   
351        LOG_INI_SEM_ENTER(semid);
352        CHECK_TSKCTX_UNL();
353        CHECK_SEMID(semid);
354        p_semcb = get_semcb(semid);
355
356        t_lock_cpu();
357        dspreq = init_wait_queue(&(p_semcb->wait_queue));
358        p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
359        if (dspreq) {
360                dispatch();
361        }
362        ercd = E_OK;
363        t_unlock_cpu();
364
365  error_exit:
366        LOG_INI_SEM_LEAVE(ercd);
367        return(ercd);
368}
369
370#endif /* TOPPERS_ini_sem */
371
372/*
373 *  ¥»¥Þ¥Õ¥©€ÎŸõÂÖ»²ŸÈ
374 */
375#ifdef TOPPERS_ref_sem
376
377ER
378ref_sem(ID semid, T_RSEM *pk_rsem)
379{
380        SEMCB   *p_semcb;
381        ER              ercd;
382   
383        LOG_REF_SEM_ENTER(semid, pk_rsem);
384        CHECK_TSKCTX_UNL();
385        CHECK_SEMID(semid);
386        p_semcb = get_semcb(semid);
387
388        t_lock_cpu();
389        pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
390        pk_rsem->semcnt = p_semcb->semcnt;
391        ercd = E_OK;
392        t_unlock_cpu();
393
394  error_exit:
395        LOG_REF_SEM_LEAVE(ercd, pk_rsem);
396        return(ercd);
397}
398
399#endif /* TOPPERS_ref_sem */
詳しい使い方は TracBrowser を参照してください。