⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buf.c

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
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 + -