diff --git a/a8/fifobuffer.cc b/a8/fifobuffer.cc index dd4d8a5..c00b52a 100644 --- a/a8/fifobuffer.cc +++ b/a8/fifobuffer.cc @@ -10,6 +10,7 @@ const int BASE_BLOCK_SIZE = 128; struct BufHead { list_head entry; + int len; }; namespace a8 @@ -43,10 +44,9 @@ namespace a8 if (real_len > 1024 * 64) { return (char*)malloc(len); } else { - size_t index = GetIndex(real_len); - BufHead* buf_head = nullptr; { + size_t index = GetIndex(real_len); lock_.lock(); list_head* head = &free_list_[index]; if (!list_empty(head)) { @@ -54,15 +54,33 @@ namespace a8 list_del(&buf_head->entry); } lock_.unlock(); + if (buf_head) { + return (char*)buf_head + sizeof(BufHead); + } } - if (buf_head) { - return (char*)buf_head + sizeof(BufHead); + int p = offset_.fetch_add(len); + if (p > buf_len_) { + offset_.fetch_sub(len); + return (char*)malloc(len); } + buf_head = buf_ + p; + buf_head->len = len; + return buf_ + p + sizeof(BufHead); } } void FifoBuffer::Free(char* p) { + if (p > buf_ && p < buf_ + buf_len_) { + BufHead* buf_head = (BufHead*)(p - sizeof(BufHead)); + int real_len = sizeof(BufHead) + buf_head->len; + size_t index = GetIndex(real_len); + lock_.lock(); + list_add(&buf_head->entry, &free_list_[index]); + lock_.unlock(); + } else { + free(p); + } } size_t FifoBuffer::GetIndex(size_t size)