updated channel buffering code
This commit is contained in:
parent
0c5da297d0
commit
34c0ba457b
31
chan.c
31
chan.c
@ -57,10 +57,13 @@ int hip_chan_send(hip_chan_t* c, const void* ptr, hip_oow_t len)
|
||||
hip = c->hip;
|
||||
caller = UCTX_FROM_LINK(hip->running);
|
||||
|
||||
if (c->unit_count < c->unit_capa)
|
||||
if (HIP_LIST_IS_EMPTY(&c->recvq))
|
||||
{
|
||||
/* buffered */
|
||||
hip_uint8_t* dptr;
|
||||
|
||||
if (c->unit_count >= c->unit_capa) goto block;
|
||||
|
||||
/* the buffer is not full. write to the buffer */
|
||||
if (len > c->unit_size) len = c->unit_size; /* can't buffer longer than the specified unit size */
|
||||
dptr = &c->buf[c->unit_wpos * c->unit_size];
|
||||
memcpy(dptr, ptr, len);
|
||||
@ -71,10 +74,16 @@ int hip_chan_send(hip_chan_t* c, const void* ptr, hip_oow_t len)
|
||||
}
|
||||
c->unit_wpos = (c->unit_wpos + 1) % c->unit_capa;
|
||||
c->unit_count++;
|
||||
|
||||
/* give another routine a chance to read.
|
||||
* does this cause too many context switches?
|
||||
* without this, there is a high chance the the same routine
|
||||
* starves the channel by reading and writing in succession
|
||||
* if it read and write on the same channel */
|
||||
hip_yield(hip);
|
||||
return len;
|
||||
}
|
||||
|
||||
if (!HIP_LIST_IS_EMPTY(&c->recvq)) /* there is a receving routine */
|
||||
else /* there is a receiving routing waiting */
|
||||
{
|
||||
hip_uctx_link_t* x;
|
||||
hip_uctx_t* recver;
|
||||
@ -95,6 +104,7 @@ int hip_chan_send(hip_chan_t* c, const void* ptr, hip_oow_t len)
|
||||
}
|
||||
|
||||
|
||||
block:
|
||||
/* remember the data holder and places the current running routine in the send queue */
|
||||
caller->chan_data_ptr = (hip_uint8_t*)ptr;
|
||||
caller->chan_data_len = len;
|
||||
@ -115,16 +125,22 @@ int hip_chan_recv(hip_chan_t* c, void* ptr, hip_oow_t len)
|
||||
hip = c->hip;
|
||||
caller = UCTX_FROM_LINK(hip->running);
|
||||
|
||||
if (c->unit_count > 0)
|
||||
if (HIP_LIST_IS_EMPTY(&c->sendq))
|
||||
{
|
||||
if (c->unit_count <= 0) goto block;
|
||||
|
||||
/* the buffer is not empty. there's data to read */
|
||||
if (len > c->unit_size) len = c->unit_size;
|
||||
memcpy(ptr, &c->buf[c->unit_rpos * c->unit_size], len);
|
||||
c->unit_rpos = (c->unit_rpos + 1) % c->unit_capa;
|
||||
c->unit_count--;
|
||||
|
||||
/* In receiving, i doubt it causes starvation to not yield to another routine.
|
||||
* let me not switch to the scheduler here for now. */
|
||||
/*hip_yield(hip);*/
|
||||
return len;
|
||||
}
|
||||
|
||||
if (!HIP_LIST_IS_EMPTY(&c->sendq)) /* there is a sending routine */
|
||||
else /* there is a sending routine */
|
||||
{
|
||||
hip_uctx_link_t* x;
|
||||
hip_uctx_t* sener;
|
||||
@ -145,6 +161,7 @@ int hip_chan_recv(hip_chan_t* c, void* ptr, hip_oow_t len)
|
||||
return len;
|
||||
}
|
||||
|
||||
block:
|
||||
/* remember the data holder and place the calling routine in the receive queue */
|
||||
caller->chan_data_ptr = ptr;
|
||||
caller->chan_data_len = len;
|
||||
|
Loading…
x
Reference in New Issue
Block a user