2 This file contains routines for buffer management.
4 Copyright 1995 Philip Homburg
12 #include "generic/assert.h"
13 #include "generic/buf.h"
18 #define BUF_USEMALLOC 0
31 #define ACC_NR ((BUF512_NR+BUF2K_NR+BUF32K_NR)*3)
34 #define DECLARE_TYPE(Tag, Type, Size) \
38 char buf_data[Size]; \
42 #define DECLARE_STORAGE(Type, Ident, Nitems) \
45 #define ALLOC_STORAGE(Ident, Nitems, Label) \
48 printf("buf.c: malloc %d %s\n", Nitems, Label); \
49 Ident= malloc(sizeof(*Ident) * Nitems); \
51 ip_panic(( "unable to alloc %s", Label )); \
54 #define DECLARE_STORAGE(Type, Ident, Nitems) \
55 PRIVATE Type Ident[Nitems]
57 #define ALLOC_STORAGE(Ident, Nitems, Label) \
62 DECLARE_TYPE(buf512
, buf512_t
, 512);
63 static acc_t
*buf512_freelist
;
64 DECLARE_STORAGE(buf512_t
, buffers512
, BUF512_NR
);
65 static void bf_512free
ARGS(( acc_t
*acc
));
68 DECLARE_TYPE(buf2K
, buf2K_t
, (2*1024));
69 static acc_t
*buf2K_freelist
;
70 DECLARE_STORAGE(buf2K_t
, buffers2K
, BUF2K_NR
);
71 static void bf_2Kfree
ARGS(( acc_t
*acc
));
74 DECLARE_TYPE(buf32K
, buf32K_t
, (32*1024));
75 static acc_t
*buf32K_freelist
;
76 DECLARE_STORAGE(buf32K_t
, buffers32K
, BUF32K_NR
);
77 static void bf_32Kfree
ARGS(( acc_t
*acc
));
80 static acc_t
*acc_freelist
;
81 DECLARE_STORAGE(acc_t
, accessors
, ACC_NR
);
83 static bf_freereq_t freereq
[CLIENT_NR
];
84 static size_t bf_buf_gran
;
86 size_t bf_free_bufsize
;
87 acc_t
*bf_temporary_acc
;
88 acc_t
*bf_linkcheck_acc
;
90 #ifdef BUF_CONSISTENCY_CHECK
92 unsigned buf_generation
;
93 static bf_checkreq_t checkreq
[CLIENT_NR
];
96 #ifndef BUF_TRACK_ALLOC_FREE
97 static acc_t
*bf_small_memreq
ARGS(( size_t size
));
99 static acc_t
*_bf_small_memreq
ARGS(( char *clnt_file
, int clnt_line
,
101 #define bf_small_memreq(a) _bf_small_memreq(clnt_file, clnt_line, a)
103 static void free_accs
ARGS(( void ));
104 #ifdef BUF_CONSISTENCY_CHECK
105 static void count_free_bufs
ARGS(( acc_t
*list
));
106 static int report_buffer
ARGS(( buf_t
*buf
, char *label
, int i
));
118 for (i
=0;i
<CLIENT_NR
;i
++)
120 #ifdef BUF_CONSISTENCY_CHECK
121 for (i
=0;i
<CLIENT_NR
;i
++)
126 ALLOC_STORAGE(buffers512
, BUF512_NR
, "512B-buffers");
129 ALLOC_STORAGE(buffers2K
, BUF2K_NR
, "2K-buffers");
132 ALLOC_STORAGE(buffers32K
, BUF32K_NR
, "32K-buffers");
134 ALLOC_STORAGE(accessors
, ACC_NR
, "accs");
137 for (i
=0;i
<ACC_NR
;i
++)
139 memset(&accessors
[i
], '\0', sizeof(accessors
[i
]));
141 accessors
[i
].acc_linkC
= 0;
142 accessors
[i
].acc_next
= acc_freelist
;
143 acc_freelist
= &accessors
[i
];
146 #define INIT_BUFFERS(Ident, Nitems, Freelist, Freefunc) \
150 for (i=0;i<Nitems;i++) \
154 ip_panic(( "fewer accessors than buffers")); \
155 acc_freelist= acc->acc_next; \
158 memset(&Ident[i], '\0', sizeof(Ident[i])); \
159 Ident[i].buf_header.buf_linkC= 0; \
160 Ident[i].buf_header.buf_free= Freefunc; \
161 Ident[i].buf_header.buf_size= \
162 sizeof(Ident[i].buf_data); \
163 Ident[i].buf_header.buf_data_p= \
166 acc->acc_buffer= &Ident[i].buf_header; \
167 acc->acc_next= Freelist; \
170 if (sizeof(Ident[0].buf_data) < bf_buf_gran) \
171 bf_buf_gran= sizeof(Ident[0].buf_data); \
172 if (sizeof(Ident[0].buf_data) > buf_s) \
173 buf_s= sizeof(Ident[0].buf_data); \
177 INIT_BUFFERS(buffers512
, BUF512_NR
, buf512_freelist
, bf_512free
);
180 INIT_BUFFERS(buffers2K
, BUF2K_NR
, buf2K_freelist
, bf_2Kfree
);
183 INIT_BUFFERS(buffers32K
, BUF32K_NR
, buf32K_freelist
, bf_32Kfree
);
188 assert (buf_s
== BUF_S
);
191 #ifndef BUF_CONSISTENCY_CHECK
195 void bf_logon(func
, checkfunc
)
197 bf_checkreq_t checkfunc
;
202 for (i
=0;i
<CLIENT_NR
;i
++)
206 #ifdef BUF_CONSISTENCY_CHECK
207 checkreq
[i
]= checkfunc
;
212 ip_panic(( "buf.c: too many clients" ));
219 #ifndef BUF_TRACK_ALLOC_FREE
220 acc_t
*bf_memreq(size
)
222 acc_t
*_bf_memreq(clnt_file
, clnt_line
, size
)
228 acc_t
*head
, *tail
, *new_acc
;
241 /* Note the tricky dangling else... */
242 #define ALLOC_BUF(Freelist, Bufsize) \
243 if (Freelist && (Bufsize == BUF_S || size <= Bufsize)) \
246 Freelist= new_acc->acc_next; \
248 assert(new_acc->acc_linkC == 0); \
249 new_acc->acc_linkC= 1; \
250 buf= new_acc->acc_buffer; \
251 assert(buf->buf_linkC == 0); \
256 /* Sort attempts by buffer size */
258 ALLOC_BUF(buf512_freelist
, 512)
261 ALLOC_BUF(buf2K_freelist
, 2*1024)
264 ALLOC_BUF(buf32K_freelist
, 32*1024)
268 DBLOCK(2, printf("freeing buffers\n"));
271 for (i
=0; bf_free_bufsize
<size
&& i
<MAX_BUFREQ_PRI
;
274 for (j
=0; j
<CLIENT_NR
; j
++)
281 j
= 0; for(acc
= buf512_freelist
; acc
; acc
= acc
->acc_next
) j
++;
282 printf("# of free 512-bytes buffer is now %d\n", j
); }
286 { printf("last level was level %d\n", i
-1); }
288 if (bf_free_bufsize
<size
)
289 ip_panic(( "not enough buffers freed" ));
294 #ifdef BUF_TRACK_ALLOC_FREE
295 new_acc
->acc_alloc_file
= clnt_file
;
296 new_acc
->acc_alloc_line
= clnt_line
;
297 buf
->buf_alloc_file
= clnt_file
;
298 buf
->buf_alloc_line
= clnt_line
;
304 tail
->acc_next
= new_acc
;
307 count
= tail
->acc_buffer
->buf_size
;
312 tail
->acc_length
= count
;
315 tail
->acc_next
= NULL
;
324 #ifndef BUF_TRACK_ALLOC_FREE
325 static acc_t
*bf_small_memreq(size
)
327 static acc_t
*_bf_small_memreq(clnt_file
, clnt_line
, size
)
333 return bf_memreq(size
);
336 #ifndef BUF_TRACK_ALLOC_FREE
339 void _bf_afree(clnt_file
, clnt_line
, acc
)
350 #if defined(bf_afree)
351 DIFBLOCK(1, (acc
->acc_linkC
<= 0),
352 printf("clnt_file= %s, clnt_line= %d\n",
353 clnt_file
, clnt_line
));
355 assert (acc
->acc_linkC
>0);
356 if (--acc
->acc_linkC
> 0)
359 #ifdef BUF_TRACK_ALLOC_FREE
360 acc
->acc_free_file
= clnt_file
;
361 acc
->acc_free_line
= clnt_line
;
363 buf
= acc
->acc_buffer
;
366 #if defined(bf_afree)
367 DIFBLOCK(1, (buf
->buf_linkC
== 0),
368 printf("clnt_file= %s, clnt_line= %d\n",
369 clnt_file
, clnt_line
));
371 assert (buf
->buf_linkC
>0);
372 if (--buf
->buf_linkC
> 0)
374 acc
->acc_buffer
= NULL
;
375 next_acc
= acc
->acc_next
;
376 acc
->acc_next
= acc_freelist
;
378 #ifdef BUF_CONSISTENCY_CHECK
381 acc
->acc_offset
= 0xdeadbeaf;
382 acc
->acc_length
= 0xdeadbeaf;
383 acc
->acc_buffer
= (buf_t
*)0xdeadbeaf;
384 acc
->acc_ext_link
= (acc_t
*)0xdeadbeaf;
391 bf_free_bufsize
+= buf
->buf_size
;
392 #ifdef BUF_TRACK_ALLOC_FREE
393 buf
->buf_free_file
= clnt_file
;
394 buf
->buf_free_line
= clnt_line
;
396 next_acc
= acc
->acc_next
;
403 #ifndef BUF_TRACK_ALLOC_FREE
404 acc_t
*bf_dupacc(acc_ptr
)
406 acc_t
*_bf_dupacc(clnt_file
, clnt_line
, acc_ptr
)
410 register acc_t
*acc_ptr
;
412 register acc_t
*new_acc
;
418 ip_panic(( "buf.c: out of accessors" ));
420 new_acc
= acc_freelist
;
421 acc_freelist
= new_acc
->acc_next
;
424 if (acc_ptr
->acc_next
)
425 acc_ptr
->acc_next
->acc_linkC
++;
426 if (acc_ptr
->acc_buffer
)
427 acc_ptr
->acc_buffer
->buf_linkC
++;
428 new_acc
->acc_linkC
= 1;
429 #ifdef BUF_TRACK_ALLOC_FREE
430 new_acc
->acc_alloc_file
= clnt_file
;
431 new_acc
->acc_alloc_line
= clnt_line
;
436 size_t bf_bufsize(acc_ptr
)
437 register acc_t
*acc_ptr
;
439 register size_t size
;
447 assert(acc_ptr
>= accessors
&& acc_ptr
<= &accessors
[ACC_NR
-1]);
448 size
+= acc_ptr
->acc_length
;
449 acc_ptr
= acc_ptr
->acc_next
;
454 #ifndef BUF_TRACK_ALLOC_FREE
455 acc_t
*bf_packIffLess(pack
, min_len
)
457 acc_t
*_bf_packIffLess(clnt_file
, clnt_line
, pack
, min_len
)
464 if (!pack
|| pack
->acc_length
>= min_len
)
468 #ifdef bf_packIffLess
469 { where(); printf("calling bf_pack because of %s %d: %d\n", bf_pack_file
,
470 bf_pack_line
, min_len
); }
473 return bf_pack(pack
);
476 #ifndef BUF_TRACK_ALLOC_FREE
477 acc_t
*bf_pack(old_acc
)
479 acc_t
*_bf_pack(clnt_file
, clnt_line
, old_acc
)
485 acc_t
*new_acc
, *acc_ptr_old
, *acc_ptr_new
;
486 size_t size
, offset_old
, offset_new
, block_size
, block_size_old
;
488 /* Check if old acc is good enough. */
489 if (!old_acc
|| (!old_acc
->acc_next
&& old_acc
->acc_linkC
== 1 &&
490 old_acc
->acc_buffer
->buf_linkC
== 1))
495 size
= bf_bufsize(old_acc
);
497 new_acc
= bf_memreq(size
);
498 acc_ptr_old
= old_acc
;
499 acc_ptr_new
= new_acc
;
504 assert (acc_ptr_old
);
505 if (offset_old
== acc_ptr_old
->acc_length
)
508 acc_ptr_old
= acc_ptr_old
->acc_next
;
511 assert (offset_old
< acc_ptr_old
->acc_length
);
512 block_size_old
= acc_ptr_old
->acc_length
- offset_old
;
513 assert (acc_ptr_new
);
514 if (offset_new
== acc_ptr_new
->acc_length
)
517 acc_ptr_new
= acc_ptr_new
->acc_next
;
520 assert (offset_new
< acc_ptr_new
->acc_length
);
521 block_size
= acc_ptr_new
->acc_length
- offset_new
;
522 if (block_size
> block_size_old
)
523 block_size
= block_size_old
;
524 memcpy(ptr2acc_data(acc_ptr_new
)+offset_new
,
525 ptr2acc_data(acc_ptr_old
)+offset_old
, block_size
);
526 offset_new
+= block_size
;
527 offset_old
+= block_size
;
534 #ifndef BUF_TRACK_ALLOC_FREE
535 acc_t
*bf_cut (data
, offset
, length
)
537 acc_t
*_bf_cut (clnt_file
, clnt_line
, data
, offset
, length
)
541 register acc_t
*data
;
542 register unsigned offset
;
543 register unsigned length
;
545 register acc_t
*head
, *tail
;
547 if (!data
&& !offset
&& !length
)
549 #ifdef BUF_TRACK_ALLOC_FREE
551 (printf("from %s, %d: %u, %u\n",
552 clnt_file
, clnt_line
, offset
, length
), 0));
561 head
= bf_dupacc(data
);
562 bf_afree(head
->acc_next
);
563 head
->acc_next
= NULL
;
567 while (data
&& offset
>=data
->acc_length
)
569 offset
-= data
->acc_length
;
570 data
= data
->acc_next
;
575 head
= bf_dupacc(data
);
576 bf_afree(head
->acc_next
);
577 head
->acc_next
= NULL
;
578 head
->acc_offset
+= offset
;
579 head
->acc_length
-= offset
;
580 if (length
>= head
->acc_length
)
581 length
-= head
->acc_length
;
584 head
->acc_length
= length
;
588 data
= data
->acc_next
;
589 while (data
&& length
&& length
>=data
->acc_length
)
591 tail
->acc_next
= bf_dupacc(data
);
592 tail
= tail
->acc_next
;
593 bf_afree(tail
->acc_next
);
594 tail
->acc_next
= NULL
;
595 data
= data
->acc_next
;
596 length
-= tail
->acc_length
;
602 (printf("bf_cut called from %s:%d\n",
603 clnt_file
, clnt_line
), 0));
607 tail
->acc_next
= bf_dupacc(data
);
608 tail
= tail
->acc_next
;
609 bf_afree(tail
->acc_next
);
610 tail
->acc_next
= NULL
;
611 tail
->acc_length
= length
;
616 #ifndef BUF_TRACK_ALLOC_FREE
617 acc_t
*bf_delhead (data
, offset
)
619 acc_t
*_bf_delhead (clnt_file
, clnt_line
, data
, offset
)
623 register acc_t
*data
;
624 register unsigned offset
;
630 /* Find the acc we need to modify. */
632 while(offset
>= new_acc
->acc_length
)
634 offset
-= new_acc
->acc_length
;
635 new_acc
= new_acc
->acc_next
;
636 #ifdef BUF_TRACK_ALLOC_FREE
637 assert(new_acc
|| (printf("called from %s, %d\n",
638 clnt_file
, clnt_line
),0));
644 /* Discard the old acc(s) */
647 new_acc
->acc_linkC
++;
652 /* Make sure that acc_linkC == 1 */
653 if (data
->acc_linkC
!= 1)
655 new_acc
= bf_dupacc(data
);
660 /* Delete the last bit by modifying acc_offset and acc_length */
661 data
->acc_offset
+= offset
;
662 data
->acc_length
-= offset
;
670 #ifndef BUF_TRACK_ALLOC_FREE
671 acc_t
*bf_append(data_first
, data_second
)
673 acc_t
*_bf_append(clnt_file
, clnt_line
, data_first
, data_second
)
680 acc_t
*head
, *tail
, *new_acc
, *acc_ptr_new
, tmp_acc
, *curr
;
681 char *src_ptr
, *dst_ptr
;
682 size_t size
, offset_old
, offset_new
, block_size_old
, block_size
;
693 if (data_first
->acc_linkC
== 1)
697 curr
= bf_dupacc(data_first
);
698 assert (curr
->acc_linkC
== 1);
699 bf_afree(data_first
);
701 data_first
= curr
->acc_next
;
702 if (!curr
->acc_length
)
704 curr
->acc_next
= NULL
;
711 tail
->acc_next
= curr
;
716 tail
->acc_next
= NULL
;
718 while (data_second
&& !data_second
->acc_length
)
721 data_second
= data_second
->acc_next
;
723 data_second
->acc_linkC
++;
729 if (tail
->acc_length
+ data_second
->acc_length
>
730 tail
->acc_buffer
->buf_size
)
732 tail
->acc_next
= data_second
;
736 if (tail
->acc_buffer
->buf_size
== bf_buf_gran
&&
737 tail
->acc_buffer
->buf_linkC
== 1)
739 if (tail
->acc_offset
)
741 memmove(tail
->acc_buffer
->buf_data_p
,
742 ptr2acc_data(tail
), tail
->acc_length
);
745 dst_ptr
= ptr2acc_data(tail
) + tail
->acc_length
;
746 src_ptr
= ptr2acc_data(data_second
);
747 memcpy(dst_ptr
, src_ptr
, data_second
->acc_length
);
748 tail
->acc_length
+= data_second
->acc_length
;
749 tail
->acc_next
= data_second
->acc_next
;
750 if (data_second
->acc_next
)
751 data_second
->acc_next
->acc_linkC
++;
752 bf_afree(data_second
);
756 new_acc
= bf_small_memreq(tail
->acc_length
+data_second
->acc_length
);
757 acc_ptr_new
= new_acc
;
760 size
= tail
->acc_length
;
763 assert (acc_ptr_new
);
764 if (offset_new
== acc_ptr_new
->acc_length
)
767 acc_ptr_new
= acc_ptr_new
->acc_next
;
770 assert (offset_new
< acc_ptr_new
->acc_length
);
771 assert (offset_old
< tail
->acc_length
);
772 block_size_old
= tail
->acc_length
- offset_old
;
773 block_size
= acc_ptr_new
->acc_length
- offset_new
;
774 if (block_size
> block_size_old
)
775 block_size
= block_size_old
;
776 memcpy(ptr2acc_data(acc_ptr_new
)+offset_new
,
777 ptr2acc_data(tail
)+offset_old
, block_size
);
778 offset_new
+= block_size
;
779 offset_old
+= block_size
;
783 size
= data_second
->acc_length
;
786 assert (acc_ptr_new
);
787 if (offset_new
== acc_ptr_new
->acc_length
)
790 acc_ptr_new
= acc_ptr_new
->acc_next
;
793 assert (offset_new
< acc_ptr_new
->acc_length
);
794 assert (offset_old
< data_second
->acc_length
);
795 block_size_old
= data_second
->acc_length
- offset_old
;
796 block_size
= acc_ptr_new
->acc_length
- offset_new
;
797 if (block_size
> block_size_old
)
798 block_size
= block_size_old
;
799 memcpy(ptr2acc_data(acc_ptr_new
)+offset_new
,
800 ptr2acc_data(data_second
)+offset_old
, block_size
);
801 offset_new
+= block_size
;
802 offset_old
+= block_size
;
810 while (tail
->acc_next
)
811 tail
= tail
->acc_next
;
813 tail
->acc_next
= data_second
->acc_next
;
814 if (data_second
->acc_next
)
815 data_second
->acc_next
->acc_linkC
++;
816 bf_afree(data_second
);
821 static void bf_512free(acc
)
824 #ifdef BUF_CONSISTENCY_CHECK
826 memset(acc
->acc_buffer
->buf_data_p
, 0xa5, 512);
828 acc
->acc_next
= buf512_freelist
;
829 buf512_freelist
= acc
;
833 static void bf_2Kfree(acc
)
836 #ifdef BUF_CONSISTENCY_CHECK
838 memset(acc
->acc_buffer
->buf_data_p
, 0xa5, 2*1024);
840 acc
->acc_next
= buf2K_freelist
;
845 static void bf_32Kfree(acc
)
848 #ifdef BUF_CONSISTENCY_CHECK
850 memset(acc
->acc_buffer
->buf_data_p
, 0xa5, 32*1024);
852 acc
->acc_next
= buf32K_freelist
;
853 buf32K_freelist
= acc
;
857 #ifdef BUF_CONSISTENCY_CHECK
858 int bf_consistency_check()
867 for (i
=0; i
<CLIENT_NR
; i
++)
873 /* Add information about free accessors */
874 for(acc
= acc_freelist
; acc
; acc
= acc
->acc_next
)
876 if (acc
->acc_generation
== buf_generation
-1)
878 acc
->acc_generation
= buf_generation
;
879 acc
->acc_check_linkC
= 0;
883 assert(acc
->acc_generation
== buf_generation
&&
884 acc
->acc_check_linkC
> 0);
885 acc
->acc_check_linkC
= -acc
->acc_check_linkC
;
890 count_free_bufs(buf512_freelist
);
893 count_free_bufs(buf2K_freelist
);
896 count_free_bufs(buf32K_freelist
);
901 /* Report about accessors */
903 for (i
=0, acc
= accessors
; i
<ACC_NR
; i
++, acc
++)
905 if (acc
->acc_generation
!= buf_generation
)
908 assert(acc
->acc_generation
== buf_generation
-1);
909 acc
->acc_generation
= buf_generation
;
913 "acc[%d] (%p) has been lost with count %d, last allocated at %s, %d\n",
914 i
, acc
, acc
->acc_linkC
, acc
->acc_alloc_file
, acc
->acc_alloc_line
);
921 if (acc
->acc_check_linkC
== acc
->acc_linkC
)
924 if (acc
->acc_check_linkC
< 0)
929 "acc[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n",
930 i
, acc
->acc_alloc_file
, acc
->acc_alloc_line
,
931 acc
->acc_free_file
, acc
->acc_free_line
);
933 acc
->acc_check_linkC
= -acc
->acc_check_linkC
;
934 if (acc
->acc_check_linkC
== acc
->acc_linkC
)
943 "# of tracked links (%d) for acc[%d] don't match with stored link count %d\n",
944 acc
->acc_check_linkC
, i
, acc
->acc_linkC
);
945 printf("acc[%d] was allocated at %s, %d\n",
946 i
, acc
->acc_alloc_file
, acc
->acc_alloc_line
);
951 /* Report about buffers */
954 for (i
= 0; i
<BUF512_NR
; i
++)
956 error
|= report_buffer(&buffers512
[i
].buf_header
,
963 for (i
= 0; i
<BUF2K_NR
; i
++)
965 error
|= report_buffer(&buffers2K
[i
].buf_header
,
972 for (i
= 0; i
<BUF32K_NR
; i
++)
974 error
|= report_buffer(&buffers32K
[i
].buf_header
,
983 static void count_free_bufs(list
)
989 for(acc
= list
; acc
; acc
= acc
->acc_next
)
991 if (acc
->acc_generation
!= buf_generation
-1)
993 assert(acc
->acc_generation
== buf_generation
&&
994 acc
->acc_check_linkC
> 0);
995 acc
->acc_check_linkC
= -acc
->acc_check_linkC
;
998 acc
->acc_generation
= buf_generation
;
999 acc
->acc_check_linkC
= 0;
1001 buf
= acc
->acc_buffer
;
1002 if (buf
->buf_generation
== buf_generation
-1)
1004 buf
->buf_generation
= buf_generation
;
1005 buf
->buf_check_linkC
= 0;
1008 assert(buf
->buf_generation
== buf_generation
&&
1009 buf
->buf_check_linkC
> 0);
1010 buf
->buf_check_linkC
= -buf
->buf_check_linkC
;
1014 static int report_buffer(buf
, label
, i
)
1019 if (buf
->buf_generation
!= buf_generation
)
1021 assert(buf
->buf_generation
== buf_generation
-1);
1022 buf
->buf_generation
= buf_generation
;
1024 "%s[%d] (%p) has been lost with count %d, last allocated at %s, %d\n",
1026 buf
->buf_linkC
, buf
->buf_alloc_file
,
1027 buf
->buf_alloc_line
);
1030 if (buf
->buf_check_linkC
== buf
->buf_linkC
)
1032 if (buf
->buf_check_linkC
< 0)
1035 "%s[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n",
1036 label
, i
, buf
->buf_alloc_file
, buf
->buf_alloc_line
,
1037 buf
->buf_free_file
, buf
->buf_free_line
);
1038 buf
->buf_check_linkC
= -buf
->buf_check_linkC
;
1039 if (buf
->buf_check_linkC
== buf
->buf_linkC
)
1043 "# of tracked links (%d) for %s[%d] don't match with stored link count %d\n",
1044 buf
->buf_check_linkC
, label
, i
, buf
->buf_linkC
);
1045 printf("%s[%d] was allocated at %s, %d\n",
1046 label
, i
, buf
->buf_alloc_file
, buf
->buf_alloc_line
);
1050 void bf_check_acc(acc
)
1057 if (acc
->acc_generation
== buf_generation
)
1059 assert(acc
->acc_check_linkC
> 0);
1060 acc
->acc_check_linkC
++;
1063 assert(acc
->acc_generation
== buf_generation
-1);
1064 acc
->acc_generation
= buf_generation
;
1065 acc
->acc_check_linkC
= 1;
1067 buf
= acc
->acc_buffer
;
1068 if (buf
->buf_generation
== buf_generation
)
1070 assert(buf
->buf_check_linkC
> 0);
1071 buf
->buf_check_linkC
++;
1075 assert(buf
->buf_generation
== buf_generation
-1);
1076 buf
->buf_generation
= buf_generation
;
1077 buf
->buf_check_linkC
= 1;
1084 void _bf_mark_1acc(clnt_file
, clnt_line
, acc
)
1089 acc
->acc_alloc_file
= clnt_file
;
1090 acc
->acc_alloc_line
= clnt_line
;
1093 void _bf_mark_acc(clnt_file
, clnt_line
, acc
)
1100 for (; acc
; acc
= acc
->acc_next
)
1102 acc
->acc_alloc_file
= clnt_file
;
1103 acc
->acc_alloc_line
= clnt_line
;
1104 buf
= acc
->acc_buffer
;
1105 buf
->buf_alloc_file
= clnt_file
;
1106 buf
->buf_alloc_line
= clnt_line
;
1111 int bf_linkcheck(acc
)
1117 for (i
= 0; i
<ACC_NR
&& acc
; i
++, acc
= acc
->acc_next
)
1119 if (acc
->acc_linkC
<= 0)
1121 printf("wrong acc_linkC (%d) for acc %p\n",
1122 acc
->acc_linkC
, acc
);
1125 if (acc
->acc_offset
< 0)
1127 printf("wrong acc_offset (%d) for acc %p\n",
1128 acc
->acc_offset
, acc
);
1131 if (acc
->acc_length
< 0)
1133 printf("wrong acc_length (%d) for acc %p\n",
1134 acc
->acc_length
, acc
);
1137 buffer
= acc
->acc_buffer
;
1140 printf("no buffer for acc %p\n", acc
);
1143 if (buffer
->buf_linkC
<= 0)
1146 "wrong buf_linkC (%d) for buffer %p, from acc %p\n",
1147 buffer
->buf_linkC
, buffer
, acc
);
1150 if (acc
->acc_offset
+ acc
->acc_length
> buffer
->buf_size
)
1152 printf("%d + %d > %d for buffer %p, and acc %p\n",
1153 acc
->acc_offset
, acc
->acc_length
,
1154 buffer
->buf_size
, buffer
, acc
);
1166 static void free_accs()
1170 DBLOCK(1, printf("free_accs\n"));
1172 assert(bf_linkcheck(bf_linkcheck_acc
));
1173 for (i
=0; !acc_freelist
&& i
<MAX_BUFREQ_PRI
; i
++)
1175 for (j
=0; j
<CLIENT_NR
; j
++)
1181 assert(bf_linkcheck(bf_linkcheck_acc
) ||
1182 (printf("just called %p\n",
1188 printf("last level was level %d\n", i
-1);
1192 #ifndef BUF_TRACK_ALLOC_FREE
1193 acc_t
*bf_align(acc
, size
, alignment
)
1195 acc_t
*_bf_align(clnt_file
, clnt_line
, acc
, size
, alignment
)
1207 /* Fast check if the buffer is aligned already. */
1208 if (acc
->acc_length
>= size
)
1210 ptr
= ptr2acc_data(acc
);
1211 if (((unsigned)ptr
& (alignment
-1)) == 0)
1214 buf_size
= bf_bufsize(acc
);
1216 assert((size
!= 0 && buf_size
!= 0) ||
1217 (printf("bf_align(..., %d, %d) from %s, %d\n",
1218 size
, alignment
, clnt_file
, clnt_line
),0));
1220 assert(size
!= 0 && buf_size
!= 0);
1222 if (buf_size
<= size
)
1227 head
= bf_cut(acc
, 0, size
);
1228 tail
= bf_cut(acc
, size
, buf_size
-size
);
1230 head
= bf_pack(head
);
1231 assert(head
->acc_next
== NULL
);
1232 head
->acc_next
= tail
;
1244 if (acc
< accessors
|| acc
>= &accessors
[ACC_NR
])
1246 acc_nr
= acc
-accessors
;
1247 return acc
== &accessors
[acc_nr
];
1252 * $PchId: buf.c,v 1.19 2003/09/10 08:54:23 philip Exp $