gonzui


Format: Advanced Search

mtkernel_3/kernel/tkernel/messagebuf.cbare sourcepermlink (0.06 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.00
    4:  *
    5:  *    Copyright (C) 2006-2019 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.1.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2019/12/11.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: /*
   15:  *      messagebuf.c
   16:  *      Message Buffer
   17:  */
   18: 
   19: #include "kernel.h"
   20: #include "wait.h"
   21: #include "check.h"
   22: #include "messagebuf.h"
   23: 
   24: #if USE_MESSAGEBUFFER == 1
   25: 
   26: 
   27: Noinit(EXPORT MBFCB knl_mbfcb_table[NUM_MBFID]);        /* Message buffer control block */
   28: Noinit(EXPORT QUEUE knl_free_mbfcb);    /* FreeQue */
   29: 
   30: 
   31: /*
   32:  * Initialization of message buffer control block 
   33:  */
   34: EXPORT ER knl_messagebuffer_initialize( void )
   35: {
   36:         MBFCB  *mbfcb, *end;
   37: 
   38:         /* Get system information */
   39:         if ( NUM_MBFID < 1 ) {
   40:                 return E_SYS;
   41:         }
   42: 
   43:         /* Register all control blocks onto FreeQue */
   44:         QueInit(&knl_free_mbfcb);
   45:         end = knl_mbfcb_table + NUM_MBFID;
   46:         for ( mbfcb = knl_mbfcb_table; mbfcb < end; mbfcb++ ) {
   47:                 mbfcb->mbfid = 0;
   48:                 QueInsert(&mbfcb->send_queue, &knl_free_mbfcb);
   49:         }
   50: 
   51:         return E_OK;
   52: }
   53: 
   54: /* ------------------------------------------------------------------------ */
   55: 
   56: /*
   57:  * Store the message to message buffer.
   58:  */
   59: LOCAL void knl_msg_to_mbf( MBFCB *mbfcb, CONST void *msg, INT msgsz )
   60: {
   61:         W      tail = mbfcb->tail;
   62:         VB     *buffer = mbfcb->buffer;
   63:         W      remsz;
   64: 
   65:         mbfcb->frbufsz -= (W)(HEADERSZ + ROUNDSZ(msgsz));
   66: 
   67:         *(HEADER*)&buffer[tail] = msgsz;
   68:         tail += HEADERSZ;
   69:         if ( tail >= mbfcb->bufsz ) {
   70:                 tail = 0;
   71:         }
   72: 
   73:         if ( (remsz = mbfcb->bufsz - tail) < (W)msgsz ) {
   74:                 knl_memcpy(&buffer[tail], msg, (SZ)remsz);
   75:                 msg = (VB*)msg + remsz;
   76:                 msgsz -= (INT)remsz;
   77:                 tail = 0;
   78:         }
   79:         knl_memcpy(&buffer[tail], msg, (SZ)msgsz);
   80:         tail += (W)ROUNDSZ(msgsz);
   81:         if ( tail >= mbfcb->bufsz ) {
   82:                 tail = 0;
   83:         }
   84: 
   85:         mbfcb->tail = tail;
   86: }
   87: 
   88: /* ------------------------------------------------------------------------ */
   89: 
   90: /*
   91:  * Accept message and release wait task,
   92:  * as long as there are free message area.
   93:  */
   94: LOCAL void knl_mbf_wakeup( MBFCB *mbfcb )
   95: {
   96:         TCB    *top;
   97:         INT    msgsz;
   98: 
   99:         while ( !isQueEmpty(&mbfcb->send_queue) ) {
  100:                 top = (TCB*)mbfcb->send_queue.next;
  101:                 msgsz = top->winfo.smbf.msgsz;
  102:                 if ( !knl_mbf_free(mbfcb, msgsz) ) {
  103:                         break;
  104:                 }
  105: 
  106:                 /* Store a message from waiting task and release it */
  107:                 knl_msg_to_mbf(mbfcb, top->winfo.smbf.msg, msgsz);
  108:                 knl_wait_release_ok(top);
  109:         }
  110: }
  111: 
  112: 
  113: /*
  114:  * Create message buffer
  115:  */
  116: SYSCALL ID tk_cre_mbf( CONST T_CMBF *pk_cmbf )
  117: {
  118: #if CHK_RSATR
  119:         const ATR VALID_MBFATR = {
  120:                  TA_TPRI
  121:                 |TA_USERBUF
  122: #if USE_OBJECT_NAME
  123:                 |TA_DSNAME
  124: #endif
  125:         };
  126: #endif
  127:         MBFCB  *mbfcb;
  128:         ID     mbfid;
  129:         W      bufsz;
  130:         VB     *msgbuf;
  131:         ER     ercd;
  132: 
  133:         CHECK_RSATR(pk_cmbf->mbfatr, VALID_MBFATR);
  134:         CHECK_PAR(pk_cmbf->bufsz >= 0);
  135:         CHECK_PAR(pk_cmbf->maxmsz > 0);
  136: #if !USE_IMALLOC
  137:         /* TA_USERBUF must be specified if configured in no Imalloc */
  138:         CHECK_PAR((pk_cmbf->mbfatr & TA_USERBUF) != 0);
  139: #endif
  140:         bufsz = (W)ROUNDSZ(pk_cmbf->bufsz);
  141: 
  142:         if ( bufsz > 0 ) {
  143: #if USE_IMALLOC
  144:                 if ( (pk_cmbf->mbfatr & TA_USERBUF) != 0 ) {
  145:                         /* Size of user buffer must be multiples of sizeof(HEADER) */
  146:                         if ( bufsz != pk_cmbf->bufsz ) {
  147:                                 return E_PAR;
  148:                         }
  149:                         /* Use user buffer */
  150:                         msgbuf = (VB*) pk_cmbf->bufptr;
  151:                 } else {
  152:                         /* Allocate by kernel */
  153:                         msgbuf = knl_Imalloc((UW)bufsz);
  154:                         if ( msgbuf == NULL ) {
  155:                                 return E_NOMEM;
  156:                         }
  157:                 }
  158: #else
  159:                 /* Size of user buffer must be multiples of sizeof(HEADER) */
  160:                 if ( bufsz != pk_cmbf->bufsz ) {
  161:                         return E_PAR;
  162:                 }
  163:                 /* Use user buffer */
  164:                 msgbuf = (VB*) pk_cmbf->bufptr;
  165: #endif
  166:         } else {
  167:                 msgbuf = NULL;
  168:         }
  169: 
  170:         BEGIN_CRITICAL_SECTION;
  171:         /* Get control block from FreeQue */
  172:         mbfcb = (MBFCB*)QueRemoveNext(&knl_free_mbfcb);
  173:         if ( mbfcb == NULL ) {
  174:                 ercd = E_LIMIT;
  175:         } else {
  176:                 mbfid = ID_MBF(mbfcb - knl_mbfcb_table);
  177: 
  178:                 /* Initialize control block */
  179:                 QueInit(&mbfcb->send_queue);
  180:                 mbfcb->mbfid = mbfid;
  181:                 mbfcb->exinf = pk_cmbf->exinf;
  182:                 mbfcb->mbfatr = pk_cmbf->mbfatr;
  183:                 QueInit(&mbfcb->recv_queue);
  184:                 mbfcb->buffer = msgbuf;
  185:                 mbfcb->bufsz = mbfcb->frbufsz = bufsz;
  186:                 mbfcb->maxmsz = pk_cmbf->maxmsz;
  187:                 mbfcb->head = mbfcb->tail = 0;
  188: #if USE_OBJECT_NAME
  189:                 if ( (pk_cmbf->mbfatr & TA_DSNAME) != 0 ) {
  190:                         knl_strncpy((char*)mbfcb->name, (char*)pk_cmbf->dsname,
  191:                                 OBJECT_NAME_LENGTH);
  192:                 }
  193: #endif
  194:                 ercd = mbfid;
  195:         }
  196:         END_CRITICAL_SECTION;
  197: 
  198: #if USE_IMALLOC
  199:         if ( (ercd < E_OK) && (msgbuf != NULL) && ((pk_cmbf->mbfatr & TA_USERBUF) == 0 ) ) {
  200:                 knl_Ifree(msgbuf);
  201:         }
  202: #endif
  203: 
  204:         return ercd;
  205: }
  206: 
  207: #ifdef USE_FUNC_TK_DEL_MBF
  208: /*
  209:  * Delete message buffer
  210:  */
  211: SYSCALL ER tk_del_mbf( ID mbfid )
  212: {
  213:         MBFCB  *mbfcb;
  214:         VB     *msgbuf = NULL;
  215:         ER     ercd = E_OK;
  216: 
  217:         CHECK_MBFID(mbfid);
  218: 
  219:         mbfcb = get_mbfcb(mbfid);
  220: 
  221:         BEGIN_CRITICAL_SECTION;
  222:         if ( mbfcb->mbfid == 0 ) {
  223:                 ercd = E_NOEXS;
  224:         } else {
  225:                 msgbuf = mbfcb->buffer;
  226: 
  227:                 /* Release wait state of task (E_DLT) */
  228:                 knl_wait_delete(&mbfcb->recv_queue);
  229:                 knl_wait_delete(&mbfcb->send_queue);
  230: 
  231:                 /* Return to FreeQue */
  232:                 QueInsert(&mbfcb->send_queue, &knl_free_mbfcb);
  233:                 mbfcb->mbfid = 0;
  234:         }
  235:         END_CRITICAL_SECTION;
  236: 
  237: #if USE_IMALLOC
  238:         if ( msgbuf != NULL && ((mbfcb->mbfatr & TA_USERBUF) == 0 ) ) {
  239:                 knl_Ifree(msgbuf);
  240:         }
  241: #endif
  242: 
  243:         return ercd;
  244: }
  245: #endif /* USE_FUNC_TK_DEL_MBF */
  246: 
  247: /*
  248:  * Processing if the priority of wait task changes
  249:  */
  250: LOCAL void knl_mbf_chg_pri( TCB *tcb, INT oldpri )
  251: {
  252:         MBFCB  *mbfcb;
  253: 
  254:         mbfcb = get_mbfcb(tcb->wid);
  255:         if ( oldpri >= 0 ) {
  256:                 /* Reorder wait queue */
  257:                 knl_gcb_change_priority((GCB*)mbfcb, tcb);
  258:         }
  259: 
  260:         /* If the new head task in a send wait queue is able to sent, 
  261:            send its message */
  262:         knl_mbf_wakeup(mbfcb);
  263: }
  264: 
  265: /*
  266:  * Processing if the wait task is released
  267:  */
  268: LOCAL void knl_mbf_rel_wai( TCB *tcb )
  269: {
  270:         knl_mbf_chg_pri(tcb, -1);
  271: }
  272: 
  273: /*
  274:  * Definition of message buffer wait specification
  275:  */
  276: LOCAL CONST WSPEC knl_wspec_smbf_tfifo = { TTW_SMBF, NULL,      knl_mbf_rel_wai };
  277: LOCAL CONST WSPEC knl_wspec_smbf_tpri  = { TTW_SMBF, knl_mbf_chg_pri,   knl_mbf_rel_wai };
  278: 
  279: /*
  280:  * Send to message buffer
  281:  */
  282: SYSCALL ER tk_snd_mbf( ID mbfid, CONST void *msg, INT msgsz, TMO tmout )
  283: {
  284:         MBFCB  *mbfcb;
  285:         TCB    *tcb;
  286:         ER     ercd = E_OK;
  287: 
  288:         CHECK_MBFID(mbfid);
  289:         CHECK_PAR(msgsz > 0);
  290:         CHECK_TMOUT(tmout);
  291:         CHECK_DISPATCH_POL(tmout);
  292: 
  293:         mbfcb = get_mbfcb(mbfid);
  294: 
  295:         BEGIN_CRITICAL_SECTION;
  296:         if ( mbfcb->mbfid == 0 ) {
  297:                 ercd = E_NOEXS;
  298:                 goto error_exit;
  299:         }
  300: #if CHK_PAR
  301:         if ( msgsz > mbfcb->maxmsz ) {
  302:                 ercd = E_PAR;
  303:                 goto error_exit;
  304:         }
  305: #endif
  306: 
  307:         if ( !isQueEmpty(&mbfcb->recv_queue) ) {
  308:                 /* Send directly to the receive wait task */
  309:                 tcb = (TCB*)mbfcb->recv_queue.next;
  310:                 knl_memcpy(tcb->winfo.rmbf.msg, msg, (SZ)msgsz);
  311:                 *tcb->winfo.rmbf.p_msgsz = msgsz;
  312:                 knl_wait_release_ok(tcb);
  313: 
  314:         } else if ( (in_indp() || knl_gcb_top_of_wait_queue((GCB*)mbfcb, knl_ctxtsk) == knl_ctxtsk)
  315:                   &&(knl_mbf_free(mbfcb, msgsz)) ) {
  316:                 /* Store the message to message buffer */
  317:                 knl_msg_to_mbf(mbfcb, msg, msgsz);
  318: 
  319:         } else {
  320:                 ercd = E_TMOUT;
  321:                 if ( tmout != TMO_POL ) {
  322:                         /* Ready for send wait */
  323:                         knl_ctxtsk->wspec = ( (mbfcb->mbfatr & TA_TPRI) != 0 )?
  324:                                         &knl_wspec_smbf_tpri: &knl_wspec_smbf_tfifo;
  325:                         knl_ctxtsk->wercd = &ercd;
  326:                         knl_ctxtsk->winfo.smbf.msg = msg;
  327:                         knl_ctxtsk->winfo.smbf.msgsz = msgsz;
  328:                         knl_gcb_make_wait((GCB*)mbfcb, tmout);
  329:                 }
  330:         }
  331: 
  332:     error_exit:
  333:         END_CRITICAL_SECTION;
  334: 
  335:         return ercd;
  336: }
  337: 
  338: 
  339: LOCAL CONST WSPEC knl_wspec_rmbf       = { TTW_RMBF, NULL,      NULL     };
  340: 
  341: /*
  342:  * Get a message from message buffer.
  343:  * Return the message size.
  344:  */
  345: LOCAL INT knl_mbf_to_msg( MBFCB *mbfcb, void *msg )
  346: {
  347:         W      head = mbfcb->head;
  348:         VB     *buffer = mbfcb->buffer;
  349:         INT    msgsz, actsz;
  350:         W      remsz;
  351: 
  352:         actsz = msgsz = *(HEADER*)&buffer[head];
  353:         mbfcb->frbufsz += (W)(HEADERSZ + ROUNDSZ(msgsz));
  354: 
  355:         head += (W)HEADERSZ;
  356:         if ( head >= mbfcb->bufsz ) {
  357:                 head = 0;
  358:         }
  359: 
  360:         if ( (remsz = mbfcb->bufsz - head) < (W)msgsz ) {
  361:                 knl_memcpy(msg, &buffer[head], (SZ)remsz);
  362:                 msg = (VB*)msg + remsz;
  363:                 msgsz -= (INT)remsz;
  364:                 head = 0;
  365:         }
  366:         knl_memcpy(msg, &buffer[head], (SZ)msgsz);
  367:         head += (INT)ROUNDSZ(msgsz);
  368:         if ( head >= mbfcb->bufsz ) {
  369:                 head = 0;
  370:         }
  371: 
  372:         mbfcb->head = head;
  373: 
  374:         return actsz;
  375: }
  376: 
  377: /*
  378:  * Receive from message buffer
  379:  */
  380: SYSCALL INT tk_rcv_mbf( ID mbfid, void *msg, TMO tmout )
  381: {
  382:         MBFCB  *mbfcb;
  383:         TCB    *tcb;
  384:         INT    rcvsz;
  385:         ER     ercd = E_OK;
  386: 
  387:         CHECK_MBFID(mbfid);
  388:         CHECK_TMOUT(tmout);
  389:         CHECK_DISPATCH();
  390: 
  391:         mbfcb = get_mbfcb(mbfid);
  392: 
  393:         BEGIN_CRITICAL_SECTION;
  394:         if (mbfcb->mbfid == 0) {
  395:                 ercd = E_NOEXS;
  396:                 goto error_exit;
  397:         }
  398: 
  399:         if ( !knl_mbf_empty(mbfcb) ) {
  400:                 /* Read from message buffer */
  401:                 rcvsz = knl_mbf_to_msg(mbfcb, msg);
  402: 
  403:                 /* Accept message from sending task(s) */
  404:                 knl_mbf_wakeup(mbfcb);
  405: 
  406:         } else if ( !isQueEmpty(&mbfcb->send_queue) ) {
  407:                 /* Receive directly from send wait task */
  408:                 tcb = (TCB*)mbfcb->send_queue.next;
  409:                 rcvsz = tcb->winfo.smbf.msgsz;
  410:                 knl_memcpy(msg, tcb->winfo.smbf.msg, (SZ)rcvsz);
  411:                 knl_wait_release_ok(tcb);
  412:                 knl_mbf_wakeup(mbfcb);
  413:         } else {
  414:                 ercd = E_TMOUT;
  415:                 if ( tmout != TMO_POL ) {
  416:                         /* Ready for receive wait */
  417:                         knl_ctxtsk->wspec = &knl_wspec_rmbf;
  418:                         knl_ctxtsk->wid = mbfid;
  419:                         knl_ctxtsk->wercd = &ercd;
  420:                         knl_ctxtsk->winfo.rmbf.msg = msg;
  421:                         knl_ctxtsk->winfo.rmbf.p_msgsz = &rcvsz;
  422:                         knl_make_wait(tmout, mbfcb->mbfatr);
  423:                         QueInsert(&knl_ctxtsk->tskque, &mbfcb->recv_queue);
  424:                 }
  425:         }
  426: 
  427:     error_exit:
  428:         END_CRITICAL_SECTION;
  429: 
  430:         return ( ercd < E_OK )? ercd: rcvsz;
  431: }
  432: 
  433: #ifdef USE_FUNC_TK_REF_MBF
  434: /*
  435:  * Refer message buffer state
  436:  */
  437: SYSCALL ER tk_ref_mbf( ID mbfid, T_RMBF *pk_rmbf )
  438: {
  439:         MBFCB  *mbfcb;
  440:         TCB    *tcb;
  441:         ER     ercd = E_OK;
  442: 
  443:         CHECK_MBFID(mbfid);
  444: 
  445:         mbfcb = get_mbfcb(mbfid);
  446: 
  447:         BEGIN_CRITICAL_SECTION;
  448:         if ( mbfcb->mbfid == 0 ) {
  449:                 ercd = E_NOEXS;
  450:         } else {
  451:                 pk_rmbf->exinf = mbfcb->exinf;
  452:                 pk_rmbf->wtsk = knl_wait_tskid(&mbfcb->recv_queue);
  453:                 pk_rmbf->stsk = knl_wait_tskid(&mbfcb->send_queue);
  454:                 if ( !knl_mbf_empty(mbfcb) ) {
  455:                         pk_rmbf->msgsz = *(HEADER*)&mbfcb->buffer[mbfcb->head];
  456:                 } else {
  457:                         if ( !isQueEmpty(&mbfcb->send_queue) ) {
  458:                                 tcb = (TCB*)mbfcb->send_queue.next;
  459:                                 pk_rmbf->msgsz = tcb->winfo.smbf.msgsz;
  460:                         } else {
  461:                                 pk_rmbf->msgsz = 0;
  462:                         }
  463:                 }
  464:                 pk_rmbf->frbufsz = mbfcb->frbufsz;
  465:                 pk_rmbf->maxmsz = mbfcb->maxmsz;
  466:         }
  467:         END_CRITICAL_SECTION;
  468: 
  469:         return ercd;
  470: }
  471: #endif /* USE_FUNC_TK_REF_MBF */
  472: 
  473: /* ------------------------------------------------------------------------ */
  474: /*
  475:  *      Debugger support function
  476:  */
  477: #if USE_DBGSPT
  478: 
  479: #if USE_OBJECT_NAME
  480: /*
  481:  * Get object name from control block
  482:  */
  483: EXPORT ER knl_messagebuffer_getname(ID id, UB **name)
  484: {
  485:         MBFCB  *mbfcb;
  486:         ER     ercd = E_OK;
  487: 
  488:         CHECK_MBFID(id);
  489: 
  490:         BEGIN_DISABLE_INTERRUPT;
  491:         mbfcb = get_mbfcb(id);
  492:         if ( mbfcb->mbfid == 0 ) {
  493:                 ercd = E_NOEXS;
  494:                 goto error_exit;
  495:         }
  496:         if ( (mbfcb->mbfatr & TA_DSNAME) == 0 ) {
  497:                 ercd = E_OBJ;
  498:                 goto error_exit;
  499:         }
  500:         *name = mbfcb->name;
  501: 
  502:     error_exit:
  503:         END_DISABLE_INTERRUPT;
  504: 
  505:         return ercd;
  506: }
  507: #endif /* USE_OBJECT_NAME */
  508: 
  509: #ifdef USE_FUNC_TD_LST_MBF
  510: /*
  511:  * Refer message buffer usage state
  512:  */
  513: SYSCALL INT td_lst_mbf( ID list[], INT nent )
  514: {
  515:         MBFCB  *mbfcb, *end;
  516:         INT    n = 0;
  517: 
  518:         BEGIN_DISABLE_INTERRUPT;
  519:         end = knl_mbfcb_table + NUM_MBFID;
  520:         for ( mbfcb = knl_mbfcb_table; mbfcb < end; mbfcb++ ) {
  521:                 if ( mbfcb->mbfid == 0 ) {
  522:                         continue;
  523:                 }
  524: 
  525:                 if ( n++ < nent ) {
  526:                         *list++ = mbfcb->mbfid;
  527:                 }
  528:         }
  529:         END_DISABLE_INTERRUPT;
  530: 
  531:         return n;
  532: }
  533: #endif /* USE_FUNC_TD_LST_MBF */
  534: 
  535: #ifdef USE_FUNC_TD_REF_MBF
  536: /*
  537:  * Refer message buffer state
  538:  */
  539: SYSCALL ER td_ref_mbf( ID mbfid, TD_RMBF *pk_rmbf )
  540: {
  541:         MBFCB  *mbfcb;
  542:         TCB    *tcb;
  543:         ER     ercd = E_OK;
  544: 
  545:         CHECK_MBFID(mbfid);
  546: 
  547:         mbfcb = get_mbfcb(mbfid);
  548: 
  549:         BEGIN_DISABLE_INTERRUPT;
  550:         if ( mbfcb->mbfid == 0 ) {
  551:                 ercd = E_NOEXS;
  552:         } else {
  553:                 pk_rmbf->exinf = mbfcb->exinf;
  554:                 pk_rmbf->wtsk = knl_wait_tskid(&mbfcb->recv_queue);
  555:                 pk_rmbf->stsk = knl_wait_tskid(&mbfcb->send_queue);
  556:                 if ( !knl_mbf_empty(mbfcb) ) {
  557:                         pk_rmbf->msgsz = *(HEADER*)&mbfcb->buffer[mbfcb->head];
  558:                 } else {
  559:                         if ( !isQueEmpty(&mbfcb->send_queue) ) {
  560:                                 tcb = (TCB*)mbfcb->send_queue.next;
  561:                                 pk_rmbf->msgsz = tcb->winfo.smbf.msgsz;
  562:                         } else {
  563:                                 pk_rmbf->msgsz = 0;
  564:                         }
  565:                 }
  566:                 pk_rmbf->frbufsz = mbfcb->frbufsz;
  567:                 pk_rmbf->maxmsz = mbfcb->maxmsz;
  568:         }
  569:         END_DISABLE_INTERRUPT;
  570: 
  571:         return ercd;
  572: }
  573: #endif /* USE_FUNC_TD_REF_MBF */
  574: 
  575: #ifdef USE_FUNC_TD_SMBF_QUE
  576: /*
  577:  * Refer message buffer send wait queue
  578:  */
  579: SYSCALL INT td_smbf_que( ID mbfid, ID list[], INT nent )
  580: {
  581:         MBFCB  *mbfcb;
  582:         QUEUE  *q;
  583:         ER     ercd = E_OK;
  584: 
  585:         CHECK_MBFID(mbfid);
  586: 
  587:         mbfcb = get_mbfcb(mbfid);
  588: 
  589:         BEGIN_DISABLE_INTERRUPT;
  590:         if ( mbfcb->mbfid == 0 ) {
  591:                 ercd = E_NOEXS;
  592:         } else {
  593:                 INT n = 0;
  594:                 for ( q = mbfcb->send_queue.next; q != &mbfcb->send_queue; q = q->next ) {
  595:                         if ( n++ < nent ) {
  596:                                 *list++ = ((TCB*)q)->tskid;
  597:                         }
  598:                 }
  599:                 ercd = n;
  600:         }
  601:         END_DISABLE_INTERRUPT;
  602: 
  603:         return ercd;
  604: }
  605: #endif /* USE_FUNC_TD_SMBF_QUE */
  606: 
  607: #ifdef USE_FUNC_TD_RMBF_QUE
  608: /*
  609:  * Refer message buffer receive wait queue
  610:  */
  611: SYSCALL INT td_rmbf_que( ID mbfid, ID list[], INT nent )
  612: {
  613:         MBFCB  *mbfcb;
  614:         QUEUE  *q;
  615:         ER     ercd = E_OK;
  616: 
  617:         CHECK_MBFID(mbfid);
  618: 
  619:         mbfcb = get_mbfcb(mbfid);
  620: 
  621:         BEGIN_DISABLE_INTERRUPT;
  622:         if ( mbfcb->mbfid == 0 ) {
  623:                 ercd = E_NOEXS;
  624:         } else {
  625:                 INT n = 0;
  626:                 for ( q = mbfcb->recv_queue.next; q != &mbfcb->recv_queue; q = q->next ) {
  627:                         if ( n++ < nent ) {
  628:                                 *list++ = ((TCB*)q)->tskid;
  629:                         }
  630:                 }
  631:                 ercd = n;
  632:         }
  633:         END_DISABLE_INTERRUPT;
  634: 
  635:         return ercd;
  636: }
  637: #endif /* USE_FUNC_TD_RMBF_QUE */
  638: 
  639: #endif /* USE_DBGSPT */
  640: #endif /* USE_MESSAGEBUFFER */