int ul_cbuff_tail_release(ul_cbuff_t *buff, ul_cbuff_tail_info_t *tail_info);
int ul_cbuff_tail_next(ul_cbuff_t *buff, ul_cbuff_tail_info_t *tail_info);
int ul_cbuff_tail_state_update(ul_cbuff_t *buff, int release_result, ul_cbuff_loc_t loc, ul_cbuff_loc_t loc_next);
+int ul_cbuff_tail_detach_onestep(ul_cbuff_t *buff, ul_cbuff_tail_info_t *tail_info);
void ul_cbuff_data_do_wrap(ul_cbuff_data_info_t *data_info);
int ul_cbuff_data_at_once(ul_cbuff_data_info_t *data_info, void **pptr, int size);
int ul_cbuff_put_data(ul_cbuff_data_info_t *data_info, const void *data, int size);
((ul_cbuff_msg_head_t *)(buff->buff_start+state->head))->flags=0;
+ flags&=~(UL_CBUFF_MSG_READY|UL_CBUFF_MSG_READERS);
+
put_info->msg_head->flags|=flags;
+ if(buff->state->readers>0)
+ put_info->msg_head->flags+=buff->state->readers;
+ else if (buff->state->readers==0)
+ put_info->msg_head->flags+=1;
+
put_info->msg_head->length=length;
return 0;
ul_cbuff_inline int
ul_cbuff_head_put(ul_cbuff_t *buff, ul_cbuff_put_info_t *put_info)
{
- if(buff->state->readers>0)
- put_info->msg_head->flags+=buff->state->readers;
ul_cbuff_mark_ready(put_info->msg_head);
put_info->msg_head=NULL;
return 0;
ul_cbuff_state_t *state=buff->state;
ul_cbuff_msg_head_t *msg_head;
- msg_head=(ul_cbuff_msg_head_t *)(buff->buff_start+state->head);
+ if(state->readers>0)
+ msg_head=(ul_cbuff_msg_head_t *)(buff->buff_start+state->head);
+ else if(state->readers==0)
+ msg_head=(ul_cbuff_msg_head_t *)(buff->buff_start+state->lasttail);
if(state->readers>=0)
state->readers++;
- if((state->readers<0)||(state->firsttail==state->head)){
- tail_info->msg_head=msg_head;
- tail_info->data.ptr=NULL;
- }else{
- /* There is already some message(s) write in progress */
- tail_info->msg_head=NULL;
- tail_info->msg_head->flags++;
- /* Some data fields are abused for ready condition checking */
- tail_info->data.ptr=(unsigned char*)msg_head;
- tail_info->data.wrap_ptr=buff->buff_start+state->firsttail;
- tail_info->data.wrap_len=state->cycles;
- }
+ tail_info->msg_head=msg_head;
+ tail_info->data.ptr=NULL;
return 0;
}
ul_cbuff_tail_incontact(ul_cbuff_t *buff, ul_cbuff_tail_info_t *tail_info)
{
if(tail_info->msg_head==NULL){
- unsigned char *new_firsttail=buff->buff_start+buff->state->firsttail;
- unsigned char *old_head=tail_info->data.ptr;
- unsigned char *old_firsttail=tail_info->data.wrap_ptr;
- unsigned int old_cycles=tail_info->data.wrap_len;
- unsigned int new_cycles=buff->state->cycles;
-
- if(old_firsttail<old_head){
- if((new_firsttail<old_head)&&(new_cycles==old_cycles))
- return 0;
- }else{
- if(new_cycles==old_cycles)
- return 0;
- if((new_firsttail<old_head)&&((new_cycles-old_cycles)==1))
- return 0;
- }
- tail_info->msg_head=(ul_cbuff_msg_head_t *)old_head;
- return 1;
+ return 0;
}
return 1;
}
}
}
+ul_cbuff_inline int
+ul_cbuff_tail_detach_onestep(ul_cbuff_t *buff, ul_cbuff_tail_info_t *tail_info)
+{
+ ul_cbuff_state_t *state=buff->state;
+ ul_cbuff_loc_t loc;
+ ul_cbuff_loc_t loc_next;
+ unsigned msg_readers;
+
+ if(tail_info->msg_head==NULL)
+ return 0;
+
+ loc = ul_cbuff_head_loc(buff, tail_info->msg_head);
+
+ if(loc!=state->head) {
+ if(!ul_cbuff_is_ready(tail_info->msg_head))
+ return 2;
+ msg_readers=tail_info->msg_head->flags&UL_CBUFF_MSG_READERS;
+ loc_next=ul_cbuff_next_loc(buff, tail_info->msg_head);
+ if(msg_readers)
+ tail_info->msg_head->flags--;
+ tail_info->msg_head=(ul_cbuff_msg_head_t *)(buff->buff_start+loc_next);
+ ul_cbuff_tail_state_update(buff, msg_readers<=1? 1: 0, loc, loc_next);
+ return 1;
+ }
+
+ if(state->readers>0)
+ state->readers--;
+ tail_info->msg_head=NULL;
+ tail_info->data.ptr=NULL;
+ return 0;
+}
+
+
ul_cbuff_inline void
ul_cbuff_data_do_wrap(ul_cbuff_data_info_t *data_info)
{