source: extension/dcre/kernel/semaphore.c @ 7

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

TOPPERS/ASP 1.9.1

ファイルサイズ: 11.0 KB
 
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 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(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_ACRE_SEM_ENTER
57#define LOG_ACRE_SEM_ENTER(pk_csem)
58#endif /* LOG_ACRE_SEM_ENTER */
59
60#ifndef LOG_ACRE_SEM_LEAVE
61#define LOG_ACRE_SEM_LEAVE(ercd)
62#endif /* LOG_ACRE_SEM_LEAVE */
63
64#ifndef LOG_DEL_SEM_ENTER
65#define LOG_DEL_SEM_ENTER(semid)
66#endif /* LOG_DEL_SEM_ENTER */
67
68#ifndef LOG_DEL_SEM_LEAVE
69#define LOG_DEL_SEM_LEAVE(ercd)
70#endif /* LOG_DEL_SEM_LEAVE */
71
72#ifndef LOG_SIG_SEM_ENTER
73#define LOG_SIG_SEM_ENTER(semid)
74#endif /* LOG_SIG_SEM_ENTER */
75
76#ifndef LOG_SIG_SEM_LEAVE
77#define LOG_SIG_SEM_LEAVE(ercd)
78#endif /* LOG_SIG_SEM_LEAVE */
79
80#ifndef LOG_ISIG_SEM_ENTER
81#define LOG_ISIG_SEM_ENTER(semid)
82#endif /* LOG_ISIG_SEM_ENTER */
83
84#ifndef LOG_ISIG_SEM_LEAVE
85#define LOG_ISIG_SEM_LEAVE(ercd)
86#endif /* LOG_ISIG_SEM_LEAVE */
87
88#ifndef LOG_WAI_SEM_ENTER
89#define LOG_WAI_SEM_ENTER(semid)
90#endif /* LOG_WAI_SEM_ENTER */
91
92#ifndef LOG_WAI_SEM_LEAVE
93#define LOG_WAI_SEM_LEAVE(ercd)
94#endif /* LOG_WAI_SEM_LEAVE */
95
96#ifndef LOG_POL_SEM_ENTER
97#define LOG_POL_SEM_ENTER(semid)
98#endif /* LOG_POL_SEM_ENTER */
99
100#ifndef LOG_POL_SEM_LEAVE
101#define LOG_POL_SEM_LEAVE(ercd)
102#endif /* LOG_POL_SEM_LEAVE */
103
104#ifndef LOG_TWAI_SEM_ENTER
105#define LOG_TWAI_SEM_ENTER(semid, tmout)
106#endif /* LOG_TWAI_SEM_ENTER */
107
108#ifndef LOG_TWAI_SEM_LEAVE
109#define LOG_TWAI_SEM_LEAVE(ercd)
110#endif /* LOG_TWAI_SEM_LEAVE */
111
112#ifndef LOG_INI_SEM_ENTER
113#define LOG_INI_SEM_ENTER(semid)
114#endif /* LOG_INI_SEM_ENTER */
115
116#ifndef LOG_INI_SEM_LEAVE
117#define LOG_INI_SEM_LEAVE(ercd)
118#endif /* LOG_INI_SEM_LEAVE */
119
120#ifndef LOG_REF_SEM_ENTER
121#define LOG_REF_SEM_ENTER(semid, pk_rsem)
122#endif /* LOG_REF_SEM_ENTER */
123
124#ifndef LOG_REF_SEM_LEAVE
125#define LOG_REF_SEM_LEAVE(ercd, pk_rsem)
126#endif /* LOG_REF_SEM_LEAVE */
127
128/*
129 *  ¥»¥Þ¥Õ¥©€Î¿ô
130 */
131#define tnum_sem        ((uint_t)(tmax_semid - TMIN_SEMID + 1))
132#define tnum_ssem       ((uint_t)(tmax_ssemid - TMIN_SEMID + 1))
133
134/*
135 *  ¥»¥Þ¥Õ¥©ID€«€é¥»¥Þ¥Õ¥©ŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯¥í
136 */
137#define INDEX_SEM(semid)        ((uint_t)((semid) - TMIN_SEMID))
138#define get_semcb(semid)        (&(semcb_table[INDEX_SEM(semid)]))
139
140#ifdef TOPPERS_semini
141
142/*
143 *  »ÈÍÑ€·€Æ€€€Ê€€¥»¥Þ¥Õ¥©ŽÉÍý¥Ö¥í¥Ã¥¯€Î¥ê¥¹¥È
144 */
145QUEUE   free_semcb;
146
147/*
148 *  ¥»¥Þ¥Õ¥©µ¡Çœ€ÎœéŽü²œ
149 */
150void
151initialize_semaphore(void)
152{
153        uint_t  i, j;
154        SEMCB   *p_semcb;
155        SEMINIB *p_seminib;
156
157        for (i = 0; i < tnum_ssem; i++) {
158                p_semcb = &(semcb_table[i]);
159                queue_initialize(&(p_semcb->wait_queue));
160                p_semcb->p_seminib = &(seminib_table[i]);
161                p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
162        }
163        queue_initialize(&free_semcb);
164        for (j = 0; i < tnum_sem; i++, j++) {
165                p_semcb = &(semcb_table[i]);
166                p_seminib = &(aseminib_table[j]);
167                p_seminib->sematr = TA_NOEXS;
168                p_semcb->p_seminib = ((const SEMINIB *) p_seminib);
169                queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
170        }
171}
172
173#endif /* TOPPERS_semini */
174
175/*
176 *  ¥»¥Þ¥Õ¥©€ÎÀžÀ®
177 */
178#ifdef TOPPERS_acre_sem
179
180ER_UINT
181acre_sem(const T_CSEM *pk_csem)
182{
183        SEMCB   *p_semcb;
184        SEMINIB *p_seminib;
185        ER              ercd;
186
187        LOG_ACRE_SEM_ENTER(pk_csem);
188        CHECK_TSKCTX_UNL();
189        CHECK_RSATR(pk_csem->sematr, TA_TPRI);
190        CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
191        CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
192
193        t_lock_cpu();
194        if (tnum_sem == 0 || queue_empty(&free_semcb)) {
195                ercd = E_NOID;
196        }
197        else {
198                p_semcb = ((SEMCB *) queue_delete_next(&free_semcb));
199                p_seminib = (SEMINIB *)(p_semcb->p_seminib);
200                p_seminib->sematr = pk_csem->sematr;
201                p_seminib->isemcnt = pk_csem->isemcnt;
202                p_seminib->maxsem = pk_csem->maxsem;
203
204                queue_initialize(&(p_semcb->wait_queue));
205                p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
206                ercd = SEMID(p_semcb);
207        }
208        t_unlock_cpu();
209
210  error_exit:
211        LOG_ACRE_SEM_LEAVE(ercd);
212        return(ercd);
213}
214
215#endif /* TOPPERS_acre_sem */
216
217/*
218 *  ¥»¥Þ¥Õ¥©€Îºïœü
219 */
220#ifdef TOPPERS_del_sem
221
222ER
223del_sem(ID semid)
224{
225        SEMCB   *p_semcb;
226        SEMINIB *p_seminib;
227        bool_t  dspreq;
228        ER              ercd;
229
230        LOG_DEL_SEM_ENTER(semid);
231        CHECK_TSKCTX_UNL();
232        CHECK_SEMID(semid);
233        p_semcb = get_semcb(semid);
234
235        t_lock_cpu();
236        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
237                ercd = E_NOEXS;
238        }
239        else if (SEMID(p_semcb) > tmax_ssemid) {
240                dspreq = init_wait_queue(&(p_semcb->wait_queue));
241                p_seminib = (SEMINIB *)(p_semcb->p_seminib);
242                p_seminib->sematr = TA_NOEXS;
243                queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
244                if (dspreq) {
245                        dispatch();
246                }
247                ercd = E_OK;
248        }
249        else {
250                ercd = E_OBJ;
251        }
252        t_unlock_cpu();
253
254  error_exit:
255        LOG_DEL_SEM_LEAVE(ercd);
256        return(ercd);
257}
258
259#endif /* TOPPERS_del_sem */
260
261/*
262 *  ¥»¥Þ¥Õ¥©»ñž»€ÎÊÖµÑ
263 */
264#ifdef TOPPERS_sig_sem
265
266ER
267sig_sem(ID semid)
268{
269        SEMCB   *p_semcb;
270        TCB             *p_tcb;
271        ER              ercd;
272   
273        LOG_SIG_SEM_ENTER(semid);
274        CHECK_TSKCTX_UNL();
275        CHECK_SEMID(semid);
276        p_semcb = get_semcb(semid);
277
278        t_lock_cpu();
279        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
280                ercd = E_NOEXS;
281        }
282        else if (!queue_empty(&(p_semcb->wait_queue))) {
283                p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
284                if (wait_complete(p_tcb)) {
285                        dispatch();
286                }
287                ercd = E_OK;
288        }
289        else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
290                p_semcb->semcnt += 1;
291                ercd = E_OK;
292        }
293        else {
294                ercd = E_QOVR;
295        }
296        t_unlock_cpu();
297
298  error_exit:
299        LOG_SIG_SEM_LEAVE(ercd);
300        return(ercd);
301}
302
303#endif /* TOPPERS_sig_sem */
304
305/*
306 *  ¥»¥Þ¥Õ¥©»ñž»€ÎÊֵѡÊÈ󥿥¹¥¯¥³¥ó¥Æ¥­¥¹¥ÈÍÑ¡Ë
307 */
308#ifdef TOPPERS_isig_sem
309
310ER
311isig_sem(ID semid)
312{
313        SEMCB   *p_semcb;
314        TCB             *p_tcb;
315        ER              ercd;
316   
317        LOG_ISIG_SEM_ENTER(semid);
318        CHECK_INTCTX_UNL();
319        CHECK_SEMID(semid);
320        p_semcb = get_semcb(semid);
321
322        i_lock_cpu();
323        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
324                ercd = E_NOEXS;
325        }
326        else if (!queue_empty(&(p_semcb->wait_queue))) {
327                p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
328                if (wait_complete(p_tcb)) {
329                        reqflg = true;
330                }
331                ercd = E_OK;
332        }
333        else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
334                p_semcb->semcnt += 1;
335                ercd = E_OK;
336        }
337        else {
338                ercd = E_QOVR;
339        }
340        i_unlock_cpu();
341
342  error_exit:
343        LOG_ISIG_SEM_LEAVE(ercd);
344        return(ercd);
345}
346
347#endif /* TOPPERS_isig_sem */
348
349/*
350 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ
351 */
352#ifdef TOPPERS_wai_sem
353
354ER
355wai_sem(ID semid)
356{
357        SEMCB   *p_semcb;
358        WINFO_SEM winfo_sem;
359        ER              ercd;
360
361        LOG_WAI_SEM_ENTER(semid);
362        CHECK_DISPATCH();
363        CHECK_SEMID(semid);
364        p_semcb = get_semcb(semid);
365
366        t_lock_cpu();
367        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
368                ercd = E_NOEXS;
369        }
370        else if (p_semcb->semcnt >= 1) {
371                p_semcb->semcnt -= 1;
372                ercd = E_OK;
373        }
374        else {
375                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
376                wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
377                dispatch();
378                ercd = winfo_sem.winfo.wercd;
379        }
380        t_unlock_cpu();
381
382  error_exit:
383        LOG_WAI_SEM_LEAVE(ercd);
384        return(ercd);
385}
386
387#endif /* TOPPERS_wai_sem */
388
389/*
390 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ¡Ê¥Ý¡Œ¥ê¥ó¥°¡Ë
391 */
392#ifdef TOPPERS_pol_sem
393
394ER
395pol_sem(ID semid)
396{
397        SEMCB   *p_semcb;
398        ER              ercd;
399
400        LOG_POL_SEM_ENTER(semid);
401        CHECK_TSKCTX_UNL();
402        CHECK_SEMID(semid);
403        p_semcb = get_semcb(semid);
404
405        t_lock_cpu();
406        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
407                ercd = E_NOEXS;
408        }
409        else if (p_semcb->semcnt >= 1) {
410                p_semcb->semcnt -= 1;
411                ercd = E_OK;
412        }
413        else {
414                ercd = E_TMOUT;
415        }
416        t_unlock_cpu();
417
418  error_exit:
419        LOG_POL_SEM_LEAVE(ercd);
420        return(ercd);
421}
422
423#endif /* TOPPERS_pol_sem */
424
425/*
426 *  ¥»¥Þ¥Õ¥©»ñž»€Î³ÍÆÀ¡Ê¥¿¥€¥à¥¢¥Š¥È€¢€ê¡Ë
427 */
428#ifdef TOPPERS_twai_sem
429
430ER
431twai_sem(ID semid, TMO tmout)
432{
433        SEMCB   *p_semcb;
434        WINFO_SEM winfo_sem;
435        TMEVTB  tmevtb;
436        ER              ercd;
437
438        LOG_TWAI_SEM_ENTER(semid, tmout);
439        CHECK_DISPATCH();
440        CHECK_SEMID(semid);
441        CHECK_TMOUT(tmout);
442        p_semcb = get_semcb(semid);
443
444        t_lock_cpu();
445        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
446                ercd = E_NOEXS;
447        }
448        else if (p_semcb->semcnt >= 1) {
449                p_semcb->semcnt -= 1;
450                ercd = E_OK;
451        }
452        else if (tmout == TMO_POL) {
453                ercd = E_TMOUT;
454        }
455        else {
456                p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
457                wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
458                                                                                                                &tmevtb, tmout);
459                dispatch();
460                ercd = winfo_sem.winfo.wercd;
461        }
462        t_unlock_cpu();
463
464  error_exit:
465        LOG_TWAI_SEM_LEAVE(ercd);
466        return(ercd);
467}
468
469#endif /* TOPPERS_twai_sem */
470
471/*
472 *  ¥»¥Þ¥Õ¥©€ÎºÆœéŽü²œ
473 */
474#ifdef TOPPERS_ini_sem
475
476ER
477ini_sem(ID semid)
478{
479        SEMCB   *p_semcb;
480        bool_t  dspreq;
481        ER              ercd;
482   
483        LOG_INI_SEM_ENTER(semid);
484        CHECK_TSKCTX_UNL();
485        CHECK_SEMID(semid);
486        p_semcb = get_semcb(semid);
487
488        t_lock_cpu();
489        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
490                ercd = E_NOEXS;
491        }
492        else {
493                dspreq = init_wait_queue(&(p_semcb->wait_queue));
494                p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
495                if (dspreq) {
496                        dispatch();
497                }
498                ercd = E_OK;
499        }
500        t_unlock_cpu();
501
502  error_exit:
503        LOG_INI_SEM_LEAVE(ercd);
504        return(ercd);
505}
506
507#endif /* TOPPERS_ini_sem */
508
509/*
510 *  ¥»¥Þ¥Õ¥©€ÎŸõÂÖ»²ŸÈ
511 */
512#ifdef TOPPERS_ref_sem
513
514ER
515ref_sem(ID semid, T_RSEM *pk_rsem)
516{
517        SEMCB   *p_semcb;
518        ER              ercd;
519   
520        LOG_REF_SEM_ENTER(semid, pk_rsem);
521        CHECK_TSKCTX_UNL();
522        CHECK_SEMID(semid);
523        p_semcb = get_semcb(semid);
524
525        t_lock_cpu();
526        if (p_semcb->p_seminib->sematr == TA_NOEXS) {
527                ercd = E_NOEXS;
528        }
529        else {
530                pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
531                pk_rsem->semcnt = p_semcb->semcnt;
532                ercd = E_OK;
533        }
534        t_unlock_cpu();
535
536  error_exit:
537        LOG_REF_SEM_LEAVE(ercd, pk_rsem);
538        return(ercd);
539}
540
541#endif /* TOPPERS_ref_sem */
詳しい使い方は TracBrowser を参照してください。