?? buf.c
字號:
/*
This file contains routines for buffer management.
*/
#include "inet.h"
#include <stdlib.h>
#include <string.h>
#include "generic/assert.h"
#include "generic/buf.h"
#include "generic/type.h"
INIT_PANIC();
#if TRACE_ENQUEUE_PROBLEM
extern enqueue_problem;
#endif
#define USE_MALLOCS 0
#ifndef BUF512_NR
#define BUF512_NR (sizeof(int) == 2 ? 40 : 128)
#endif
#define ACC_NR 200
#define CLIENT_NR 5
typedef struct buf512
{
buf_t buf_header;
char buf_data[512];
} buf512_t;
#if USE_MALLOCS
PRIVATE buf512_t *buffers512;
PRIVATE acc_t *accessors;
#else
PRIVATE buf512_t buffers512[BUF512_NR];
PRIVATE acc_t accessors[ACC_NR];
#endif
PRIVATE buf512_t *buf512_free;
PRIVATE bf_freereq_t freereq[CLIENT_NR];
PRIVATE size_t bf_buf_gran;
PRIVATE acc_t *acc_free_list;
PUBLIC size_t bf_free_buffsize;
PUBLIC acc_t *bf_temporary_acc;
#ifdef bf_memreq
PUBLIC char *bf_memreq_file;
PUBLIC int bf_memreq_line;
#endif
#ifdef bf_cut
PUBLIC char *bf_cut_file;
PUBLIC int bf_cut_line;
#endif
#ifdef bf_packIffLess
PUBLIC char *bf_pack_file;
PUBLIC int bf_pack_line;
#endif
#ifdef bf_bufsize
PUBLIC char *bf_bufsize_file;
PUBLIC int bf_bufsize_line;
#endif
FORWARD acc_t *bf_small_memreq ARGS(( size_t size ));
FORWARD void bf_512free ARGS(( buf_t *buffer ));
PUBLIC void bf_init()
{
int i;
size_t size;
size_t buf_s;
bf_buf_gran= BUF_S;
buf_s= 0;
#if USE_MALLOCS
printf("buf.c: malloc %d 32K-buffers (%dK)\n", BUF32K_NR,
sizeof(*buffers32K) * BUF32K_NR / 1024);
buffers32K= malloc(sizeof(*buffers32K) * BUF32K_NR);
if (!buffers32K)
ip_panic(( "unable to alloc 32K-buffers" ));
printf("buf.c: malloc %d 2K-buffers (%dK)\n", BUF2K_NR,
sizeof(*buffers2K) * BUF2K_NR / 1024);
buffers2K= malloc(sizeof(*buffers2K) * BUF2K_NR);
if (!buffers2K)
ip_panic(( "unable to alloc 2K-buffers" ));
printf("buf.c: malloc %d 512-buffers (%dK)\n", BUF512_NR,
sizeof(*buffers512) * BUF512_NR / 1024);
buffers512= malloc(sizeof(*buffers512) * BUF512_NR);
if (!buffers512)
ip_panic(( "unable to alloc 512-buffers" ));
printf("buf.c: malloc %d accessors (%dK)\n", ACC_NR,
sizeof(*accessors) * ACC_NR / 1024);
accessors= malloc(sizeof(*accessors) * ACC_NR);
if (!accessors)
ip_panic(( "unable to alloc accessors" ));
#endif
for (i=0;i<BUF512_NR;i++)
{
buffers512[i].buf_header.buf_linkC= 0;
buffers512[i].buf_header.buf_next= &buffers512[i+1];
buffers512[i].buf_header.buf_free= bf_512free;
buffers512[i].buf_header.buf_size= sizeof(buffers512[i].
buf_data);
buffers512[i].buf_header.buf_data_p= buffers512[i].buf_data;
}
buffers512[i-1].buf_header.buf_next= 0;
buf512_free= &buffers512[0];
if (sizeof(buffers512[0].buf_data) < bf_buf_gran)
bf_buf_gran= sizeof(buffers512[0].buf_data);
if (sizeof(buffers512[0].buf_data) > buf_s)
buf_s= sizeof(buffers512[0].buf_data);
for (i=0;i<ACC_NR;i++)
{
accessors[i].acc_linkC= 0;
accessors[i].acc_next= &accessors[i+1];
}
acc_free_list= accessors;
accessors[i-1].acc_next= 0;
for (i=0;i<CLIENT_NR;i++)
freereq[i]=0;
assert (buf_s == BUF_S);
}
PUBLIC void bf_logon(func)
bf_freereq_t func;
{
int i;
for (i=0;i<CLIENT_NR;i++)
if (!freereq[i])
{
freereq[i]=func;
return;
}
ip_panic(( "buf.c: to many clients" ));
}
/*
bf_memreq
*/
#ifndef bf_memreq
PUBLIC acc_t *bf_memreq(size)
#else
PUBLIC acc_t *_bf_memreq(size)
#endif
size_t size;
{
acc_t *head, *tail, *new_acc;
int i,j;
size_t count;
#if TRACE_ENQUEUE_PROBLEM
{ if (enqueue_problem)
{ where(); printf("bf_memreq(%d) called with enqueue_problem\n", size); } }
#endif
#ifdef bf_memreq
{ where(); printf("bf_memreq(%d) called by %s, %d\n", size, bf_memreq_file,
bf_memreq_line); }
#endif
assert (size>0);
head= NULL;
while (size)
{
if (!acc_free_list)
{
#if DEBUG
{ where(); printf("freeing accessors\n"); }
#endif
for (i=0; !acc_free_list && i<MAX_BUFREQ_PRI; i++)
{
for (j=0; !acc_free_list && j<CLIENT_NR; j++)
{
bf_free_buffsize= 0;
if (freereq[j])
(*freereq[j])(i, BUF_S);
}
}
}
if (!acc_free_list)
ip_panic(( "To few accessors" ));
new_acc= acc_free_list;
acc_free_list= acc_free_list->acc_next;
#if DEBUG & 256
{ where(); printf("got accessor %d\n", new_acc-accessors); }
#endif
new_acc->acc_linkC= 1;
new_acc->acc_buffer= 0;
#if DEBUG & 256
{ where(); printf("looking for 512 byte buffer\n"); }
#endif
if (buf512_free)
{
buf512_t *buf512;
#if DEBUG & 256
{ where(); printf("found a 512 byte buffer\n"); }
#endif
buf512= buf512_free;
buf512_free= buf512->buf_header.buf_next;
assert (!buf512->buf_header.buf_linkC);
buf512->buf_header.buf_linkC= 1;
assert (buf512->buf_header.buf_free == bf_512free);
assert (buf512->buf_header.buf_size == sizeof(buf512->buf_data));
assert (buf512->buf_header.buf_data_p == buf512->buf_data);
new_acc->acc_buffer= &buf512->buf_header;
buf512->buf_header.buf_next= buf512;
}
#if DEBUG
else
{ where(); printf("unable to find a 512 byte buffer\n"); }
#endif
if (!new_acc->acc_buffer)
{
#if DEBUG
{ where(); printf("freeing buffers\n"); }
#endif
bf_free_buffsize= 0;
for (i=0; bf_free_buffsize<size && i<MAX_BUFREQ_PRI;
i++)
for (j=0; bf_free_buffsize<size && j<CLIENT_NR;
j++)
if (freereq[j])
(*freereq[j])(i, size);
if (bf_free_buffsize<size)
ip_panic(( "not enough buffers freed" ));
continue;
}
if (!head)
head= new_acc;
else
tail->acc_next= new_acc;
tail= new_acc;
count= tail->acc_buffer->buf_size;
if (count > size)
count= size;
tail->acc_offset= 0;
tail->acc_length= count;
size -= count;
}
tail->acc_next= 0;
#if DEBUG
bf_chkbuf(head);
#endif
#if DEBUG & 256
{ where(); printf("acc 0x%x has buffer 0x%x\n", head, head->acc_buffer); }
#endif
return head;
}
/*
bf_small_memreq
*/
PRIVATE acc_t *bf_small_memreq(size)
size_t size;
{
acc_t *head, *tail, *new_acc;
int i,j;
size_t count;
#if TRACE_ENQUEUE_PROBLEM
{ if (enqueue_problem)
{ where(); printf("bf_small_memreq(%d) called with enqueue_problem\n", size);
} }
#endif
#if DEBUG & 256
{ where(); printf("bf_small_memreq(%d)\n", size); }
#endif
assert (size>0);
head= NULL;
while (size)
{
if (!acc_free_list)
{
#if DEBUG
{ where(); printf("freeing accessors\n"); }
#endif
for (i=0; !acc_free_list && i<MAX_BUFREQ_PRI; i++)
{
for (j=0; !acc_free_list && j<CLIENT_NR; j++)
{
bf_free_buffsize= 0;
if (freereq[j])
(*freereq[j])(i, BUF_S);
}
}
}
new_acc= acc_free_list;
if (!new_acc)
ip_panic(( "buf.c: out of accessors" ));
acc_free_list= new_acc->acc_next;
#if DEBUG & 256
{ where(); printf("got accessor %d\n", new_acc-accessors); }
#endif
new_acc->acc_linkC= 1;
if (size >= sizeof(buf512_free->buf_data))
{
if (buf512_free)
{
buf512_t *buf512;
#if DEBUG & 256
{ where(); printf("found a 512 byte buffer\n"); }
#endif
buf512= buf512_free;
buf512_free= buf512->buf_header.buf_next;
assert (!buf512->buf_header.buf_linkC);
buf512->buf_header.buf_linkC= 1;
assert (buf512->buf_header.buf_free == bf_512free);
assert (buf512->buf_header.buf_size == sizeof(buf512->buf_data));
assert (buf512->buf_header.buf_data_p == buf512->buf_data);
new_acc->acc_buffer= &buf512->buf_header;
buf512->buf_header.buf_next= buf512;
}
else
break;
}
else
break;
if (!head)
head= new_acc;
else
tail->acc_next= new_acc;
tail= new_acc;
count= tail->acc_buffer->buf_size;
if (count > size)
count= size;
tail->acc_offset= 0;
tail->acc_length= count;
size -= count;
}
if (size)
{
new_acc->acc_linkC= 0;
new_acc->acc_next= acc_free_list;
acc_free_list= new_acc;
new_acc= bf_memreq(size);
if (!head)
head= new_acc;
else
tail->acc_next= new_acc;
}
else
tail->acc_next= 0;
return head;
}
PUBLIC void bf_afree(acc_ptr)
acc_t *acc_ptr;
{
acc_t *tmp_acc;
buf_t *tmp_buf;
while (acc_ptr)
{
assert (acc_ptr->acc_linkC);
acc_ptr->acc_linkC--;
if (!acc_ptr->acc_linkC)
{
tmp_buf= acc_ptr->acc_buffer;
assert (tmp_buf);
assert (tmp_buf->buf_linkC);
if (!--tmp_buf->buf_linkC)
{
bf_free_buffsize += tmp_buf->buf_size;
tmp_buf->buf_free(tmp_buf);
}
tmp_acc= acc_ptr;
acc_ptr= acc_ptr->acc_next;
tmp_acc->acc_next= acc_free_list;
acc_free_list= tmp_acc;
}
else
break;
}
}
PUBLIC acc_t *bf_dupacc(acc_ptr)
register acc_t *acc_ptr;
{
register acc_t *new_acc;
int i, j;
#if TRACE_ENQUEUE_PROBLEM
{ if (enqueue_problem)
{ where(); printf("bf_dupacc(0x%x) called with enqueue_problem\n", acc_ptr);
} }
#endif
if (!acc_free_list)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -