File:  [MW Coherent from dump] / coherent / d / PS2_KERNEL / coh.386 / poll.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/* $Header: /var/lib/cvsd/repos/coherent/coherent/d/PS2_KERNEL/coh.386/poll.c,v 1.1.1.1 2019/05/29 04:56:39 root Exp $ */
/*
 *	The  information  contained herein  is a trade secret  of INETCO
 *	Systems, and is confidential information.   It is provided under
 *	a license agreement,  and may be copied or disclosed  only under
 *	the terms of that agreement.   Any reproduction or disclosure of
 *	this  material  without  the express  written  authorization  of
 *	INETCO Systems or persuant to the license agreement is unlawful.
 *
 *	Copyright (c) 1986
 *	An unpublished work by INETCO Systems, Ltd.
 *	All rights reserved.
 */

/*
 * [Stream] Polling.
 *
 *	void pollinit( ) -- allocate polling buffers
 *	int pollopen(qp) -- enable polling  by current process  on given queue
 *	int pollwake(qp) -- wake all processes waiting for poll on given queue
 *	int pollexit(  ) -- terminate all polls enabled by current process
 *	event_t * ep;
 *
 * $Log: poll.c,v $
 * Revision 1.1.1.1  2019/05/29 04:56:39  root
 * coherent
 *
 * Revision 1.2  92/08/04  12:34:05  bin
 * changed for ker 59
 * 
 * Revision 1.2  92/01/06  11:59:56  hal
 * Compile with cc.mwc.
 * 
 * Revision 1.1	88/03/24  16:14:10	src
 * Initial revision
 * 
 * 86/11/19	Allan Cornish		/usr/src/sys/coh/poll.c
 * Ported to Coherent from RTX.
 */

#include <sys/coherent.h>
#include <sys/proc.h>

/*
 * Patchable data.
 */
int	NPOLL  = 0;

/*
 * Private data.
 */
static	event_t	* efreep;

/**
 *
 * event_t *
 * pollinit()		-- allocate event buffers.
 */
event_t *
pollinit()
{
	register event_t * ep;
	register event_t * ap;
	static int first = 1;

	/*
	 * If dynamically growing event pool is specified [NPOLL == 0],
	 * try to allocate an additional cluster of 32 on each call.
	 */
	if ( NPOLL == 0 ) {
		if ( ep = kalloc( 32 * sizeof(event_t) ) )
			ap = ep + 32;
	}

	/*
	 * If statically sized event pool is specified [NPOLL != 0],
	 * try to allocate the pool on the first call.
	 */
	else if ( first ) {
		first = 0;
		if ( ep = kalloc( NPOLL * sizeof(event_t) ) )
			ap = ep + NPOLL;
	}

	/*
	 * If event cluster was allocated, insert into free event queue.
	 */
	if ( ep ) {
		do {
			ep->e_pnext = efreep;
			efreep = ep;
		} while ( ++ep < ap );
	}

	return efreep;
}

/**
 *
 * int
 * pollopen(qp) -- enable polling by current process on given event queue
 * event_t * qp;
 */
pollopen( qp )
register event_t * qp;
{
	register event_t * ep;

	/*
	 * Initialize device queue if required.
	 */
	if ( qp->e_dnext == 0 )
		qp->e_dnext = qp->e_dlast = qp;

	/*
	 * Obtain a free event buffer, or return.
	 */
	if ( ((ep = efreep) == 0) && ((ep = pollinit()) == 0) ) {
		printf("out of poll buffers\n");
		return;
	}

	/*
	 * Remove event buffer from free queue.
	 */
	efreep = ep->e_pnext;

	/*
	 * Record process pointer in event buffer.
	 */
	ep->e_procp = cprocp;

	/*
	 * Insert event at head of process event singularly-linked queue.
	 */
	ep->e_pnext = cprocp->p_polls;
	cprocp->p_polls = ep;

	/*
	 * Insert event at tail of circularly-linked device queue.
	 * This ensures that processes are first-in first-out.
	 */
	ep->e_dnext  = qp;
	(ep->e_dlast = qp->e_dlast)->e_dnext = ep;
	qp->e_dlast  = ep;

	/*
	 * Record last process to enable polling on device.
	 */
	qp->e_procp = cprocp;
}

/**
 *
 * int
 * pollwake( qp ) -- wake all processes waiting for poll on given queue
 * event_t * qp;
 */
pollwake( qp )
event_t * qp;
{
	register event_t * ep = qp;
	register PROC    * pp;

	/*
	 * Clear device process pointer, indicating poll completed.
	 * NOTE: interrupt handlers may have already cleared it.
	 */
	qp->e_procp = 0;

	if ( ep = qp->e_dnext ) {

		/*
		 * Service circularly-linked polls on device queue.
		 */
		while ( ep != qp ) {
			/*
			 * Wake process if it is sleeping.
			 */
			if ( (pp = ep->e_procp) && (pp->p_state == PSSLEEP) )
				wakeup( &pp->p_polls );

			ep = ep->e_dnext;
		}
	}
}

/**
 *
 * int
 * pollexit() -- terminate all polls opened by current process
 */
int
pollexit()
{
	register PROC    * pp = cprocp;
	register event_t * ep;

	/*
	 * Service all polling event buffers enabled by current process.
	 */
	while ( ep = pp->p_polls ) {

		/*
		 * Remove event buffer from circularly-linked device queue.
		 */
		(ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext;

		/*
		 * Remove event buffer from singularly-linked process queue.
		 */
		pp->p_polls = ep->e_pnext;

		/*
		 * Insert event buffer at head of free event buffer queue.
		 */
		ep->e_pnext = efreep;
		efreep = ep;
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.