[9] | 1 | /*
|
---|
| 2 | This file contains routines for buffer management.
|
---|
| 3 |
|
---|
| 4 | Copyright 1995 Philip Homburg
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 | #define BUF_IMPLEMENTATION 1 /* Avoid some macros */
|
---|
| 8 |
|
---|
| 9 | #include "inet.h"
|
---|
| 10 |
|
---|
| 11 | #include <stdlib.h>
|
---|
| 12 | #include <string.h>
|
---|
| 13 |
|
---|
| 14 | #include "generic/assert.h"
|
---|
| 15 | #include "generic/buf.h"
|
---|
| 16 | #include "generic/type.h"
|
---|
| 17 |
|
---|
| 18 | THIS_FILE
|
---|
| 19 |
|
---|
| 20 | #ifndef BUF_USEMALLOC
|
---|
| 21 | #define BUF_USEMALLOC 0
|
---|
| 22 | #endif
|
---|
| 23 |
|
---|
| 24 | #ifndef BUF512_NR
|
---|
| 25 | #define BUF512_NR 512
|
---|
| 26 | #endif
|
---|
| 27 | #ifndef BUF2K_NR
|
---|
| 28 | #define BUF2K_NR 0
|
---|
| 29 | #endif
|
---|
| 30 | #ifndef BUF32K_NR
|
---|
| 31 | #define BUF32K_NR 0
|
---|
| 32 | #endif
|
---|
| 33 |
|
---|
| 34 | #define ACC_NR ((BUF512_NR+BUF2K_NR+BUF32K_NR)*3)
|
---|
| 35 | #define CLIENT_NR 7
|
---|
| 36 |
|
---|
| 37 | #define DECLARE_TYPE(Tag, Type, Size) \
|
---|
| 38 | typedef struct Tag \
|
---|
| 39 | { \
|
---|
| 40 | buf_t buf_header; \
|
---|
| 41 | char buf_data[Size]; \
|
---|
| 42 | } Type
|
---|
| 43 |
|
---|
| 44 | #if BUF_USEMALLOC
|
---|
| 45 | #define DECLARE_STORAGE(Type, Ident, Nitems) \
|
---|
| 46 | PRIVATE Type *Ident
|
---|
| 47 |
|
---|
| 48 | #define ALLOC_STORAGE(Ident, Nitems, Label) \
|
---|
| 49 | do \
|
---|
| 50 | { \
|
---|
| 51 | printf("buf.c: malloc %d %s\n", Nitems, Label); \
|
---|
| 52 | Ident= malloc(sizeof(*Ident) * Nitems); \
|
---|
| 53 | if (!Ident) \
|
---|
| 54 | ip_panic(( "unable to alloc %s", Label )); \
|
---|
| 55 | } while(0)
|
---|
| 56 | #else
|
---|
| 57 | #define DECLARE_STORAGE(Type, Ident, Nitems) \
|
---|
| 58 | PRIVATE Type Ident[Nitems]
|
---|
| 59 |
|
---|
| 60 | #define ALLOC_STORAGE(Ident, Nitems, Label) \
|
---|
| 61 | (void)0
|
---|
| 62 | #endif
|
---|
| 63 |
|
---|
| 64 | #if BUF512_NR
|
---|
| 65 | DECLARE_TYPE(buf512, buf512_t, 512);
|
---|
| 66 | PRIVATE acc_t *buf512_freelist;
|
---|
| 67 | DECLARE_STORAGE(buf512_t, buffers512, BUF512_NR);
|
---|
| 68 | FORWARD void bf_512free ARGS(( acc_t *acc ));
|
---|
| 69 | #endif
|
---|
| 70 | #if BUF2K_NR
|
---|
| 71 | DECLARE_TYPE(buf2K, buf2K_t, (2*1024));
|
---|
| 72 | PRIVATE acc_t *buf2K_freelist;
|
---|
| 73 | DECLARE_STORAGE(buf2K_t, buffers2K, BUF2K_NR);
|
---|
| 74 | FORWARD void bf_2Kfree ARGS(( acc_t *acc ));
|
---|
| 75 | #endif
|
---|
| 76 | #if BUF32K_NR
|
---|
| 77 | DECLARE_TYPE(buf32K, buf32K_t, (32*1024));
|
---|
| 78 | PRIVATE acc_t *buf32K_freelist;
|
---|
| 79 | DECLARE_STORAGE(buf32K_t, buffers32K, BUF32K_NR);
|
---|
| 80 | FORWARD void bf_32Kfree ARGS(( acc_t *acc ));
|
---|
| 81 | #endif
|
---|
| 82 |
|
---|
| 83 | PRIVATE acc_t *acc_freelist;
|
---|
| 84 | DECLARE_STORAGE(acc_t, accessors, ACC_NR);
|
---|
| 85 |
|
---|
| 86 | PRIVATE bf_freereq_t freereq[CLIENT_NR];
|
---|
| 87 | PRIVATE size_t bf_buf_gran;
|
---|
| 88 |
|
---|
| 89 | PUBLIC size_t bf_free_bufsize;
|
---|
| 90 | PUBLIC acc_t *bf_temporary_acc;
|
---|
| 91 | PUBLIC acc_t *bf_linkcheck_acc;
|
---|
| 92 |
|
---|
| 93 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 94 | int inet_buf_debug;
|
---|
| 95 | unsigned buf_generation;
|
---|
| 96 | PRIVATE bf_checkreq_t checkreq[CLIENT_NR];
|
---|
| 97 | #endif
|
---|
| 98 |
|
---|
| 99 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 100 | FORWARD acc_t *bf_small_memreq ARGS(( size_t size ));
|
---|
| 101 | #else
|
---|
| 102 | FORWARD acc_t *_bf_small_memreq ARGS(( char *clnt_file, int clnt_line,
|
---|
| 103 | size_t size ));
|
---|
| 104 | #define bf_small_memreq(a) _bf_small_memreq(clnt_file, clnt_line, a)
|
---|
| 105 | #endif
|
---|
| 106 | FORWARD void free_accs ARGS(( void ));
|
---|
| 107 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 108 | FORWARD void count_free_bufs ARGS(( acc_t *list ));
|
---|
| 109 | FORWARD int report_buffer ARGS(( buf_t *buf, char *label, int i ));
|
---|
| 110 | #endif
|
---|
| 111 |
|
---|
| 112 | PUBLIC void bf_init()
|
---|
| 113 | {
|
---|
| 114 | int i;
|
---|
| 115 | size_t buf_s;
|
---|
| 116 | acc_t *acc;
|
---|
| 117 |
|
---|
| 118 | bf_buf_gran= BUF_S;
|
---|
| 119 | buf_s= 0;
|
---|
| 120 |
|
---|
| 121 | for (i=0;i<CLIENT_NR;i++)
|
---|
| 122 | freereq[i]=0;
|
---|
| 123 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 124 | for (i=0;i<CLIENT_NR;i++)
|
---|
| 125 | checkreq[i]=0;
|
---|
| 126 | #endif
|
---|
| 127 |
|
---|
| 128 | #if BUF512_NR
|
---|
| 129 | ALLOC_STORAGE(buffers512, BUF512_NR, "512B-buffers");
|
---|
| 130 | #endif
|
---|
| 131 | #if BUF2K_NR
|
---|
| 132 | ALLOC_STORAGE(buffers2K, BUF2K_NR, "2K-buffers");
|
---|
| 133 | #endif
|
---|
| 134 | #if BUF32K_NR
|
---|
| 135 | ALLOC_STORAGE(buffers32K, BUF32K_NR, "32K-buffers");
|
---|
| 136 | #endif
|
---|
| 137 | ALLOC_STORAGE(accessors, ACC_NR, "accs");
|
---|
| 138 |
|
---|
| 139 | acc_freelist= NULL;
|
---|
| 140 | for (i=0;i<ACC_NR;i++)
|
---|
| 141 | {
|
---|
| 142 | memset(&accessors[i], '\0', sizeof(accessors[i]));
|
---|
| 143 |
|
---|
| 144 | accessors[i].acc_linkC= 0;
|
---|
| 145 | accessors[i].acc_next= acc_freelist;
|
---|
| 146 | acc_freelist= &accessors[i];
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | #define INIT_BUFFERS(Ident, Nitems, Freelist, Freefunc) \
|
---|
| 150 | do \
|
---|
| 151 | { \
|
---|
| 152 | Freelist= NULL; \
|
---|
| 153 | for (i=0;i<Nitems;i++) \
|
---|
| 154 | { \
|
---|
| 155 | acc= acc_freelist; \
|
---|
| 156 | if (!acc) \
|
---|
| 157 | ip_panic(( "fewer accessors than buffers")); \
|
---|
| 158 | acc_freelist= acc->acc_next; \
|
---|
| 159 | acc->acc_linkC= 0; \
|
---|
| 160 | \
|
---|
| 161 | memset(&Ident[i], '\0', sizeof(Ident[i])); \
|
---|
| 162 | Ident[i].buf_header.buf_linkC= 0; \
|
---|
| 163 | Ident[i].buf_header.buf_free= Freefunc; \
|
---|
| 164 | Ident[i].buf_header.buf_size= \
|
---|
| 165 | sizeof(Ident[i].buf_data); \
|
---|
| 166 | Ident[i].buf_header.buf_data_p= \
|
---|
| 167 | Ident[i].buf_data; \
|
---|
| 168 | \
|
---|
| 169 | acc->acc_buffer= &Ident[i].buf_header; \
|
---|
| 170 | acc->acc_next= Freelist; \
|
---|
| 171 | Freelist= acc; \
|
---|
| 172 | } \
|
---|
| 173 | if (sizeof(Ident[0].buf_data) < bf_buf_gran) \
|
---|
| 174 | bf_buf_gran= sizeof(Ident[0].buf_data); \
|
---|
| 175 | if (sizeof(Ident[0].buf_data) > buf_s) \
|
---|
| 176 | buf_s= sizeof(Ident[0].buf_data); \
|
---|
| 177 | } while(0)
|
---|
| 178 |
|
---|
| 179 | #if BUF512_NR
|
---|
| 180 | INIT_BUFFERS(buffers512, BUF512_NR, buf512_freelist, bf_512free);
|
---|
| 181 | #endif
|
---|
| 182 | #if BUF2K_NR
|
---|
| 183 | INIT_BUFFERS(buffers2K, BUF2K_NR, buf2K_freelist, bf_2Kfree);
|
---|
| 184 | #endif
|
---|
| 185 | #if BUF32K_NR
|
---|
| 186 | INIT_BUFFERS(buffers32K, BUF32K_NR, buf32K_freelist, bf_32Kfree);
|
---|
| 187 | #endif
|
---|
| 188 |
|
---|
| 189 | #undef INIT_BUFFERS
|
---|
| 190 |
|
---|
| 191 | assert (buf_s == BUF_S);
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 | #ifndef BUF_CONSISTENCY_CHECK
|
---|
| 195 | PUBLIC void bf_logon(func)
|
---|
| 196 | bf_freereq_t func;
|
---|
| 197 | #else
|
---|
| 198 | PUBLIC void bf_logon(func, checkfunc)
|
---|
| 199 | bf_freereq_t func;
|
---|
| 200 | bf_checkreq_t checkfunc;
|
---|
| 201 | #endif
|
---|
| 202 | {
|
---|
| 203 | int i;
|
---|
| 204 |
|
---|
| 205 | for (i=0;i<CLIENT_NR;i++)
|
---|
| 206 | if (!freereq[i])
|
---|
| 207 | {
|
---|
| 208 | freereq[i]=func;
|
---|
| 209 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 210 | checkreq[i]= checkfunc;
|
---|
| 211 | #endif
|
---|
| 212 | return;
|
---|
| 213 | }
|
---|
| 214 |
|
---|
| 215 | ip_panic(( "buf.c: too many clients" ));
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | /*
|
---|
| 219 | bf_memreq
|
---|
| 220 | */
|
---|
| 221 |
|
---|
| 222 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 223 | PUBLIC acc_t *bf_memreq(size)
|
---|
| 224 | #else
|
---|
| 225 | PUBLIC acc_t *_bf_memreq(clnt_file, clnt_line, size)
|
---|
| 226 | char *clnt_file;
|
---|
| 227 | int clnt_line;
|
---|
| 228 | #endif
|
---|
| 229 | size_t size;
|
---|
| 230 | {
|
---|
| 231 | acc_t *head, *tail, *new_acc;
|
---|
| 232 | buf_t *buf;
|
---|
| 233 | int i,j;
|
---|
| 234 | size_t count;
|
---|
| 235 |
|
---|
| 236 | assert (size>0);
|
---|
| 237 |
|
---|
| 238 | head= NULL;
|
---|
| 239 | tail= NULL;
|
---|
| 240 | while (size)
|
---|
| 241 | {
|
---|
| 242 | new_acc= NULL;
|
---|
| 243 |
|
---|
| 244 | /* Note the tricky dangling else... */
|
---|
| 245 | #define ALLOC_BUF(Freelist, Bufsize) \
|
---|
| 246 | if (Freelist && (Bufsize == BUF_S || size <= Bufsize)) \
|
---|
| 247 | { \
|
---|
| 248 | new_acc= Freelist; \
|
---|
| 249 | Freelist= new_acc->acc_next; \
|
---|
| 250 | \
|
---|
| 251 | assert(new_acc->acc_linkC == 0); \
|
---|
| 252 | new_acc->acc_linkC= 1; \
|
---|
| 253 | buf= new_acc->acc_buffer; \
|
---|
| 254 | assert(buf->buf_linkC == 0); \
|
---|
| 255 | buf->buf_linkC= 1; \
|
---|
| 256 | } \
|
---|
| 257 | else
|
---|
| 258 |
|
---|
| 259 | /* Sort attempts by buffer size */
|
---|
| 260 | #if BUF512_NR
|
---|
| 261 | ALLOC_BUF(buf512_freelist, 512)
|
---|
| 262 | #endif
|
---|
| 263 | #if BUF2K_NR
|
---|
| 264 | ALLOC_BUF(buf2K_freelist, 2*1024)
|
---|
| 265 | #endif
|
---|
| 266 | #if BUF32K_NR
|
---|
| 267 | ALLOC_BUF(buf32K_freelist, 32*1024)
|
---|
| 268 | #endif
|
---|
| 269 | #undef ALLOC_BUF
|
---|
| 270 | {
|
---|
| 271 | DBLOCK(2, printf("freeing buffers\n"));
|
---|
| 272 |
|
---|
| 273 | bf_free_bufsize= 0;
|
---|
| 274 | for (i=0; bf_free_bufsize<size && i<MAX_BUFREQ_PRI;
|
---|
| 275 | i++)
|
---|
| 276 | {
|
---|
| 277 | for (j=0; j<CLIENT_NR; j++)
|
---|
| 278 | {
|
---|
| 279 | if (freereq[j])
|
---|
| 280 | (*freereq[j])(i);
|
---|
| 281 | }
|
---|
| 282 | #if DEBUG && 0
|
---|
| 283 | { acc_t *acc;
|
---|
| 284 | j= 0; for(acc= buf512_freelist; acc; acc= acc->acc_next) j++;
|
---|
| 285 | printf("# of free 512-bytes buffer is now %d\n", j); }
|
---|
| 286 | #endif
|
---|
| 287 | }
|
---|
| 288 | #if DEBUG && 0
|
---|
| 289 | { printf("last level was level %d\n", i-1); }
|
---|
| 290 | #endif
|
---|
| 291 | if (bf_free_bufsize<size)
|
---|
| 292 | ip_panic(( "not enough buffers freed" ));
|
---|
| 293 |
|
---|
| 294 | continue;
|
---|
| 295 | }
|
---|
| 296 |
|
---|
| 297 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 298 | new_acc->acc_alloc_file= clnt_file;
|
---|
| 299 | new_acc->acc_alloc_line= clnt_line;
|
---|
| 300 | buf->buf_alloc_file= clnt_file;
|
---|
| 301 | buf->buf_alloc_line= clnt_line;
|
---|
| 302 | #endif
|
---|
| 303 |
|
---|
| 304 | if (!head)
|
---|
| 305 | head= new_acc;
|
---|
| 306 | else
|
---|
| 307 | tail->acc_next= new_acc;
|
---|
| 308 | tail= new_acc;
|
---|
| 309 |
|
---|
| 310 | count= tail->acc_buffer->buf_size;
|
---|
| 311 | if (count > size)
|
---|
| 312 | count= size;
|
---|
| 313 |
|
---|
| 314 | tail->acc_offset= 0;
|
---|
| 315 | tail->acc_length= count;
|
---|
| 316 | size -= count;
|
---|
| 317 | }
|
---|
| 318 | tail->acc_next= NULL;
|
---|
| 319 |
|
---|
| 320 | return head;
|
---|
| 321 | }
|
---|
| 322 |
|
---|
| 323 | /*
|
---|
| 324 | bf_small_memreq
|
---|
| 325 | */
|
---|
| 326 |
|
---|
| 327 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 328 | PRIVATE acc_t *bf_small_memreq(size)
|
---|
| 329 | #else
|
---|
| 330 | PRIVATE acc_t *_bf_small_memreq(clnt_file, clnt_line, size)
|
---|
| 331 | char *clnt_file;
|
---|
| 332 | int clnt_line;
|
---|
| 333 | #endif
|
---|
| 334 | size_t size;
|
---|
| 335 | {
|
---|
| 336 | return bf_memreq(size);
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 340 | PUBLIC void bf_afree(acc)
|
---|
| 341 | #else
|
---|
| 342 | PUBLIC void _bf_afree(clnt_file, clnt_line, acc)
|
---|
| 343 | char *clnt_file;
|
---|
| 344 | int clnt_line;
|
---|
| 345 | #endif
|
---|
| 346 | acc_t *acc;
|
---|
| 347 | {
|
---|
| 348 | acc_t *next_acc;
|
---|
| 349 | buf_t *buf;
|
---|
| 350 |
|
---|
| 351 | while (acc)
|
---|
| 352 | {
|
---|
| 353 | #if defined(bf_afree)
|
---|
| 354 | DIFBLOCK(1, (acc->acc_linkC <= 0),
|
---|
| 355 | printf("clnt_file= %s, clnt_line= %d\n",
|
---|
| 356 | clnt_file, clnt_line));
|
---|
| 357 | #endif
|
---|
| 358 | assert (acc->acc_linkC>0);
|
---|
| 359 | if (--acc->acc_linkC > 0)
|
---|
| 360 | break;
|
---|
| 361 |
|
---|
| 362 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 363 | acc->acc_free_file= clnt_file;
|
---|
| 364 | acc->acc_free_line= clnt_line;
|
---|
| 365 | #endif
|
---|
| 366 | buf= acc->acc_buffer;
|
---|
| 367 | assert (buf);
|
---|
| 368 |
|
---|
| 369 | #if defined(bf_afree)
|
---|
| 370 | DIFBLOCK(1, (buf->buf_linkC == 0),
|
---|
| 371 | printf("clnt_file= %s, clnt_line= %d\n",
|
---|
| 372 | clnt_file, clnt_line));
|
---|
| 373 | #endif
|
---|
| 374 | assert (buf->buf_linkC>0);
|
---|
| 375 | if (--buf->buf_linkC > 0)
|
---|
| 376 | {
|
---|
| 377 | acc->acc_buffer= NULL;
|
---|
| 378 | next_acc= acc->acc_next;
|
---|
| 379 | acc->acc_next= acc_freelist;
|
---|
| 380 | acc_freelist= acc;
|
---|
| 381 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 382 | if (inet_buf_debug)
|
---|
| 383 | {
|
---|
| 384 | acc->acc_offset= 0xdeadbeaf;
|
---|
| 385 | acc->acc_length= 0xdeadbeaf;
|
---|
| 386 | acc->acc_buffer= (buf_t *)0xdeadbeaf;
|
---|
| 387 | acc->acc_ext_link= (acc_t *)0xdeadbeaf;
|
---|
| 388 | }
|
---|
| 389 | #endif
|
---|
| 390 | acc= next_acc;
|
---|
| 391 | continue;
|
---|
| 392 | }
|
---|
| 393 |
|
---|
| 394 | bf_free_bufsize += buf->buf_size;
|
---|
| 395 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 396 | buf->buf_free_file= clnt_file;
|
---|
| 397 | buf->buf_free_line= clnt_line;
|
---|
| 398 | #endif
|
---|
| 399 | next_acc= acc->acc_next;
|
---|
| 400 | buf->buf_free(acc);
|
---|
| 401 | acc= next_acc;
|
---|
| 402 | continue;
|
---|
| 403 | }
|
---|
| 404 | }
|
---|
| 405 |
|
---|
| 406 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 407 | PUBLIC acc_t *bf_dupacc(acc_ptr)
|
---|
| 408 | #else
|
---|
| 409 | PUBLIC acc_t *_bf_dupacc(clnt_file, clnt_line, acc_ptr)
|
---|
| 410 | char *clnt_file;
|
---|
| 411 | int clnt_line;
|
---|
| 412 | #endif
|
---|
| 413 | register acc_t *acc_ptr;
|
---|
| 414 | {
|
---|
| 415 | register acc_t *new_acc;
|
---|
| 416 |
|
---|
| 417 | if (!acc_freelist)
|
---|
| 418 | {
|
---|
| 419 | free_accs();
|
---|
| 420 | if (!acc_freelist)
|
---|
| 421 | ip_panic(( "buf.c: out of accessors" ));
|
---|
| 422 | }
|
---|
| 423 | new_acc= acc_freelist;
|
---|
| 424 | acc_freelist= new_acc->acc_next;
|
---|
| 425 |
|
---|
| 426 | *new_acc= *acc_ptr;
|
---|
| 427 | if (acc_ptr->acc_next)
|
---|
| 428 | acc_ptr->acc_next->acc_linkC++;
|
---|
| 429 | if (acc_ptr->acc_buffer)
|
---|
| 430 | acc_ptr->acc_buffer->buf_linkC++;
|
---|
| 431 | new_acc->acc_linkC= 1;
|
---|
| 432 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 433 | new_acc->acc_alloc_file= clnt_file;
|
---|
| 434 | new_acc->acc_alloc_line= clnt_line;
|
---|
| 435 | #endif
|
---|
| 436 | return new_acc;
|
---|
| 437 | }
|
---|
| 438 |
|
---|
| 439 | PUBLIC size_t bf_bufsize(acc_ptr)
|
---|
| 440 | register acc_t *acc_ptr;
|
---|
| 441 | {
|
---|
| 442 | register size_t size;
|
---|
| 443 |
|
---|
| 444 | assert(acc_ptr);
|
---|
| 445 |
|
---|
| 446 | size=0;
|
---|
| 447 |
|
---|
| 448 | while (acc_ptr)
|
---|
| 449 | {
|
---|
| 450 | assert(acc_ptr >= accessors && acc_ptr <= &accessors[ACC_NR-1]);
|
---|
| 451 | size += acc_ptr->acc_length;
|
---|
| 452 | acc_ptr= acc_ptr->acc_next;
|
---|
| 453 | }
|
---|
| 454 | return size;
|
---|
| 455 | }
|
---|
| 456 |
|
---|
| 457 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 458 | PUBLIC acc_t *bf_packIffLess(pack, min_len)
|
---|
| 459 | #else
|
---|
| 460 | PUBLIC acc_t *_bf_packIffLess(clnt_file, clnt_line, pack, min_len)
|
---|
| 461 | char *clnt_file;
|
---|
| 462 | int clnt_line;
|
---|
| 463 | #endif
|
---|
| 464 | acc_t *pack;
|
---|
| 465 | int min_len;
|
---|
| 466 | {
|
---|
| 467 | if (!pack || pack->acc_length >= min_len)
|
---|
| 468 | return pack;
|
---|
| 469 |
|
---|
| 470 | #if DEBUG
|
---|
| 471 | #ifdef bf_packIffLess
|
---|
| 472 | { where(); printf("calling bf_pack because of %s %d: %d\n", bf_pack_file,
|
---|
| 473 | bf_pack_line, min_len); }
|
---|
| 474 | #endif
|
---|
| 475 | #endif
|
---|
| 476 | return bf_pack(pack);
|
---|
| 477 | }
|
---|
| 478 |
|
---|
| 479 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 480 | PUBLIC acc_t *bf_pack(old_acc)
|
---|
| 481 | #else
|
---|
| 482 | PUBLIC acc_t *_bf_pack(clnt_file, clnt_line, old_acc)
|
---|
| 483 | char *clnt_file;
|
---|
| 484 | int clnt_line;
|
---|
| 485 | #endif
|
---|
| 486 | acc_t *old_acc;
|
---|
| 487 | {
|
---|
| 488 | acc_t *new_acc, *acc_ptr_old, *acc_ptr_new;
|
---|
| 489 | size_t size, offset_old, offset_new, block_size, block_size_old;
|
---|
| 490 |
|
---|
| 491 | /* Check if old acc is good enough. */
|
---|
| 492 | if (!old_acc || (!old_acc->acc_next && old_acc->acc_linkC == 1 &&
|
---|
| 493 | old_acc->acc_buffer->buf_linkC == 1))
|
---|
| 494 | {
|
---|
| 495 | return old_acc;
|
---|
| 496 | }
|
---|
| 497 |
|
---|
| 498 | size= bf_bufsize(old_acc);
|
---|
| 499 | assert(size > 0);
|
---|
| 500 | new_acc= bf_memreq(size);
|
---|
| 501 | acc_ptr_old= old_acc;
|
---|
| 502 | acc_ptr_new= new_acc;
|
---|
| 503 | offset_old= 0;
|
---|
| 504 | offset_new= 0;
|
---|
| 505 | while (size)
|
---|
| 506 | {
|
---|
| 507 | assert (acc_ptr_old);
|
---|
| 508 | if (offset_old == acc_ptr_old->acc_length)
|
---|
| 509 | {
|
---|
| 510 | offset_old= 0;
|
---|
| 511 | acc_ptr_old= acc_ptr_old->acc_next;
|
---|
| 512 | continue;
|
---|
| 513 | }
|
---|
| 514 | assert (offset_old < acc_ptr_old->acc_length);
|
---|
| 515 | block_size_old= acc_ptr_old->acc_length - offset_old;
|
---|
| 516 | assert (acc_ptr_new);
|
---|
| 517 | if (offset_new == acc_ptr_new->acc_length)
|
---|
| 518 | {
|
---|
| 519 | offset_new= 0;
|
---|
| 520 | acc_ptr_new= acc_ptr_new->acc_next;
|
---|
| 521 | continue;
|
---|
| 522 | }
|
---|
| 523 | assert (offset_new < acc_ptr_new->acc_length);
|
---|
| 524 | block_size= acc_ptr_new->acc_length - offset_new;
|
---|
| 525 | if (block_size > block_size_old)
|
---|
| 526 | block_size= block_size_old;
|
---|
| 527 | memcpy(ptr2acc_data(acc_ptr_new)+offset_new,
|
---|
| 528 | ptr2acc_data(acc_ptr_old)+offset_old, block_size);
|
---|
| 529 | offset_new += block_size;
|
---|
| 530 | offset_old += block_size;
|
---|
| 531 | size -= block_size;
|
---|
| 532 | }
|
---|
| 533 | bf_afree(old_acc);
|
---|
| 534 | return new_acc;
|
---|
| 535 | }
|
---|
| 536 |
|
---|
| 537 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 538 | PUBLIC acc_t *bf_cut (data, offset, length)
|
---|
| 539 | #else
|
---|
| 540 | PUBLIC acc_t *_bf_cut (clnt_file, clnt_line, data, offset, length)
|
---|
| 541 | char *clnt_file;
|
---|
| 542 | int clnt_line;
|
---|
| 543 | #endif
|
---|
| 544 | register acc_t *data;
|
---|
| 545 | register unsigned offset;
|
---|
| 546 | register unsigned length;
|
---|
| 547 | {
|
---|
| 548 | register acc_t *head, *tail;
|
---|
| 549 |
|
---|
| 550 | if (!data && !offset && !length)
|
---|
| 551 | return NULL;
|
---|
| 552 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 553 | assert(data ||
|
---|
| 554 | (printf("from %s, %d: %u, %u\n",
|
---|
| 555 | clnt_file, clnt_line, offset, length), 0));
|
---|
| 556 | #else
|
---|
| 557 | assert(data);
|
---|
| 558 | #endif
|
---|
| 559 |
|
---|
| 560 | assert(data);
|
---|
| 561 |
|
---|
| 562 | if (!length)
|
---|
| 563 | {
|
---|
| 564 | head= bf_dupacc(data);
|
---|
| 565 | bf_afree(head->acc_next);
|
---|
| 566 | head->acc_next= NULL;
|
---|
| 567 | head->acc_length= 0;
|
---|
| 568 | return head;
|
---|
| 569 | }
|
---|
| 570 | while (data && offset>=data->acc_length)
|
---|
| 571 | {
|
---|
| 572 | offset -= data->acc_length;
|
---|
| 573 | data= data->acc_next;
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | assert (data);
|
---|
| 577 |
|
---|
| 578 | head= bf_dupacc(data);
|
---|
| 579 | bf_afree(head->acc_next);
|
---|
| 580 | head->acc_next= NULL;
|
---|
| 581 | head->acc_offset += offset;
|
---|
| 582 | head->acc_length -= offset;
|
---|
| 583 | if (length >= head->acc_length)
|
---|
| 584 | length -= head->acc_length;
|
---|
| 585 | else
|
---|
| 586 | {
|
---|
| 587 | head->acc_length= length;
|
---|
| 588 | length= 0;
|
---|
| 589 | }
|
---|
| 590 | tail= head;
|
---|
| 591 | data= data->acc_next;
|
---|
| 592 | while (data && length && length>=data->acc_length)
|
---|
| 593 | {
|
---|
| 594 | tail->acc_next= bf_dupacc(data);
|
---|
| 595 | tail= tail->acc_next;
|
---|
| 596 | bf_afree(tail->acc_next);
|
---|
| 597 | tail->acc_next= NULL;
|
---|
| 598 | data= data->acc_next;
|
---|
| 599 | length -= tail->acc_length;
|
---|
| 600 | }
|
---|
| 601 | if (length)
|
---|
| 602 | {
|
---|
| 603 | #ifdef bf_cut
|
---|
| 604 | assert (data ||
|
---|
| 605 | (printf("bf_cut called from %s:%d\n",
|
---|
| 606 | clnt_file, clnt_line), 0));
|
---|
| 607 | #else
|
---|
| 608 | assert (data);
|
---|
| 609 | #endif
|
---|
| 610 | tail->acc_next= bf_dupacc(data);
|
---|
| 611 | tail= tail->acc_next;
|
---|
| 612 | bf_afree(tail->acc_next);
|
---|
| 613 | tail->acc_next= NULL;
|
---|
| 614 | tail->acc_length= length;
|
---|
| 615 | }
|
---|
| 616 | return head;
|
---|
| 617 | }
|
---|
| 618 |
|
---|
| 619 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 620 | PUBLIC acc_t *bf_delhead (data, offset)
|
---|
| 621 | #else
|
---|
| 622 | PUBLIC acc_t *_bf_delhead (clnt_file, clnt_line, data, offset)
|
---|
| 623 | char *clnt_file;
|
---|
| 624 | int clnt_line;
|
---|
| 625 | #endif
|
---|
| 626 | register acc_t *data;
|
---|
| 627 | register unsigned offset;
|
---|
| 628 | {
|
---|
| 629 | acc_t *new_acc;
|
---|
| 630 |
|
---|
| 631 | assert(data);
|
---|
| 632 |
|
---|
| 633 | /* Find the acc we need to modify. */
|
---|
| 634 | new_acc= data;
|
---|
| 635 | while(offset >= new_acc->acc_length)
|
---|
| 636 | {
|
---|
| 637 | offset -= new_acc->acc_length;
|
---|
| 638 | new_acc= new_acc->acc_next;
|
---|
| 639 | #ifdef BUF_TRACK_ALLOC_FREE
|
---|
| 640 | assert(new_acc || (printf("called from %s, %d\n",
|
---|
| 641 | clnt_file, clnt_line),0));
|
---|
| 642 | #else
|
---|
| 643 | assert(new_acc);
|
---|
| 644 | #endif
|
---|
| 645 | }
|
---|
| 646 |
|
---|
| 647 | /* Discard the old acc(s) */
|
---|
| 648 | if (new_acc != data)
|
---|
| 649 | {
|
---|
| 650 | new_acc->acc_linkC++;
|
---|
| 651 | bf_afree(data);
|
---|
| 652 | data= new_acc;
|
---|
| 653 | }
|
---|
| 654 |
|
---|
| 655 | /* Make sure that acc_linkC == 1 */
|
---|
| 656 | if (data->acc_linkC != 1)
|
---|
| 657 | {
|
---|
| 658 | new_acc= bf_dupacc(data);
|
---|
| 659 | bf_afree(data);
|
---|
| 660 | data= new_acc;
|
---|
| 661 | }
|
---|
| 662 |
|
---|
| 663 | /* Delete the last bit by modifying acc_offset and acc_length */
|
---|
| 664 | data->acc_offset += offset;
|
---|
| 665 | data->acc_length -= offset;
|
---|
| 666 | return data;
|
---|
| 667 | }
|
---|
| 668 |
|
---|
| 669 | /*
|
---|
| 670 | bf_append
|
---|
| 671 | */
|
---|
| 672 |
|
---|
| 673 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 674 | PUBLIC acc_t *bf_append(data_first, data_second)
|
---|
| 675 | #else
|
---|
| 676 | PUBLIC acc_t *_bf_append(clnt_file, clnt_line, data_first, data_second)
|
---|
| 677 | char *clnt_file;
|
---|
| 678 | int clnt_line;
|
---|
| 679 | #endif
|
---|
| 680 | acc_t *data_first;
|
---|
| 681 | acc_t *data_second;
|
---|
| 682 | {
|
---|
| 683 | acc_t *head, *tail, *new_acc, *acc_ptr_new, tmp_acc, *curr;
|
---|
| 684 | char *src_ptr, *dst_ptr;
|
---|
| 685 | size_t size, offset_old, offset_new, block_size_old, block_size;
|
---|
| 686 |
|
---|
| 687 | if (!data_first)
|
---|
| 688 | return data_second;
|
---|
| 689 | if (!data_second)
|
---|
| 690 | return data_first;
|
---|
| 691 |
|
---|
| 692 | head= NULL;
|
---|
| 693 | tail= NULL;
|
---|
| 694 | while (data_first)
|
---|
| 695 | {
|
---|
| 696 | if (data_first->acc_linkC == 1)
|
---|
| 697 | curr= data_first;
|
---|
| 698 | else
|
---|
| 699 | {
|
---|
| 700 | curr= bf_dupacc(data_first);
|
---|
| 701 | assert (curr->acc_linkC == 1);
|
---|
| 702 | bf_afree(data_first);
|
---|
| 703 | }
|
---|
| 704 | data_first= curr->acc_next;
|
---|
| 705 | if (!curr->acc_length)
|
---|
| 706 | {
|
---|
| 707 | curr->acc_next= NULL;
|
---|
| 708 | bf_afree(curr);
|
---|
| 709 | continue;
|
---|
| 710 | }
|
---|
| 711 | if (!head)
|
---|
| 712 | head= curr;
|
---|
| 713 | else
|
---|
| 714 | tail->acc_next= curr;
|
---|
| 715 | tail= curr;
|
---|
| 716 | }
|
---|
| 717 | if (!head)
|
---|
| 718 | return data_second;
|
---|
| 719 | tail->acc_next= NULL;
|
---|
| 720 |
|
---|
| 721 | while (data_second && !data_second->acc_length)
|
---|
| 722 | {
|
---|
| 723 | curr= data_second;
|
---|
| 724 | data_second= data_second->acc_next;
|
---|
| 725 | if (data_second)
|
---|
| 726 | data_second->acc_linkC++;
|
---|
| 727 | bf_afree(curr);
|
---|
| 728 | }
|
---|
| 729 | if (!data_second)
|
---|
| 730 | return head;
|
---|
| 731 |
|
---|
| 732 | if (tail->acc_length + data_second->acc_length >
|
---|
| 733 | tail->acc_buffer->buf_size)
|
---|
| 734 | {
|
---|
| 735 | tail->acc_next= data_second;
|
---|
| 736 | return head;
|
---|
| 737 | }
|
---|
| 738 |
|
---|
| 739 | if (tail->acc_buffer->buf_size == bf_buf_gran &&
|
---|
| 740 | tail->acc_buffer->buf_linkC == 1)
|
---|
| 741 | {
|
---|
| 742 | if (tail->acc_offset)
|
---|
| 743 | {
|
---|
| 744 | memmove(tail->acc_buffer->buf_data_p,
|
---|
| 745 | ptr2acc_data(tail), tail->acc_length);
|
---|
| 746 | tail->acc_offset= 0;
|
---|
| 747 | }
|
---|
| 748 | dst_ptr= ptr2acc_data(tail) + tail->acc_length;
|
---|
| 749 | src_ptr= ptr2acc_data(data_second);
|
---|
| 750 | memcpy(dst_ptr, src_ptr, data_second->acc_length);
|
---|
| 751 | tail->acc_length += data_second->acc_length;
|
---|
| 752 | tail->acc_next= data_second->acc_next;
|
---|
| 753 | if (data_second->acc_next)
|
---|
| 754 | data_second->acc_next->acc_linkC++;
|
---|
| 755 | bf_afree(data_second);
|
---|
| 756 | return head;
|
---|
| 757 | }
|
---|
| 758 |
|
---|
| 759 | new_acc= bf_small_memreq(tail->acc_length+data_second->acc_length);
|
---|
| 760 | acc_ptr_new= new_acc;
|
---|
| 761 | offset_old= 0;
|
---|
| 762 | offset_new= 0;
|
---|
| 763 | size= tail->acc_length;
|
---|
| 764 | while (size)
|
---|
| 765 | {
|
---|
| 766 | assert (acc_ptr_new);
|
---|
| 767 | if (offset_new == acc_ptr_new->acc_length)
|
---|
| 768 | {
|
---|
| 769 | offset_new= 0;
|
---|
| 770 | acc_ptr_new= acc_ptr_new->acc_next;
|
---|
| 771 | continue;
|
---|
| 772 | }
|
---|
| 773 | assert (offset_new < acc_ptr_new->acc_length);
|
---|
| 774 | assert (offset_old < tail->acc_length);
|
---|
| 775 | block_size_old= tail->acc_length - offset_old;
|
---|
| 776 | block_size= acc_ptr_new->acc_length - offset_new;
|
---|
| 777 | if (block_size > block_size_old)
|
---|
| 778 | block_size= block_size_old;
|
---|
| 779 | memcpy(ptr2acc_data(acc_ptr_new)+offset_new,
|
---|
| 780 | ptr2acc_data(tail)+offset_old, block_size);
|
---|
| 781 | offset_new += block_size;
|
---|
| 782 | offset_old += block_size;
|
---|
| 783 | size -= block_size;
|
---|
| 784 | }
|
---|
| 785 | offset_old= 0;
|
---|
| 786 | size= data_second->acc_length;
|
---|
| 787 | while (size)
|
---|
| 788 | {
|
---|
| 789 | assert (acc_ptr_new);
|
---|
| 790 | if (offset_new == acc_ptr_new->acc_length)
|
---|
| 791 | {
|
---|
| 792 | offset_new= 0;
|
---|
| 793 | acc_ptr_new= acc_ptr_new->acc_next;
|
---|
| 794 | continue;
|
---|
| 795 | }
|
---|
| 796 | assert (offset_new < acc_ptr_new->acc_length);
|
---|
| 797 | assert (offset_old < data_second->acc_length);
|
---|
| 798 | block_size_old= data_second->acc_length - offset_old;
|
---|
| 799 | block_size= acc_ptr_new->acc_length - offset_new;
|
---|
| 800 | if (block_size > block_size_old)
|
---|
| 801 | block_size= block_size_old;
|
---|
| 802 | memcpy(ptr2acc_data(acc_ptr_new)+offset_new,
|
---|
| 803 | ptr2acc_data(data_second)+offset_old, block_size);
|
---|
| 804 | offset_new += block_size;
|
---|
| 805 | offset_old += block_size;
|
---|
| 806 | size -= block_size;
|
---|
| 807 | }
|
---|
| 808 | tmp_acc= *tail;
|
---|
| 809 | *tail= *new_acc;
|
---|
| 810 | *new_acc= tmp_acc;
|
---|
| 811 |
|
---|
| 812 | bf_afree(new_acc);
|
---|
| 813 | while (tail->acc_next)
|
---|
| 814 | tail= tail->acc_next;
|
---|
| 815 |
|
---|
| 816 | tail->acc_next= data_second->acc_next;
|
---|
| 817 | if (data_second->acc_next)
|
---|
| 818 | data_second->acc_next->acc_linkC++;
|
---|
| 819 | bf_afree(data_second);
|
---|
| 820 | return head;
|
---|
| 821 | }
|
---|
| 822 |
|
---|
| 823 | #if BUF512_NR
|
---|
| 824 | PRIVATE void bf_512free(acc)
|
---|
| 825 | acc_t *acc;
|
---|
| 826 | {
|
---|
| 827 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 828 | if (inet_buf_debug)
|
---|
| 829 | memset(acc->acc_buffer->buf_data_p, 0xa5, 512);
|
---|
| 830 | #endif
|
---|
| 831 | acc->acc_next= buf512_freelist;
|
---|
| 832 | buf512_freelist= acc;
|
---|
| 833 | }
|
---|
| 834 | #endif
|
---|
| 835 | #if BUF2K_NR
|
---|
| 836 | PRIVATE void bf_2Kfree(acc)
|
---|
| 837 | acc_t *acc;
|
---|
| 838 | {
|
---|
| 839 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 840 | if (inet_buf_debug)
|
---|
| 841 | memset(acc->acc_buffer->buf_data_p, 0xa5, 2*1024);
|
---|
| 842 | #endif
|
---|
| 843 | acc->acc_next= buf2K_freelist;
|
---|
| 844 | buf2K_freelist= acc;
|
---|
| 845 | }
|
---|
| 846 | #endif
|
---|
| 847 | #if BUF32K_NR
|
---|
| 848 | PRIVATE void bf_32Kfree(acc)
|
---|
| 849 | acc_t *acc;
|
---|
| 850 | {
|
---|
| 851 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 852 | if (inet_buf_debug)
|
---|
| 853 | memset(acc->acc_buffer->buf_data_p, 0xa5, 32*1024);
|
---|
| 854 | #endif
|
---|
| 855 | acc->acc_next= buf32K_freelist;
|
---|
| 856 | buf32K_freelist= acc;
|
---|
| 857 | }
|
---|
| 858 | #endif
|
---|
| 859 |
|
---|
| 860 | #ifdef BUF_CONSISTENCY_CHECK
|
---|
| 861 | PUBLIC int bf_consistency_check()
|
---|
| 862 | {
|
---|
| 863 | acc_t *acc;
|
---|
| 864 | int silent;
|
---|
| 865 | int error;
|
---|
| 866 | int i;
|
---|
| 867 |
|
---|
| 868 | buf_generation++;
|
---|
| 869 |
|
---|
| 870 | for (i=0; i<CLIENT_NR; i++)
|
---|
| 871 | {
|
---|
| 872 | if (checkreq[i])
|
---|
| 873 | (*checkreq[i])();
|
---|
| 874 | }
|
---|
| 875 |
|
---|
| 876 | /* Add information about free accessors */
|
---|
| 877 | for(acc= acc_freelist; acc; acc= acc->acc_next)
|
---|
| 878 | {
|
---|
| 879 | if (acc->acc_generation == buf_generation-1)
|
---|
| 880 | {
|
---|
| 881 | acc->acc_generation= buf_generation;
|
---|
| 882 | acc->acc_check_linkC= 0;
|
---|
| 883 | }
|
---|
| 884 | else
|
---|
| 885 | {
|
---|
| 886 | assert(acc->acc_generation == buf_generation &&
|
---|
| 887 | acc->acc_check_linkC > 0);
|
---|
| 888 | acc->acc_check_linkC= -acc->acc_check_linkC;
|
---|
| 889 | }
|
---|
| 890 | }
|
---|
| 891 |
|
---|
| 892 | #if BUF512_NR
|
---|
| 893 | count_free_bufs(buf512_freelist);
|
---|
| 894 | #endif
|
---|
| 895 | #if BUF2K_NR
|
---|
| 896 | count_free_bufs(buf2K_freelist);
|
---|
| 897 | #endif
|
---|
| 898 | #if BUF32K_NR
|
---|
| 899 | count_free_bufs(buf32K_freelist);
|
---|
| 900 | #endif
|
---|
| 901 |
|
---|
| 902 | error= 0;
|
---|
| 903 |
|
---|
| 904 | /* Report about accessors */
|
---|
| 905 | silent= 0;
|
---|
| 906 | for (i=0, acc= accessors; i<ACC_NR; i++, acc++)
|
---|
| 907 | {
|
---|
| 908 | if (acc->acc_generation != buf_generation)
|
---|
| 909 | {
|
---|
| 910 | error++;
|
---|
| 911 | assert(acc->acc_generation == buf_generation-1);
|
---|
| 912 | acc->acc_generation= buf_generation;
|
---|
| 913 | if (!silent)
|
---|
| 914 | {
|
---|
| 915 | printf(
|
---|
| 916 | "acc[%d] (%p) has been lost with count %d, last allocated at %s, %d\n",
|
---|
| 917 | i, acc, acc->acc_linkC, acc->acc_alloc_file, acc->acc_alloc_line);
|
---|
| 918 | #if 0
|
---|
| 919 | silent= 1;
|
---|
| 920 | #endif
|
---|
| 921 | }
|
---|
| 922 | continue;
|
---|
| 923 | }
|
---|
| 924 | if (acc->acc_check_linkC == acc->acc_linkC)
|
---|
| 925 | continue;
|
---|
| 926 | error++;
|
---|
| 927 | if (acc->acc_check_linkC < 0)
|
---|
| 928 | {
|
---|
| 929 | if (!silent)
|
---|
| 930 | {
|
---|
| 931 | printf(
|
---|
| 932 | "acc[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n",
|
---|
| 933 | i, acc->acc_alloc_file, acc->acc_alloc_line,
|
---|
| 934 | acc->acc_free_file, acc->acc_free_line);
|
---|
| 935 | }
|
---|
| 936 | acc->acc_check_linkC= -acc->acc_check_linkC;
|
---|
| 937 | if (acc->acc_check_linkC == acc->acc_linkC)
|
---|
| 938 | {
|
---|
| 939 | silent= 1;
|
---|
| 940 | continue;
|
---|
| 941 | }
|
---|
| 942 | }
|
---|
| 943 | if (!silent)
|
---|
| 944 | {
|
---|
| 945 | printf(
|
---|
| 946 | "# of tracked links (%d) for acc[%d] don't match with stored link count %d\n",
|
---|
| 947 | acc->acc_check_linkC, i, acc->acc_linkC);
|
---|
| 948 | printf("acc[%d] was allocated at %s, %d\n",
|
---|
| 949 | i, acc->acc_alloc_file, acc->acc_alloc_line);
|
---|
| 950 | silent=1;
|
---|
| 951 | }
|
---|
| 952 | }
|
---|
| 953 |
|
---|
| 954 | /* Report about buffers */
|
---|
| 955 | #if BUF512_NR
|
---|
| 956 | {
|
---|
| 957 | for (i= 0; i<BUF512_NR; i++)
|
---|
| 958 | {
|
---|
| 959 | error |= report_buffer(&buffers512[i].buf_header,
|
---|
| 960 | "512-buffer", i);
|
---|
| 961 | }
|
---|
| 962 | }
|
---|
| 963 | #endif
|
---|
| 964 | #if BUF2K_NR
|
---|
| 965 | {
|
---|
| 966 | for (i= 0; i<BUF2K_NR; i++)
|
---|
| 967 | {
|
---|
| 968 | error |= report_buffer(&buffers2K[i].buf_header,
|
---|
| 969 | "2K-buffer", i);
|
---|
| 970 | }
|
---|
| 971 | }
|
---|
| 972 | #endif
|
---|
| 973 | #if BUF32K_NR
|
---|
| 974 | {
|
---|
| 975 | for (i= 0; i<BUF32K_NR; i++)
|
---|
| 976 | {
|
---|
| 977 | error |= report_buffer(&buffers32K[i].buf_header,
|
---|
| 978 | "32K-buffer", i);
|
---|
| 979 | }
|
---|
| 980 | }
|
---|
| 981 | #endif
|
---|
| 982 |
|
---|
| 983 | return !error;
|
---|
| 984 | }
|
---|
| 985 |
|
---|
| 986 | PRIVATE void count_free_bufs(list)
|
---|
| 987 | acc_t *list;
|
---|
| 988 | {
|
---|
| 989 | acc_t *acc;
|
---|
| 990 | buf_t *buf;
|
---|
| 991 |
|
---|
| 992 | for(acc= list; acc; acc= acc->acc_next)
|
---|
| 993 | {
|
---|
| 994 | if (acc->acc_generation != buf_generation-1)
|
---|
| 995 | {
|
---|
| 996 | assert(acc->acc_generation == buf_generation &&
|
---|
| 997 | acc->acc_check_linkC > 0);
|
---|
| 998 | acc->acc_check_linkC= -acc->acc_check_linkC;
|
---|
| 999 | continue;
|
---|
| 1000 | }
|
---|
| 1001 | acc->acc_generation= buf_generation;
|
---|
| 1002 | acc->acc_check_linkC= 0;
|
---|
| 1003 |
|
---|
| 1004 | buf= acc->acc_buffer;
|
---|
| 1005 | if (buf->buf_generation == buf_generation-1)
|
---|
| 1006 | {
|
---|
| 1007 | buf->buf_generation= buf_generation;
|
---|
| 1008 | buf->buf_check_linkC= 0;
|
---|
| 1009 | continue;
|
---|
| 1010 | }
|
---|
| 1011 | assert(buf->buf_generation == buf_generation &&
|
---|
| 1012 | buf->buf_check_linkC > 0);
|
---|
| 1013 | buf->buf_check_linkC= -buf->buf_check_linkC;
|
---|
| 1014 | }
|
---|
| 1015 | }
|
---|
| 1016 |
|
---|
| 1017 | PRIVATE int report_buffer(buf, label, i)
|
---|
| 1018 | buf_t *buf;
|
---|
| 1019 | char *label;
|
---|
| 1020 | int i;
|
---|
| 1021 | {
|
---|
| 1022 | if (buf->buf_generation != buf_generation)
|
---|
| 1023 | {
|
---|
| 1024 | assert(buf->buf_generation == buf_generation-1);
|
---|
| 1025 | buf->buf_generation= buf_generation;
|
---|
| 1026 | printf(
|
---|
| 1027 | "%s[%d] (%p) has been lost with count %d, last allocated at %s, %d\n",
|
---|
| 1028 | label, i, buf,
|
---|
| 1029 | buf->buf_linkC, buf->buf_alloc_file,
|
---|
| 1030 | buf->buf_alloc_line);
|
---|
| 1031 | return 1;
|
---|
| 1032 | }
|
---|
| 1033 | if (buf->buf_check_linkC == buf->buf_linkC)
|
---|
| 1034 | return 0;
|
---|
| 1035 | if (buf->buf_check_linkC < 0)
|
---|
| 1036 | {
|
---|
| 1037 | printf(
|
---|
| 1038 | "%s[%d] is freed but still in use, allocated at %s, %d, freed at %s, %d\n",
|
---|
| 1039 | label, i, buf->buf_alloc_file, buf->buf_alloc_line,
|
---|
| 1040 | buf->buf_free_file, buf->buf_free_line);
|
---|
| 1041 | buf->buf_check_linkC= -buf->buf_check_linkC;
|
---|
| 1042 | if (buf->buf_check_linkC == buf->buf_linkC)
|
---|
| 1043 | return 1;
|
---|
| 1044 | }
|
---|
| 1045 | printf(
|
---|
| 1046 | "# of tracked links (%d) for %s[%d] don't match with stored link count %d\n",
|
---|
| 1047 | buf->buf_check_linkC, label, i, buf->buf_linkC);
|
---|
| 1048 | printf("%s[%d] was allocated at %s, %d\n",
|
---|
| 1049 | label, i, buf->buf_alloc_file, buf->buf_alloc_line);
|
---|
| 1050 | return 1;
|
---|
| 1051 | }
|
---|
| 1052 |
|
---|
| 1053 | PUBLIC void bf_check_acc(acc)
|
---|
| 1054 | acc_t *acc;
|
---|
| 1055 | {
|
---|
| 1056 | buf_t *buf;
|
---|
| 1057 |
|
---|
| 1058 | while(acc != NULL)
|
---|
| 1059 | {
|
---|
| 1060 | if (acc->acc_generation == buf_generation)
|
---|
| 1061 | {
|
---|
| 1062 | assert(acc->acc_check_linkC > 0);
|
---|
| 1063 | acc->acc_check_linkC++;
|
---|
| 1064 | return;
|
---|
| 1065 | }
|
---|
| 1066 | assert(acc->acc_generation == buf_generation-1);
|
---|
| 1067 | acc->acc_generation= buf_generation;
|
---|
| 1068 | acc->acc_check_linkC= 1;
|
---|
| 1069 |
|
---|
| 1070 | buf= acc->acc_buffer;
|
---|
| 1071 | if (buf->buf_generation == buf_generation)
|
---|
| 1072 | {
|
---|
| 1073 | assert(buf->buf_check_linkC > 0);
|
---|
| 1074 | buf->buf_check_linkC++;
|
---|
| 1075 | }
|
---|
| 1076 | else
|
---|
| 1077 | {
|
---|
| 1078 | assert(buf->buf_generation == buf_generation-1);
|
---|
| 1079 | buf->buf_generation= buf_generation;
|
---|
| 1080 | buf->buf_check_linkC= 1;
|
---|
| 1081 | }
|
---|
| 1082 |
|
---|
| 1083 | acc= acc->acc_next;
|
---|
| 1084 | }
|
---|
| 1085 | }
|
---|
| 1086 |
|
---|
| 1087 | PUBLIC void _bf_mark_1acc(clnt_file, clnt_line, acc)
|
---|
| 1088 | char *clnt_file;
|
---|
| 1089 | int clnt_line;
|
---|
| 1090 | acc_t *acc;
|
---|
| 1091 | {
|
---|
| 1092 | acc->acc_alloc_file= clnt_file;
|
---|
| 1093 | acc->acc_alloc_line= clnt_line;
|
---|
| 1094 | }
|
---|
| 1095 |
|
---|
| 1096 | PUBLIC void _bf_mark_acc(clnt_file, clnt_line, acc)
|
---|
| 1097 | char *clnt_file;
|
---|
| 1098 | int clnt_line;
|
---|
| 1099 | acc_t *acc;
|
---|
| 1100 | {
|
---|
| 1101 | buf_t *buf;
|
---|
| 1102 |
|
---|
| 1103 | for (; acc; acc= acc->acc_next)
|
---|
| 1104 | {
|
---|
| 1105 | acc->acc_alloc_file= clnt_file;
|
---|
| 1106 | acc->acc_alloc_line= clnt_line;
|
---|
| 1107 | buf= acc->acc_buffer;
|
---|
| 1108 | buf->buf_alloc_file= clnt_file;
|
---|
| 1109 | buf->buf_alloc_line= clnt_line;
|
---|
| 1110 | }
|
---|
| 1111 | }
|
---|
| 1112 | #endif
|
---|
| 1113 |
|
---|
| 1114 | PUBLIC int bf_linkcheck(acc)
|
---|
| 1115 | acc_t *acc;
|
---|
| 1116 | {
|
---|
| 1117 | int i;
|
---|
| 1118 |
|
---|
| 1119 | buf_t *buffer;
|
---|
| 1120 | for (i= 0; i<ACC_NR && acc; i++, acc= acc->acc_next)
|
---|
| 1121 | {
|
---|
| 1122 | if (acc->acc_linkC <= 0)
|
---|
| 1123 | {
|
---|
| 1124 | printf("wrong acc_linkC (%d) for acc %p\n",
|
---|
| 1125 | acc->acc_linkC, acc);
|
---|
| 1126 | return 0;
|
---|
| 1127 | }
|
---|
| 1128 | if (acc->acc_offset < 0)
|
---|
| 1129 | {
|
---|
| 1130 | printf("wrong acc_offset (%d) for acc %p\n",
|
---|
| 1131 | acc->acc_offset, acc);
|
---|
| 1132 | return 0;
|
---|
| 1133 | }
|
---|
| 1134 | if (acc->acc_length < 0)
|
---|
| 1135 | {
|
---|
| 1136 | printf("wrong acc_length (%d) for acc %p\n",
|
---|
| 1137 | acc->acc_length, acc);
|
---|
| 1138 | return 0;
|
---|
| 1139 | }
|
---|
| 1140 | buffer= acc->acc_buffer;
|
---|
| 1141 | if (buffer == NULL)
|
---|
| 1142 | {
|
---|
| 1143 | printf("no buffer for acc %p\n", acc);
|
---|
| 1144 | return 0;
|
---|
| 1145 | }
|
---|
| 1146 | if (buffer->buf_linkC <= 0)
|
---|
| 1147 | {
|
---|
| 1148 | printf(
|
---|
| 1149 | "wrong buf_linkC (%d) for buffer %p, from acc %p\n",
|
---|
| 1150 | buffer->buf_linkC, buffer, acc);
|
---|
| 1151 | return 0;
|
---|
| 1152 | }
|
---|
| 1153 | if (acc->acc_offset + acc->acc_length > buffer->buf_size)
|
---|
| 1154 | {
|
---|
| 1155 | printf("%d + %d > %d for buffer %p, and acc %p\n",
|
---|
| 1156 | acc->acc_offset, acc->acc_length,
|
---|
| 1157 | buffer->buf_size, buffer, acc);
|
---|
| 1158 | return 0;
|
---|
| 1159 | }
|
---|
| 1160 | }
|
---|
| 1161 | if (acc != NULL)
|
---|
| 1162 | {
|
---|
| 1163 | printf("loop\n");
|
---|
| 1164 | return 0;
|
---|
| 1165 | }
|
---|
| 1166 | return 1;
|
---|
| 1167 | }
|
---|
| 1168 |
|
---|
| 1169 | PRIVATE void free_accs()
|
---|
| 1170 | {
|
---|
| 1171 | int i, j;
|
---|
| 1172 |
|
---|
| 1173 | DBLOCK(1, printf("free_accs\n"));
|
---|
| 1174 |
|
---|
| 1175 | assert(bf_linkcheck(bf_linkcheck_acc));
|
---|
| 1176 | for (i=0; !acc_freelist && i<MAX_BUFREQ_PRI; i++)
|
---|
| 1177 | {
|
---|
| 1178 | for (j=0; j<CLIENT_NR; j++)
|
---|
| 1179 | {
|
---|
| 1180 | bf_free_bufsize= 0;
|
---|
| 1181 | if (freereq[j])
|
---|
| 1182 | {
|
---|
| 1183 | (*freereq[j])(i);
|
---|
| 1184 | assert(bf_linkcheck(bf_linkcheck_acc) ||
|
---|
| 1185 | (printf("just called %p\n",
|
---|
| 1186 | freereq[i]),0));
|
---|
| 1187 | }
|
---|
| 1188 | }
|
---|
| 1189 | }
|
---|
| 1190 | #if DEBUG
|
---|
| 1191 | printf("last level was level %d\n", i-1);
|
---|
| 1192 | #endif
|
---|
| 1193 | }
|
---|
| 1194 |
|
---|
| 1195 | #ifndef BUF_TRACK_ALLOC_FREE
|
---|
| 1196 | PUBLIC acc_t *bf_align(acc, size, alignment)
|
---|
| 1197 | #else
|
---|
| 1198 | PUBLIC acc_t *_bf_align(clnt_file, clnt_line, acc, size, alignment)
|
---|
| 1199 | char *clnt_file;
|
---|
| 1200 | int clnt_line;
|
---|
| 1201 | #endif
|
---|
| 1202 | acc_t *acc;
|
---|
| 1203 | size_t size;
|
---|
| 1204 | size_t alignment;
|
---|
| 1205 | {
|
---|
| 1206 | char *ptr;
|
---|
| 1207 | size_t buf_size;
|
---|
| 1208 | acc_t *head, *tail;
|
---|
| 1209 |
|
---|
| 1210 | /* Fast check if the buffer is aligned already. */
|
---|
| 1211 | if (acc->acc_length >= size)
|
---|
| 1212 | {
|
---|
| 1213 | ptr= ptr2acc_data(acc);
|
---|
| 1214 | if (((unsigned)ptr & (alignment-1)) == 0)
|
---|
| 1215 | return acc;
|
---|
| 1216 | }
|
---|
| 1217 | buf_size= bf_bufsize(acc);
|
---|
| 1218 | #ifdef bf_align
|
---|
| 1219 | assert((size != 0 && buf_size != 0) ||
|
---|
| 1220 | (printf("bf_align(..., %d, %d) from %s, %d\n",
|
---|
| 1221 | size, alignment, clnt_file, clnt_line),0));
|
---|
| 1222 | #else
|
---|
| 1223 | assert(size != 0 && buf_size != 0);
|
---|
| 1224 | #endif
|
---|
| 1225 | if (buf_size <= size)
|
---|
| 1226 | {
|
---|
| 1227 | acc= bf_pack(acc);
|
---|
| 1228 | return acc;
|
---|
| 1229 | }
|
---|
| 1230 | head= bf_cut(acc, 0, size);
|
---|
| 1231 | tail= bf_cut(acc, size, buf_size-size);
|
---|
| 1232 | bf_afree(acc);
|
---|
| 1233 | head= bf_pack(head);
|
---|
| 1234 | assert(head->acc_next == NULL);
|
---|
| 1235 | head->acc_next= tail;
|
---|
| 1236 | return head;
|
---|
| 1237 | }
|
---|
| 1238 |
|
---|
| 1239 | #if 0
|
---|
| 1240 | int chk_acc(acc)
|
---|
| 1241 | acc_t *acc;
|
---|
| 1242 | {
|
---|
| 1243 | int acc_nr;
|
---|
| 1244 |
|
---|
| 1245 | if (!acc)
|
---|
| 1246 | return 1;
|
---|
| 1247 | if (acc < accessors || acc >= &accessors[ACC_NR])
|
---|
| 1248 | return 0;
|
---|
| 1249 | acc_nr= acc-accessors;
|
---|
| 1250 | return acc == &accessors[acc_nr];
|
---|
| 1251 | }
|
---|
| 1252 | #endif
|
---|
| 1253 |
|
---|
| 1254 | /*
|
---|
| 1255 | * $PchId: buf.c,v 1.19 2003/09/10 08:54:23 philip Exp $
|
---|
| 1256 | */
|
---|