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

📄 tty_subr.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1994, David Greenman * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $\Id: tty_subr.c,v 1.10.4.4 1996/04/08 01:28:10 davidg Exp $ *//* * clist support routines */#include <sys/param.h>#include <sys/systm.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <sys/clist.h>#include <sys/malloc.h>struct cblock *cfreelist = 0;int cfreecount = 0;static int cslushcount;static int ctotcount;#ifndef INITIAL_CBLOCKS#define	INITIAL_CBLOCKS 50#endifstatic void cblock_alloc_cblocks __P((int number));static void cblock_free_cblocks __P((int number));#define	CBLOCK_DIAG#ifdef CBLOCK_DIAGstatic voidcbstat(){	printf(	"tot = %d (active = %d, free = %d (reserved = %d, slush = %d))\n",	       ctotcount * CBSIZE, ctotcount * CBSIZE - cfreecount, cfreecount,	       cfreecount - cslushcount * CBSIZE, cslushcount * CBSIZE);}#endif/* * Called from init_main.c */voidclist_init(){	/*	 * Allocate an initial base set of cblocks as a 'slush'.	 * We allocate non-slush cblocks with each initial ttyopen() and	 * deallocate them with each ttyclose().	 * We should adjust the slush allocation.  This can't be done in	 * the i/o routines because they are sometimes called from	 * interrupt handlers when it may be unsafe to call malloc().	 */	cblock_alloc_cblocks(cslushcount = INITIAL_CBLOCKS);}/* * Remove a cblock from the cfreelist queue and return a pointer * to it. */static inline struct cblock *cblock_alloc(){	struct cblock *cblockp;	cblockp = cfreelist;	if (cblockp == NULL)		panic("clist reservation botch");	cfreelist = cblockp->c_next;	cblockp->c_next = NULL;	cfreecount -= CBSIZE;	return (cblockp);}/* * Add a cblock to the cfreelist queue. */static inline voidcblock_free(cblockp)	struct cblock *cblockp;{	if (isset(cblockp->c_quote, CBQSIZE * NBBY - 1))		bzero(cblockp->c_quote, sizeof cblockp->c_quote);	cblockp->c_next = cfreelist;	cfreelist = cblockp;	cfreecount += CBSIZE;}/* * Allocate some cblocks for the cfreelist queue. */static voidcblock_alloc_cblocks(number)	int number;{	int i;	struct cblock *cbp;	for (i = 0; i < number; ++i) {		cbp = malloc(sizeof *cbp, M_TTYS, M_WAITOK);		/*		 * Freed cblocks have zero quotes and garbage elsewhere.		 * Set the may-have-quote bit to force zeroing the quotes.		 */		setbit(cbp->c_quote, CBQSIZE * NBBY - 1);		cblock_free(cbp);	}	ctotcount += number;}/* * Set the cblock allocation policy for a a clist. * Must be called in process context at spltty(). */voidclist_alloc_cblocks(clistp, ccmax, ccreserved)	struct clist *clistp;	int ccmax;	int ccreserved;{	int dcbr;	/*	 * Allow for wasted space at the head.	 */	if (ccmax != 0)		ccmax += CBSIZE - 1;	if (ccreserved != 0)		ccreserved += CBSIZE - 1;	clistp->c_cbmax = roundup(ccmax, CBSIZE) / CBSIZE;	dcbr = roundup(ccreserved, CBSIZE) / CBSIZE - clistp->c_cbreserved;	if (dcbr >= 0)		cblock_alloc_cblocks(dcbr);	else {		if (clistp->c_cbreserved + dcbr < clistp->c_cbcount)			dcbr = clistp->c_cbcount - clistp->c_cbreserved;		cblock_free_cblocks(-dcbr);	}	clistp->c_cbreserved += dcbr;}/* * Free some cblocks from the cfreelist queue back to the * system malloc pool. */static voidcblock_free_cblocks(number)	int number;{	int i;	for (i = 0; i < number; ++i)		free(cblock_alloc(), M_TTYS);	ctotcount -= number;}/* * Free the cblocks reserved for a clist. * Must be called at spltty(). */voidclist_free_cblocks(clistp)	struct clist *clistp;{	if (clistp->c_cbcount != 0)		panic("freeing active clist cblocks");	cblock_free_cblocks(clistp->c_cbreserved);	clistp->c_cbmax = 0;	clistp->c_cbreserved = 0;}/* * Get a character from the head of a clist. */intgetc(clistp)	struct clist *clistp;{	int chr = -1;	int s;	struct cblock *cblockp;	s = spltty();	/* If there are characters in the list, get one */	if (clistp->c_cc) {		cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND);		chr = (u_char)*clistp->c_cf;		/*		 * If this char is quoted, set the flag.		 */		if (isset(cblockp->c_quote, clistp->c_cf - (char *)cblockp->c_info))			chr |= TTY_QUOTE;		/*		 * Advance to next character.		 */		clistp->c_cf++;		clistp->c_cc--;		/*		 * If we have advanced the 'first' character pointer		 * past the end of this cblock, advance to the next one.		 * If there are no more characters, set the first and		 * last pointers to NULL. In either case, free the		 * current cblock.		 */		if ((clistp->c_cf >= (char *)(cblockp+1)) || (clistp->c_cc == 0)) {			if (clistp->c_cc > 0) {				clistp->c_cf = cblockp->c_next->c_info;			} else {				clistp->c_cf = clistp->c_cl = NULL;			}			cblock_free(cblockp);			if (--clistp->c_cbcount >= clistp->c_cbreserved)				++cslushcount;		}	}	splx(s);	return (chr);}/* * Copy 'amount' of chars, beginning at head of clist 'clistp' to * destination linear buffer 'dest'. Return number of characters * actually copied. */intq_to_b(clistp, dest, amount)	struct clist *clistp;	char *dest;	int amount;{	struct cblock *cblockp;	struct cblock *cblockn;	char *dest_orig = dest;	int numc;	int s;	s = spltty();	while (clistp && amount && (clistp->c_cc > 0)) {		cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND);		cblockn = cblockp + 1; /* pointer arithmetic! */		numc = min(amount, (char *)cblockn - clistp->c_cf);		numc = min(numc, clistp->c_cc);		bcopy(clistp->c_cf, dest, numc);		amount -= numc;		clistp->c_cf += numc;		clistp->c_cc -= numc;		dest += numc;		/*		 * If this cblock has been emptied, advance to the next		 * one. If there are no more characters, set the first		 * and last pointer to NULL. In either case, free the		 * current cblock.		 */		if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {			if (clistp->c_cc > 0) {				clistp->c_cf = cblockp->c_next->c_info;			} else {				clistp->c_cf = clistp->c_cl = NULL;			}			cblock_free(cblockp);			if (--clistp->c_cbcount >= clistp->c_cbreserved)				++cslushcount;		}	}	splx(s);	return (dest - dest_orig);}/* * Flush 'amount' of chars, beginning at head of clist 'clistp'. */voidndflush(clistp, amount)	struct clist *clistp;	int amount;{	struct cblock *cblockp;	struct cblock *cblockn;	int numc;	int s;	s = spltty();	while (amount && (clistp->c_cc > 0)) {		cblockp = (struct cblock *)((long)clistp->c_cf & ~CROUND);		cblockn = cblockp + 1; /* pointer arithmetic! */		numc = min(amount, (char *)cblockn - clistp->c_cf);		numc = min(numc, clistp->c_cc);		amount -= numc;		clistp->c_cf += numc;		clistp->c_cc -= numc;		/*		 * If this cblock has been emptied, advance to the next		 * one. If there are no more characters, set the first		 * and last pointer to NULL. In either case, free the		 * current cblock.		 */		if ((clistp->c_cf >= (char *)cblockn) || (clistp->c_cc == 0)) {			if (clistp->c_cc > 0) {				clistp->c_cf = cblockp->c_next->c_info;			} else {				clistp->c_cf = clistp->c_cl = NULL;			}			cblock_free(cblockp);			if (--clistp->c_cbcount >= clistp->c_cbreserved)				++cslushcount;		}	}	splx(s);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -