📄 buf.c
字号:
assert(data); /* Find the acc we need to modify. */ new_acc= data; while(offset >= new_acc->acc_length) { offset -= new_acc->acc_length; new_acc= new_acc->acc_next;#ifdef BUF_TRACK_ALLOC_FREE assert(new_acc || (printf("called from %s, %d\n", clnt_file, clnt_line),0));#else assert(new_acc);#endif } /* Discard the old acc(s) */ if (new_acc != data) { new_acc->acc_linkC++; bf_afree(data); data= new_acc; } /* Make sure that acc_linkC == 1 */ if (data->acc_linkC != 1) { new_acc= bf_dupacc(data); bf_afree(data); data= new_acc; } /* Delete the last bit by modifying acc_offset and acc_length */ data->acc_offset += offset; data->acc_length -= offset; return data;}/*bf_append*/#ifndef BUF_TRACK_ALLOC_FREEPUBLIC acc_t *bf_append(data_first, data_second)#elsePUBLIC acc_t *_bf_append(clnt_file, clnt_line, data_first, data_second)char *clnt_file;int clnt_line;#endifacc_t *data_first;acc_t *data_second;{ acc_t *head, *tail, *new_acc, *acc_ptr_new, tmp_acc, *curr; char *src_ptr, *dst_ptr; size_t size, offset_old, offset_new, block_size_old, block_size; if (!data_first) return data_second; if (!data_second) return data_first; head= NULL; tail= NULL; while (data_first) { if (data_first->acc_linkC == 1) curr= data_first; else { curr= bf_dupacc(data_first); assert (curr->acc_linkC == 1); bf_afree(data_first); } data_first= curr->acc_next; if (!curr->acc_length) { curr->acc_next= NULL; bf_afree(curr); continue; } if (!head) head= curr; else tail->acc_next= curr; tail= curr; } if (!head) return data_second; tail->acc_next= NULL; while (data_second && !data_second->acc_length) { curr= data_second; data_second= data_second->acc_next; if (data_second) data_second->acc_linkC++; bf_afree(curr); } if (!data_second) return head; if (tail->acc_length + data_second->acc_length > tail->acc_buffer->buf_size) { tail->acc_next= data_second; return head; } if (tail->acc_buffer->buf_size == bf_buf_gran && tail->acc_buffer->buf_linkC == 1) { if (tail->acc_offset) { memmove(tail->acc_buffer->buf_data_p, ptr2acc_data(tail), tail->acc_length); tail->acc_offset= 0; } dst_ptr= ptr2acc_data(tail) + tail->acc_length; src_ptr= ptr2acc_data(data_second); memcpy(dst_ptr, src_ptr, data_second->acc_length); tail->acc_length += data_second->acc_length; tail->acc_next= data_second->acc_next; if (data_second->acc_next) data_second->acc_next->acc_linkC++; bf_afree(data_second); return head; } new_acc= bf_small_memreq(tail->acc_length+data_second->acc_length); acc_ptr_new= new_acc; offset_old= 0; offset_new= 0; size= tail->acc_length; while (size) {assert (acc_ptr_new); if (offset_new == acc_ptr_new->acc_length) { offset_new= 0; acc_ptr_new= acc_ptr_new->acc_next; continue; }assert (offset_new < acc_ptr_new->acc_length);assert (offset_old < tail->acc_length); block_size_old= tail->acc_length - offset_old; block_size= acc_ptr_new->acc_length - offset_new; if (block_size > block_size_old) block_size= block_size_old; memcpy(ptr2acc_data(acc_ptr_new)+offset_new, ptr2acc_data(tail)+offset_old, block_size); offset_new += block_size; offset_old += block_size; size -= block_size; } offset_old= 0; size= data_second->acc_length; while (size) {assert (acc_ptr_new); if (offset_new == acc_ptr_new->acc_length) { offset_new= 0; acc_ptr_new= acc_ptr_new->acc_next; continue; }assert (offset_new < acc_ptr_new->acc_length);assert (offset_old < data_second->acc_length); block_size_old= data_second->acc_length - offset_old; block_size= acc_ptr_new->acc_length - offset_new; if (block_size > block_size_old) block_size= block_size_old; memcpy(ptr2acc_data(acc_ptr_new)+offset_new, ptr2acc_data(data_second)+offset_old, block_size); offset_new += block_size; offset_old += block_size; size -= block_size; } tmp_acc= *tail; *tail= *new_acc; *new_acc= tmp_acc; bf_afree(new_acc); while (tail->acc_next) tail= tail->acc_next; tail->acc_next= data_second->acc_next; if (data_second->acc_next) data_second->acc_next->acc_linkC++; bf_afree(data_second); return head;}#if BUF512_NRPRIVATE void bf_512free(acc)acc_t *acc;{#ifdef BUF_CONSISTENCY_CHECK if (inet_buf_debug) memset(acc->acc_buffer->buf_data_p, 0xa5, 512);#endif acc->acc_next= buf512_freelist; buf512_freelist= acc;}#endif#if BUF2K_NRPRIVATE void bf_2Kfree(acc)acc_t *acc;{#ifdef BUF_CONSISTENCY_CHECK if (inet_buf_debug) memset(acc->acc_buffer->buf_data_p, 0xa5, 2*1024);#endif acc->acc_next= buf2K_freelist; buf2K_freelist= acc;}#endif#if BUF32K_NRPRIVATE void bf_32Kfree(acc)acc_t *acc;{#ifdef BUF_CONSISTENCY_CHECK if (inet_buf_debug) memset(acc->acc_buffer->buf_data_p, 0xa5, 32*1024);#endif acc->acc_next= buf32K_freelist; buf32K_freelist= acc;}#endif#ifdef BUF_CONSISTENCY_CHECKPUBLIC int bf_consistency_check(){ acc_t *acc; int silent; int error; int i; buf_generation++; for (i=0; i<CLIENT_NR; i++) { if (checkreq[i]) (*checkreq[i])(); } /* Add information about free accessors */ for(acc= acc_freelist; acc; acc= acc->acc_next) { if (acc->acc_generation == buf_generation-1) { acc->acc_generation= buf_generation; acc->acc_check_linkC= 0; } else { assert(acc->acc_generation == buf_generation && acc->acc_check_linkC > 0); acc->acc_check_linkC= -acc->acc_check_linkC; } }#if BUF512_NR count_free_bufs(buf512_freelist);#endif#if BUF2K_NR count_free_bufs(buf2K_freelist);#endif#if BUF32K_NR count_free_bufs(buf32K_freelist);#endif error= 0; /* Report about accessors */ silent= 0; for (i=0, acc= accessors; i<ACC_NR; i++, acc++) { if (acc->acc_generation != buf_generation) { error++; assert(acc->acc_generation == buf_generation-1); acc->acc_generation= buf_generation; if (!silent) { printf("acc[%d] (%p) has been lost with count %d, last allocated at %s, %d\n", i, acc, acc->acc_linkC, acc->acc_alloc_file, acc->acc_alloc_line);#if 0 silent= 1;#endif } continue; } if (acc->acc_check_linkC == acc->acc_linkC) continue; error++; if (acc->acc_check_linkC < 0) { if (!silent) { printf("acc[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n", i, acc->acc_alloc_file, acc->acc_alloc_line, acc->acc_free_file, acc->acc_free_line); } acc->acc_check_linkC= -acc->acc_check_linkC; if (acc->acc_check_linkC == acc->acc_linkC) { silent= 1; continue; } } if (!silent) { printf("# of tracked links (%d) for acc[%d] don't match with stored link count %d\n", acc->acc_check_linkC, i, acc->acc_linkC); printf("acc[%d] was allocated at %s, %d\n", i, acc->acc_alloc_file, acc->acc_alloc_line); silent=1; } } /* Report about buffers */#if BUF512_NR { for (i= 0; i<BUF512_NR; i++) { error |= report_buffer(&buffers512[i].buf_header, "512-buffer", i); } }#endif#if BUF2K_NR { for (i= 0; i<BUF2K_NR; i++) { error |= report_buffer(&buffers2K[i].buf_header, "2K-buffer", i); } }#endif#if BUF32K_NR { for (i= 0; i<BUF32K_NR; i++) { error |= report_buffer(&buffers32K[i].buf_header, "32K-buffer", i); } }#endif return !error;}PRIVATE void count_free_bufs(list)acc_t *list;{ acc_t *acc; buf_t *buf; for(acc= list; acc; acc= acc->acc_next) { if (acc->acc_generation != buf_generation-1) { assert(acc->acc_generation == buf_generation && acc->acc_check_linkC > 0); acc->acc_check_linkC= -acc->acc_check_linkC; continue; } acc->acc_generation= buf_generation; acc->acc_check_linkC= 0; buf= acc->acc_buffer; if (buf->buf_generation == buf_generation-1) { buf->buf_generation= buf_generation; buf->buf_check_linkC= 0; continue; } assert(buf->buf_generation == buf_generation && buf->buf_check_linkC > 0); buf->buf_check_linkC= -buf->buf_check_linkC; }}PRIVATE int report_buffer(buf, label, i)buf_t *buf;char *label;int i;{ if (buf->buf_generation != buf_generation) { assert(buf->buf_generation == buf_generation-1); buf->buf_generation= buf_generation; printf("%s[%d] (%p) has been lost with count %d, last allocated at %s, %d\n", label, i, buf, buf->buf_linkC, buf->buf_alloc_file, buf->buf_alloc_line); return 1; } if (buf->buf_check_linkC == buf->buf_linkC) return 0; if (buf->buf_check_linkC < 0) { printf("%s[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n", label, i, buf->buf_alloc_file, buf->buf_alloc_line, buf->buf_free_file, buf->buf_free_line); buf->buf_check_linkC= -buf->buf_check_linkC; if (buf->buf_check_linkC == buf->buf_linkC) return 1; } printf("# of tracked links (%d) for %s[%d] don't match with stored link count %d\n", buf->buf_check_linkC, label, i, buf->buf_linkC); printf("%s[%d] was allocated at %s, %d\n", label, i, buf->buf_alloc_file, buf->buf_alloc_line); return 1;}PUBLIC void bf_check_acc(acc)acc_t *acc;{ buf_t *buf; while(acc != NULL) { if (acc->acc_generation == buf_generation) { assert(acc->acc_check_linkC > 0); acc->acc_check_linkC++; return; } assert(acc->acc_generation == buf_generation-1); acc->acc_generation= buf_generation; acc->acc_check_linkC= 1; buf= acc->acc_buffer; if (buf->buf_generation == buf_generation) { assert(buf->buf_check_linkC > 0); buf->buf_check_linkC++; } else { assert(buf->buf_generation == buf_generation-1); buf->buf_generation= buf_generation; buf->buf_check_linkC= 1; } acc= acc->acc_next; }}PUBLIC void _bf_mark_1acc(clnt_file, clnt_line, acc)char *clnt_file;int clnt_line;acc_t *acc;{ acc->acc_alloc_file= clnt_file; acc->acc_alloc_line= clnt_line;}PUBLIC void _bf_mark_acc(clnt_file, clnt_line, acc)char *clnt_file;int clnt_line;acc_t *acc;{ buf_t *buf; for (; acc; acc= acc->acc_next) { acc->acc_alloc_file= clnt_file; acc->acc_alloc_line= clnt_line; buf= acc->acc_buffer; buf->buf_alloc_file= clnt_file; buf->buf_alloc_line= clnt_line; }}#endifPUBLIC int bf_linkcheck(acc)acc_t *acc;{ int i; buf_t *buffer; for (i= 0; i<ACC_NR && acc; i++, acc= acc->acc_next) { if (acc->acc_linkC <= 0) { printf("wrong acc_linkC (%d) for acc %p\n", acc->acc_linkC, acc); return 0; } if (acc->acc_offset < 0) { printf("wrong acc_offset (%d) for acc %p\n", acc->acc_offset, acc); return 0; } if (acc->acc_length < 0) { printf("wrong acc_length (%d) for acc %p\n", acc->acc_length, acc); return 0; } buffer= acc->acc_buffer; if (buffer == NULL) { printf("no buffer for acc %p\n", acc); return 0; } if (buffer->buf_linkC <= 0) { printf( "wrong buf_linkC (%d) for buffer %p, from acc %p\n", buffer->buf_linkC, buffer, acc); return 0; } if (acc->acc_offset + acc->acc_length > buffer->buf_size) { printf("%d + %d > %d for buffer %p, and acc %p\n", acc->acc_offset, acc->acc_length, buffer->buf_size, buffer, acc); return 0; } } if (acc != NULL) { printf("loop\n"); return 0; } return 1;}PRIVATE void free_accs(){ int i, j; DBLOCK(1, printf("free_accs\n"));assert(bf_linkcheck(bf_linkcheck_acc)); for (i=0; !acc_freelist && i<MAX_BUFREQ_PRI; i++) { for (j=0; j<CLIENT_NR; j++) { bf_free_bufsize= 0; if (freereq[j]) { (*freereq[j])(i); assert(bf_linkcheck(bf_linkcheck_acc) || (printf("just called %p\n", freereq[i]),0)); } } }#if DEBUG printf("last level was level %d\n", i-1);#endif}#ifndef BUF_TRACK_ALLOC_FREEPUBLIC acc_t *bf_align(acc, size, alignment)#elsePUBLIC acc_t *_bf_align(clnt_file, clnt_line, acc, size, alignment)char *clnt_file;int clnt_line;#endifacc_t *acc;size_t size;size_t alignment;{ char *ptr; size_t buf_size; acc_t *head, *tail; /* Fast check if the buffer is aligned already. */ if (acc->acc_length >= size) { ptr= ptr2acc_data(acc); if (((unsigned)ptr & (alignment-1)) == 0) return acc; } buf_size= bf_bufsize(acc);#ifdef bf_align assert((size != 0 && buf_size != 0) || (printf("bf_align(..., %d, %d) from %s, %d\n", size, alignment, clnt_file, clnt_line),0));#else assert(size != 0 && buf_size != 0);#endif if (buf_size <= size) { acc= bf_pack(acc); return acc; } head= bf_cut(acc, 0, size); tail= bf_cut(acc, size, buf_size-size); bf_afree(acc); head= bf_pack(head); assert(head->acc_next == NULL); head->acc_next= tail; return head;}#if 0int chk_acc(acc)acc_t *acc;{ int acc_nr; if (!acc) return 1; if (acc < accessors || acc >= &accessors[ACC_NR]) return 0; acc_nr= acc-accessors; return acc == &accessors[acc_nr];}#endif/* * $PchId: buf.c,v 1.19 2003/09/10 08:54:23 philip Exp $ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -