BQUEUE.C
资源名称:ertos.rar [点击查看]
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:7k
源码类别:
操作系统开发
开发平台:
DOS
- //#define OLD
- #define NEW
- #define NEWEST
- /*
- * bqueue.c - BYTE queue for serial/parallel interfacing
- * Copyright (c) 1990, 1999 Erick Engelke
- */
- #include <stdio.h>
- #include "rtos.h"
- void bq_msg( bq_str *bq, int type )
- {
- if ( type == EMSG_BQ_WAITING ) bq->bq_msg_waiting = kcurthread;
- if ( type == EMSG_BQ_AVAIL ) bq->bq_msg_avail = kcurthread;
- /* start a siphon */
- if ( bq->bq_msg_waiting && (bq->bq_head != bq->bq_tail))
- ksendmessage( bq->bq_msg_waiting, EMSG_BQ_WAITING, 0 );
- else
- ksendmessage( bq->bq_msg_avail, EMSG_BQ_AVAIL, 0 );
- }
- bq_str *bq_alloc( int queuesize )
- {
- bq_str *b;
- BYTE *p;
- p = kcalloc( queuesize, 1 );
- if ( p == NULL ) return( NULL );
- b = kcalloc( sizeof( bq_str ), 1 );
- if ( b == NULL ) {
- kfree( p );
- return( NULL );
- }
- b->bq_size = queuesize;
- b->bq_queue = p;
- b->bq_head = 0;
- b->bq_tail = 0;
- b->bq_sendwait = NULL;
- b->bq_recvwait = NULL;
- b->bq_msg_waiting = NULL;
- b->bq_msg_avail = NULL;
- return( b );
- }
- void bq_free( bq_str *bq )
- {
- kfree( bq->bq_queue );
- kfree( bq );
- }
- /*
- * bq_semdbyte - nonblock write of BYTE, does not detect buffer overflow
- */
- void bq_sendbyte( bq_str *bq, BYTE b )
- {
- WORD i;
- WORD flags, newhead;
- thread_x *t;
- rt_cpu_block( &flags );
- i = bq->bq_head;
- bq->bq_queue[ i ] = b;
- newhead = ( i + 1 ) % bq->bq_size;
- rt_cpu_unblock( &flags );
- if ( newhead == bq->bq_tail ) return; /* no room */
- bq->bq_head = newhead;
- /* time to poke receiver if he is waiting */
- if ( bq->bq_head != bq->bq_tail ) {
- if ( bq->bq_msg_waiting )
- ksendmessage( bq->bq_msg_waiting, EMSG_BQ_WAITING, 0 );
- rt_cpu_block( &flags );
- if ( (t = bq->bq_recvwait) != NULL ) {
- #ifdef NEW
- bq->bq_recvwait = NULL;
- t->th_bq = NULL;
- ksendmessage( t , EMSG_BQ_WAITING , 0 );
- rt_cpu_unblock( &flags );
- #else
- bq->bq_recvwait = NULL;
- t->th_bq = NULL;
- kresume( t );
- rt_cpu_unblock( &flags );
- #endif
- return;
- }
- rt_cpu_unblock( &flags );
- }
- }
- /*
- * bq_getbyte - nonblock read of BYTE
- * - returns 1 if a byte is available
- */
- int bq_getbyte( bq_str *bq, BYTE *b )
- {
- WORD i, flags, newtail;
- thread_x *t;
- rt_cpu_block( &flags );
- i = bq->bq_tail;
- if ( i != bq->bq_head ) {
- *b = bq->bq_queue[ i ];
- newtail = i + 1;
- if ( newtail == bq->bq_size ) newtail = 0;
- bq->bq_tail = newtail;
- rt_cpu_unblock( &flags );
- /* time to poke sender if he is waiting */
- rt_cpu_block( &flags );
- if (( t = bq->bq_sendwait) != NULL ) {
- #ifdef NEW
- bq->bq_sendwait = NULL;
- t->th_bq = NULL;
- ksendmessage( t, EMSG_BQ_AVAIL, 0 );
- #else
- bq->bq_sendwait = NULL;
- t->th_bq = NULL;
- kresume( t );
- #endif
- }
- rt_cpu_unblock( &flags );
- /* inform peer it can write more */
- if ( bq->bq_msg_avail )
- ksendmessage( bq->bq_msg_avail, EMSG_BQ_AVAIL, 0 );
- return( 1 );
- }
- rt_cpu_unblock( &flags );
- return( 0 );
- }
- /*
- * bq_writebyte - block write of BYTE, does not allow buffer overflow
- */
- void bq_writebyte( bq_str *bq, BYTE b )
- {
- WORD newhead, head, tail, size, flags;
- thread_x *t;
- size = bq->bq_size;
- do {
- rt_cpu_block( &flags );
- head = bq->bq_head;
- tail = bq->bq_tail;
- rt_cpu_unblock( &flags );
- newhead = head + 1;
- if ( newhead == size ) newhead = 0;
- /* we block if tail was where we want to move into */
- if ( newhead != tail ) break;
- #ifdef OLD
- rt_sleep(0);
- #else
- #ifdef NEW
- rt_cpu_block( &flags );
- kcurthread->th_bq = bq;
- bq->bq_sendwait = kcurthread;
- rt_cpu_unblock( &flags );
- #ifdef NEWEST
- kreadspecialmessage( EMSG_BQ_AVAIL );
- bq->bq_sendwait = NULL; /* clear the messaging requirement */
- #else // just NEW
- {
- int msg;
- DWORD data;
- kreadmessage( &msg, &data );
- }
- #endif // NEWEST
- #else
- #error fails
- rt_cpu_block( &flags );
- kcurthread->th_bq = bq;
- ksuspendhow( kcurthread, &bq->bq_sendwait );
- rt_cpu_unblock( &flags );
- rt_yield();
- #endif
- #endif
- } while ( 1 );
- /* don't need to block interrupts because orderred correctly */
- bq->bq_queue[ head ] = b;
- bq->bq_head = newhead;
- /* inform peer */
- if ( bq->bq_msg_waiting )
- ksendmessage( bq->bq_msg_waiting, EMSG_BQ_WAITING, 0 );
- rt_cpu_block( &flags );
- if (( t = bq->bq_recvwait) != NULL ) {
- #ifdef NEW
- bq->bq_recvwait = NULL;
- t->th_bq = NULL;
- ksendmessage( t , EMSG_BQ_WAITING , 0 );
- #else
- bq->bq_recvwait = NULL;
- t->th_bq = NULL;
- kresume( t );
- #endif
- }
- rt_cpu_unblock( &flags );
- }
- /*
- * bq_readbyte - block of read of BYTE
- */
- int bq_readbyte( bq_str *bq, BYTE *b )
- {
- WORD head, tail, size;
- WORD flags;
- size = bq->bq_size;
- rt_cpu_block( &flags );
- do {
- tail = bq->bq_tail;
- head = bq->bq_head;
- if ( tail != head ) {
- *b = bq->bq_queue[ tail++ ];
- bq->bq_tail = tail % size;
- rt_cpu_unblock( &flags );
- /* inform peer it can write more */
- if ( bq->bq_msg_avail )
- ksendmessage( bq->bq_msg_avail, EMSG_BQ_AVAIL, 0 );
- if ( bq->bq_sendwait )
- ksendmessage( bq->bq_sendwait, EMSG_BQ_AVAIL, 0 );
- return( 1 );
- }
- rt_cpu_unblock( &flags );
- #ifdef OLD
- rt_sleep( 0 );
- #else
- #ifdef NEW
- rt_cpu_block( &flags );
- kcurthread->th_bq = bq;
- bq->bq_recvwait = kcurthread;
- rt_cpu_unblock( &flags );
- #ifdef NEWEST
- kreadspecialmessage( EMSG_BQ_WAITING );
- #else // just NEW
- {
- int msg;
- DWORD data;
- kreadmessage( &msg, &data );
- }
- #endif // NEWEST
- #else
- #error fails
- rt_cpu_block( &flags );
- kcurthread->th_bq = bq;
- // bq->bq_recvwait = kcurthread;
- ksuspendhow( kcurthread, &bq->bq_recvwait );
- rt_cpu_unblock( &flags );
- rt_yield();
- #endif
- #endif
- } while ( 1 );
- }
- /*
- * bq_readcount - returns number of BYTEs left to read
- * - not async
- */
- WORD bq_readcount( bq_str *bq )
- {
- WORD i;
- WORD flags;
- rt_cpu_block( &flags );
- i = bq->bq_tail;
- if ( bq->bq_head == i )
- i = 0;
- else if ( bq->bq_head > i )
- i = bq->bq_head - i;
- else
- i = bq->bq_size - i + bq->bq_head;
- rt_cpu_unblock( &flags );
- return( i );
- }