gonzui


Format: Advanced Search

tkernel_2/kernel/tkernel/src/messagebuf.cbare sourcepermlink (0.08 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by T-Engine Forum at 2012/10/24.
   11:  *    Modified by T-Engine Forum at 2014/09/10.
   12:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   13:  *
   14:  *----------------------------------------------------------------------
   15:  */
   16: 
   17: /*
   18:  *      messagebuf.c (T-Kernel/OS)
   19:  *      Message Buffer
   20:  */
   21: 
   22: #include "kernel.h"
   23: #include "task.h"
   24: #include "wait.h"
   25: #include "check.h"
   26: #include <sys/rominfo.h>
   27: 
   28: #ifdef NUM_MBFID
   29: 
   30: EXPORT ID       max_mbfid;    /* Maximum message buffer ID */
   31: 
   32: /*
   33:  * Message buffer control block
   34:  *
   35:  *      Because Receive wait task (TTW_MBF) and Send wait task (TTW_SMBF)
   36:  *      do not co-exist for one message buffer, the wait queue may be
   37:  *      allowed to share.
   38:  *      However, when the size of message buffer is 0, it is difficult
   39:  *      to judge the wait queue if it is for receive or send,
   40:  *      therefore do not use this method.
   41:  */
   42: typedef struct messagebuffer_control_block {
   43:         QUEUE  send_queue;      /* Message buffer send wait queue */
   44:         ID     mbfid;              /* message buffer ID */
   45:         void   *exinf;           /* Extended information */
   46:         ATR    mbfatr;            /* Message buffer attribute */
   47:         QUEUE  recv_queue;      /* Message buffer receive wait queue */
   48:         INT    bufsz;             /* Message buffer size */
   49:         INT    maxmsz;            /* Maximum length of message */
   50:         INT    frbufsz;   /* Free buffer size */
   51:         INT    head;              /* First message store address */
   52:         INT    tail;              /* Next to the last message store address */
   53:         VB     *buffer;    /* Message buffer address */
   54: #if USE_OBJECT_NAME
   55:         UB     name[OBJECT_NAME_LENGTH];   /* name */
   56: #endif
   57: } MBFCB;
   58: 
   59: LOCAL MBFCB     *mbfcb_table;       /* Message buffer control block */
   60: LOCAL QUEUE     free_mbfcb; /* FreeQue */
   61: 
   62: #define get_mbfcb(id)   ( &mbfcb_table[INDEX_MBF(id)] )
   63: 
   64: 
   65: /*
   66:  * Initialization of message buffer control block
   67:  */
   68: EXPORT ER messagebuffer_initialize( void )
   69: {
   70:         MBFCB  *mbfcb, *end;
   71:         W      n;
   72: 
   73:         /* Get system information */
   74:         n = _tk_get_cfn(SCTAG_TMAXMBFID, &max_mbfid, 1);
   75:         if ( n < 1 || NUM_MBFID < 1 ) {
   76:                 return E_SYS;
   77:         }
   78: 
   79:         /* Create message buffer control block */
   80:         mbfcb_table = Imalloc((UINT)NUM_MBFID * sizeof(MBFCB));
   81:         if ( mbfcb_table == NULL ) {
   82:                 return E_NOMEM;
   83:         }
   84: 
   85:         /* Register all control blocks onto FreeQue */
   86:         QueInit(&free_mbfcb);
   87:         end = mbfcb_table + NUM_MBFID;
   88:         for ( mbfcb = mbfcb_table; mbfcb < end; mbfcb++ ) {
   89:                 mbfcb->mbfid = 0;
   90:                 QueInsert(&mbfcb->send_queue, &free_mbfcb);
   91:         }
   92: 
   93:         return E_OK;
   94: }
   95: 
   96: /* ------------------------------------------------------------------------ */
   97: 
   98: /*
   99:  * Message header format
  100:  */
  101: typedef INT             HEADER;
  102: #define HEADERSZ        (sizeof(HEADER))
  103: 
  104: #define ROUNDSIZE       (sizeof(HEADER))
  105: #define ROUNDSZ(sz)     (((UINT)(sz) + (ROUNDSIZE-1)) & ~(ROUNDSIZE-1))
  106: 
  107: /*
  108:  * Check message buffer free space
  109:  *      If 'msgsz' message is able to be stored, return TRUE.
  110:  */
  111: Inline BOOL mbf_free( MBFCB *mbfcb, INT msgsz )
  112: {
  113:         return ( HEADERSZ + (UINT)msgsz <= (UINT)mbfcb->frbufsz );
  114: }
  115: 
  116: /*
  117:  * If message buffer is empty, return TRUE.
  118:  */
  119: Inline BOOL mbf_empty( MBFCB *mbfcb )
  120: {
  121:         return ( mbfcb->frbufsz == mbfcb->bufsz );
  122: }
  123: 
  124: /*
  125:  * Store the message to message buffer.
  126:  */
  127: LOCAL void msg_to_mbf( MBFCB *mbfcb, CONST void *msg, INT msgsz )
  128: {
  129:         INT    tail = mbfcb->tail;
  130:         VB     *buffer = mbfcb->buffer;
  131:         INT    remsz;
  132: 
  133:         mbfcb->frbufsz -= (INT)(HEADERSZ + ROUNDSZ(msgsz));
  134: 
  135:         *(HEADER*)&buffer[tail] = msgsz;
  136:         tail += HEADERSZ;
  137:         if ( tail >= mbfcb->bufsz ) {
  138:                 tail = 0;
  139:         }
  140: 
  141:         if ( (remsz = mbfcb->bufsz - tail) < msgsz ) {
  142:                 MEMCPY(&buffer[tail], msg, (UINT)remsz);
  143:                 msg = (VB*)msg + remsz;
  144:                 msgsz -= remsz;
  145:                 tail = 0;
  146:         }
  147:         MEMCPY(&buffer[tail], msg, (UINT)msgsz);
  148:         tail += (INT)ROUNDSZ(msgsz);
  149:         if ( tail >= mbfcb->bufsz ) {
  150:                 tail = 0;
  151:         }
  152: 
  153:         mbfcb->tail = tail;
  154: }
  155: 
  156: /*
  157:  * Get a message from message buffer.
  158:  * Return the message size.
  159:  */
  160: LOCAL INT mbf_to_msg( MBFCB *mbfcb, void *msg )
  161: {
  162:         INT    head = mbfcb->head;
  163:         VB     *buffer = mbfcb->buffer;
  164:         INT    msgsz, actsz;
  165:         INT    remsz;
  166: 
  167:         actsz = msgsz = *(HEADER*)&buffer[head];
  168:         mbfcb->frbufsz += (INT)(HEADERSZ + ROUNDSZ(msgsz));
  169: 
  170:         head += (INT)HEADERSZ;
  171:         if ( head >= mbfcb->bufsz ) {
  172:                 head = 0;
  173:         }
  174: 
  175:         if ( (remsz = mbfcb->bufsz - head) < msgsz ) {
  176:                 MEMCPY(msg, &buffer[head], (UINT)remsz);
  177:                 msg = (VB*)msg + remsz;
  178:                 msgsz -= remsz;
  179:                 head = 0;
  180:         }
  181:         MEMCPY(msg, &buffer[head], (UINT)msgsz);
  182:         head += (INT)ROUNDSZ(msgsz);
  183:         if ( head >= mbfcb->bufsz ) {
  184:                 head = 0;
  185:         }
  186: 
  187:         mbfcb->head = head;
  188: 
  189:         return actsz;
  190: }
  191: 
  192: /* ------------------------------------------------------------------------ */
  193: 
  194: /*
  195:  * Accept message and release wait task,
  196:  * as long as there are free message area.
  197:  */
  198: LOCAL void mbf_wakeup( MBFCB *mbfcb )
  199: {
  200:         TCB    *top;
  201:         INT    msgsz;
  202: 
  203:         while ( !isQueEmpty(&mbfcb->send_queue) ) {
  204:                 top = (TCB*)mbfcb->send_queue.next;
  205:                 msgsz = top->winfo.smbf.msgsz;
  206:                 if ( !mbf_free(mbfcb, msgsz) ) {
  207:                         break;
  208:                 }
  209: 
  210:                 /* Store a message from waiting task and release it */
  211:                 msg_to_mbf(mbfcb, top->winfo.smbf.msg, msgsz);
  212:                 wait_release_ok(top);
  213:         }
  214: }
  215: 
  216: /*
  217:  * Processing if the priority of wait task changes
  218:  */
  219: LOCAL void mbf_chg_pri( TCB *tcb, INT oldpri )
  220: {
  221:         MBFCB  *mbfcb;
  222: 
  223:         mbfcb = get_mbfcb(tcb->wid);
  224:         if ( oldpri >= 0 ) {
  225:                 /* Reorder wait queue */
  226:                 gcb_change_priority((GCB*)mbfcb, tcb);
  227:         }
  228: 
  229:         /* If the new head task in a send wait queue is able to sent,
  230:            send its message */
  231:         mbf_wakeup(mbfcb);
  232: }
  233: 
  234: /*
  235:  * Processing if the wait task is released
  236:  */
  237: LOCAL void mbf_rel_wai( TCB *tcb )
  238: {
  239:         mbf_chg_pri(tcb, -1);
  240: }
  241: 
  242: /*
  243:  * Definition of message buffer wait specification
  244:  */
  245: LOCAL CONST WSPEC wspec_smbf_tfifo = { TTW_SMBF, NULL,  mbf_rel_wai };
  246: LOCAL CONST WSPEC wspec_smbf_tpri  = { TTW_SMBF, mbf_chg_pri,   mbf_rel_wai };
  247: LOCAL CONST WSPEC wspec_rmbf       = { TTW_RMBF, NULL,  NULL         };
  248: 
  249: 
  250: /*
  251:  * Create message buffer
  252:  */
  253: SYSCALL ID _tk_cre_mbf( CONST T_CMBF *pk_cmbf )
  254: {
  255: #if CHK_RSATR
  256:         const ATR VALID_MBFATR = {
  257:                  TA_TPRI
  258:                 |TA_NODISWAI
  259: #if USE_OBJECT_NAME
  260:                 |TA_DSNAME
  261: #endif
  262:         };
  263: #endif
  264:         MBFCB  *mbfcb;
  265:         ID     mbfid;
  266:         INT    bufsz;
  267:         VB     *msgbuf;
  268:         ER     ercd;
  269: 
  270:         CHECK_RSATR(pk_cmbf->mbfatr, VALID_MBFATR);
  271:         CHECK_PAR(pk_cmbf->bufsz >= 0);
  272:         CHECK_PAR(pk_cmbf->maxmsz > 0);
  273:         bufsz = (INT)ROUNDSZ(pk_cmbf->bufsz);
  274: 
  275:         if ( bufsz > 0 ) {
  276:                 msgbuf = Imalloc((UINT)bufsz);
  277:                 if ( msgbuf == NULL ) {
  278:                         return E_NOMEM;
  279:                 }
  280:         } else {
  281:                 msgbuf = NULL;
  282:         }
  283: 
  284:         BEGIN_CRITICAL_SECTION;
  285:         /* Get control block from FreeQue */
  286:         mbfcb = (MBFCB*)QueRemoveNext(&free_mbfcb);
  287:         if ( mbfcb == NULL ) {
  288:                 ercd = E_LIMIT;
  289:         } else {
  290:                 mbfid = ID_MBF(mbfcb - mbfcb_table);
  291: 
  292:                 /* Initialize control block */
  293:                 QueInit(&mbfcb->send_queue);
  294:                 mbfcb->mbfid = mbfid;
  295:                 mbfcb->exinf = pk_cmbf->exinf;
  296:                 mbfcb->mbfatr = pk_cmbf->mbfatr;
  297:                 QueInit(&mbfcb->recv_queue);
  298:                 mbfcb->buffer = msgbuf;
  299:                 mbfcb->bufsz = mbfcb->frbufsz = bufsz;
  300:                 mbfcb->maxmsz = pk_cmbf->maxmsz;
  301:                 mbfcb->head = mbfcb->tail = 0;
  302: #if USE_OBJECT_NAME
  303:                 if ( (pk_cmbf->mbfatr & TA_DSNAME) != 0 ) {
  304:                         STRNCPY((char*)mbfcb->name, (char*)pk_cmbf->dsname,
  305:                                 OBJECT_NAME_LENGTH);
  306:                 }
  307: #endif
  308:                 ercd = mbfid;
  309:         }
  310:         END_CRITICAL_SECTION;
  311: 
  312:         if ( ercd < E_OK && msgbuf != NULL ) {
  313:                 Ifree(msgbuf);
  314:         }
  315: 
  316:         return ercd;
  317: }
  318: 
  319: /*
  320:  * Delete message buffer
  321:  */
  322: SYSCALL ER _tk_del_mbf( ID mbfid )
  323: {
  324:         MBFCB  *mbfcb;
  325:         VB     *msgbuf = NULL;
  326:         ER     ercd = E_OK;
  327: 
  328:         CHECK_MBFID(mbfid);
  329: 
  330:         mbfcb = get_mbfcb(mbfid);
  331: 
  332:         BEGIN_CRITICAL_SECTION;
  333:         if ( mbfcb->mbfid == 0 ) {
  334:                 ercd = E_NOEXS;
  335:         } else {
  336:                 msgbuf = mbfcb->buffer;
  337: 
  338:                 /* Release wait state of task (E_DLT) */
  339:                 wait_delete(&mbfcb->recv_queue);
  340:                 wait_delete(&mbfcb->send_queue);
  341: 
  342:                 /* Return to FreeQue */
  343:                 QueInsert(&mbfcb->send_queue, &free_mbfcb);
  344:                 mbfcb->mbfid = 0;
  345:         }
  346:         END_CRITICAL_SECTION;
  347: 
  348:         if ( msgbuf != NULL ) {
  349:                 Ifree(msgbuf);
  350:         }
  351: 
  352:         return ercd;
  353: }
  354: 
  355: /*
  356:  * Send to message buffer
  357:  */
  358: SYSCALL ER _tk_snd_mbf( ID mbfid, CONST void *msg, INT msgsz, TMO tmout )
  359: {
  360:         return _tk_snd_mbf_u(mbfid, msg, msgsz, to_usec_tmo(tmout));
  361: }
  362: 
  363: SYSCALL ER _tk_snd_mbf_u( ID mbfid, CONST void *msg, INT msgsz, TMO_U tmout )
  364: {
  365:         MBFCB  *mbfcb;
  366:         TCB    *tcb;
  367:         ER     ercd = E_OK;
  368: 
  369:         CHECK_MBFID(mbfid);
  370:         CHECK_PAR(msgsz > 0);
  371:         CHECK_TMOUT(tmout);
  372:         CHECK_DISPATCH_POL(tmout);
  373: 
  374:         mbfcb = get_mbfcb(mbfid);
  375: 
  376:         BEGIN_CRITICAL_SECTION;
  377:         if ( mbfcb->mbfid == 0 ) {
  378:                 ercd = E_NOEXS;
  379:                 goto error_exit;
  380:         }
  381: #if CHK_PAR
  382:         if ( msgsz > mbfcb->maxmsz ) {
  383:                 ercd = E_PAR;
  384:                 goto error_exit;
  385:         }
  386: #endif
  387: 
  388:         /* Check send wait disable */
  389:         if ( !in_indp() && is_diswai((GCB*)mbfcb, ctxtsk, TTW_SMBF) ) {
  390:                 ercd = E_DISWAI;
  391:                 goto error_exit;
  392:         }
  393: 
  394:         if ( !isQueEmpty(&mbfcb->recv_queue) ) {
  395:                 /* Send directly to the receive wait task */
  396:                 tcb = (TCB*)mbfcb->recv_queue.next;
  397:                 MEMCPY(tcb->winfo.rmbf.msg, msg, (UINT)msgsz);
  398:                 *tcb->winfo.rmbf.p_msgsz = msgsz;
  399:                 wait_release_ok(tcb);
  400: 
  401:         } else if ( (in_indp() || gcb_top_of_wait_queue((GCB*)mbfcb, ctxtsk) == ctxtsk)
  402:                   &&(mbf_free(mbfcb, msgsz)) ) {
  403:                 /* Store the message to message buffer */
  404:                 msg_to_mbf(mbfcb, msg, msgsz);
  405: 
  406:         } else {
  407:                 ercd = E_TMOUT;
  408:                 if ( tmout != TMO_POL ) {
  409:                         /* Ready for send wait */
  410:                         ctxtsk->wspec = ( (mbfcb->mbfatr & TA_TPRI) != 0 )?
  411:                                         &wspec_smbf_tpri: &wspec_smbf_tfifo;
  412:                         ctxtsk->wercd = &ercd;
  413:                         ctxtsk->winfo.smbf.msg = msg;
  414:                         ctxtsk->winfo.smbf.msgsz = msgsz;
  415:                         gcb_make_wait_with_diswai((GCB*)mbfcb, tmout);
  416:                 }
  417:         }
  418: 
  419:     error_exit:
  420:         END_CRITICAL_SECTION;
  421: 
  422:         return ercd;
  423: }
  424: 
  425: /*
  426:  * Receive from message buffer
  427:  */
  428: SYSCALL INT _tk_rcv_mbf( ID mbfid, void *msg, TMO tmout )
  429: {
  430:         return _tk_rcv_mbf_u(mbfid, msg, to_usec_tmo(tmout));
  431: }
  432: 
  433: SYSCALL INT _tk_rcv_mbf_u( ID mbfid, void *msg, TMO_U tmout )
  434: {
  435:         MBFCB  *mbfcb;
  436:         TCB    *tcb;
  437:         INT    rcvsz;
  438:         ER     ercd = E_OK;
  439: 
  440:         CHECK_MBFID(mbfid);
  441:         CHECK_TMOUT(tmout);
  442:         CHECK_DISPATCH();
  443: 
  444:         mbfcb = get_mbfcb(mbfid);
  445: 
  446:         BEGIN_CRITICAL_SECTION;
  447:         if (mbfcb->mbfid == 0) {
  448:                 ercd = E_NOEXS;
  449:                 goto error_exit;
  450:         }
  451: 
  452:         /* Check receive wait disable */
  453:         if ( is_diswai((GCB*)mbfcb, ctxtsk, TTW_RMBF) ) {
  454:                 ercd = E_DISWAI;
  455:                 goto error_exit;
  456:         }
  457: 
  458:         if ( !mbf_empty(mbfcb) ) {
  459:                 /* Read from message buffer */
  460:                 rcvsz = mbf_to_msg(mbfcb, msg);
  461: 
  462:                 /* Accept message from sending task(s) */
  463:                 mbf_wakeup(mbfcb);
  464: 
  465:         } else if ( !isQueEmpty(&mbfcb->send_queue) ) {
  466:                 /* Receive directly from send wait task */
  467:                 tcb = (TCB*)mbfcb->send_queue.next;
  468:                 rcvsz = tcb->winfo.smbf.msgsz;
  469:                 MEMCPY(msg, tcb->winfo.smbf.msg, (UINT)rcvsz);
  470:                 wait_release_ok(tcb);
  471:                 mbf_wakeup(mbfcb);
  472:         } else {
  473:                 ercd = E_TMOUT;
  474:                 if ( tmout != TMO_POL ) {
  475:                         /* Ready for receive wait */
  476:                         ctxtsk->wspec = &wspec_rmbf;
  477:                         ctxtsk->wid = mbfid;
  478:                         ctxtsk->wercd = &ercd;
  479:                         ctxtsk->winfo.rmbf.msg = msg;
  480:                         ctxtsk->winfo.rmbf.p_msgsz = &rcvsz;
  481:                         make_wait(tmout, mbfcb->mbfatr);
  482:                         QueInsert(&ctxtsk->tskque, &mbfcb->recv_queue);
  483:                 }
  484:         }
  485: 
  486:     error_exit:
  487:         END_CRITICAL_SECTION;
  488: 
  489:         return ( ercd < E_OK )? ercd: rcvsz;
  490: }
  491: 
  492: /*
  493:  * Refer message buffer state
  494:  */
  495: SYSCALL ER _tk_ref_mbf( ID mbfid, T_RMBF *pk_rmbf )
  496: {
  497:         MBFCB  *mbfcb;
  498:         TCB    *tcb;
  499:         ER     ercd = E_OK;
  500: 
  501:         CHECK_MBFID(mbfid);
  502: 
  503:         mbfcb = get_mbfcb(mbfid);
  504: 
  505:         BEGIN_CRITICAL_SECTION;
  506:         if ( mbfcb->mbfid == 0 ) {
  507:                 ercd = E_NOEXS;
  508:         } else {
  509:                 pk_rmbf->exinf = mbfcb->exinf;
  510:                 pk_rmbf->wtsk = wait_tskid(&mbfcb->recv_queue);
  511:                 pk_rmbf->stsk = wait_tskid(&mbfcb->send_queue);
  512:                 if ( !mbf_empty(mbfcb) ) {
  513:                         pk_rmbf->msgsz = *(HEADER*)&mbfcb->buffer[mbfcb->head];
  514:                 } else {
  515:                         if ( !isQueEmpty(&mbfcb->send_queue) ) {
  516:                                 tcb = (TCB*)mbfcb->send_queue.next;
  517:                                 pk_rmbf->msgsz = tcb->winfo.smbf.msgsz;
  518:                         } else {
  519:                                 pk_rmbf->msgsz = 0;
  520:                         }
  521:                 }
  522:                 pk_rmbf->frbufsz = mbfcb->frbufsz;
  523:                 pk_rmbf->maxmsz = mbfcb->maxmsz;
  524:         }
  525:         END_CRITICAL_SECTION;
  526: 
  527:         return ercd;
  528: }
  529: 
  530: /* ------------------------------------------------------------------------ */
  531: /*
  532:  *      Debugger support function
  533:  */
  534: #if USE_DBGSPT
  535: 
  536: /*
  537:  * Get object name from control block
  538:  */
  539: #if USE_OBJECT_NAME
  540: EXPORT ER messagebuffer_getname(ID id, UB **name)
  541: {
  542:         MBFCB  *mbfcb;
  543:         ER     ercd = E_OK;
  544: 
  545:         CHECK_MBFID(id);
  546: 
  547:         BEGIN_DISABLE_INTERRUPT;
  548:         mbfcb = get_mbfcb(id);
  549:         if ( mbfcb->mbfid == 0 ) {
  550:                 ercd = E_NOEXS;
  551:                 goto error_exit;
  552:         }
  553:         if ( (mbfcb->mbfatr & TA_DSNAME) == 0 ) {
  554:                 ercd = E_OBJ;
  555:                 goto error_exit;
  556:         }
  557:         *name = mbfcb->name;
  558: 
  559:     error_exit:
  560:         END_DISABLE_INTERRUPT;
  561: 
  562:         return ercd;
  563: }
  564: #endif /* USE_OBJECT_NAME */
  565: 
  566: /*
  567:  * Refer message buffer usage state
  568:  */
  569: SYSCALL INT _td_lst_mbf( ID list[], INT nent )
  570: {
  571:         MBFCB  *mbfcb, *end;
  572:         INT    n = 0;
  573: 
  574:         BEGIN_DISABLE_INTERRUPT;
  575:         end = mbfcb_table + NUM_MBFID;
  576:         for ( mbfcb = mbfcb_table; mbfcb < end; mbfcb++ ) {
  577:                 if ( mbfcb->mbfid == 0 ) {
  578:                         continue;
  579:                 }
  580: 
  581:                 if ( n++ < nent ) {
  582:                         *list++ = mbfcb->mbfid;
  583:                 }
  584:         }
  585:         END_DISABLE_INTERRUPT;
  586: 
  587:         return n;
  588: }
  589: 
  590: /*
  591:  * Refer message buffer state
  592:  */
  593: SYSCALL ER _td_ref_mbf( ID mbfid, TD_RMBF *pk_rmbf )
  594: {
  595:         MBFCB  *mbfcb;
  596:         TCB    *tcb;
  597:         ER     ercd = E_OK;
  598: 
  599:         CHECK_MBFID(mbfid);
  600: 
  601:         mbfcb = get_mbfcb(mbfid);
  602: 
  603:         BEGIN_DISABLE_INTERRUPT;
  604:         if ( mbfcb->mbfid == 0 ) {
  605:                 ercd = E_NOEXS;
  606:         } else {
  607:                 pk_rmbf->exinf = mbfcb->exinf;
  608:                 pk_rmbf->wtsk = wait_tskid(&mbfcb->recv_queue);
  609:                 pk_rmbf->stsk = wait_tskid(&mbfcb->send_queue);
  610:                 if ( !mbf_empty(mbfcb) ) {
  611:                         pk_rmbf->msgsz = *(HEADER*)&mbfcb->buffer[mbfcb->head];
  612:                 } else {
  613:                         if ( !isQueEmpty(&mbfcb->send_queue) ) {
  614:                                 tcb = (TCB*)mbfcb->send_queue.next;
  615:                                 pk_rmbf->msgsz = tcb->winfo.smbf.msgsz;
  616:                         } else {
  617:                                 pk_rmbf->msgsz = 0;
  618:                         }
  619:                 }
  620:                 pk_rmbf->frbufsz = mbfcb->frbufsz;
  621:                 pk_rmbf->maxmsz = mbfcb->maxmsz;
  622:         }
  623:         END_DISABLE_INTERRUPT;
  624: 
  625:         return ercd;
  626: }
  627: 
  628: /*
  629:  * Refer message buffer send wait queue
  630:  */
  631: SYSCALL INT _td_smbf_que( ID mbfid, ID list[], INT nent )
  632: {
  633:         MBFCB  *mbfcb;
  634:         QUEUE  *q;
  635:         ER     ercd = E_OK;
  636: 
  637:         CHECK_MBFID(mbfid);
  638: 
  639:         mbfcb = get_mbfcb(mbfid);
  640: 
  641:         BEGIN_DISABLE_INTERRUPT;
  642:         if ( mbfcb->mbfid == 0 ) {
  643:                 ercd = E_NOEXS;
  644:         } else {
  645:                 INT n = 0;
  646:                 for ( q = mbfcb->send_queue.next; q != &mbfcb->send_queue; q = q->next ) {
  647:                         if ( n++ < nent ) {
  648:                                 *list++ = ((TCB*)q)->tskid;
  649:                         }
  650:                 }
  651:                 ercd = n;
  652:         }
  653:         END_DISABLE_INTERRUPT;
  654: 
  655:         return ercd;
  656: }
  657: 
  658: /*
  659:  * Refer message buffer receive wait queue
  660:  */
  661: SYSCALL INT _td_rmbf_que( ID mbfid, ID list[], INT nent )
  662: {
  663:         MBFCB  *mbfcb;
  664:         QUEUE  *q;
  665:         ER     ercd = E_OK;
  666: 
  667:         CHECK_MBFID(mbfid);
  668: 
  669:         mbfcb = get_mbfcb(mbfid);
  670: 
  671:         BEGIN_DISABLE_INTERRUPT;
  672:         if ( mbfcb->mbfid == 0 ) {
  673:                 ercd = E_NOEXS;
  674:         } else {
  675:                 INT n = 0;
  676:                 for ( q = mbfcb->recv_queue.next; q != &mbfcb->recv_queue; q = q->next ) {
  677:                         if ( n++ < nent ) {
  678:                                 *list++ = ((TCB*)q)->tskid;
  679:                         }
  680:                 }
  681:                 ercd = n;
  682:         }
  683:         END_DISABLE_INTERRUPT;
  684: 
  685:         return ercd;
  686: }
  687: 
  688: #endif /* USE_DBGSPT */
  689: #endif /* NUM_MBFID */