|
|
1.1 ! root 1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/poll.c,v 1.4 91/07/24 07:51:32 bin Exp Locker: bin $ */ ! 2: /* ! 3: * The information contained herein is a trade secret of INETCO ! 4: * Systems, and is confidential information. It is provided under ! 5: * a license agreement, and may be copied or disclosed only under ! 6: * the terms of that agreement. Any reproduction or disclosure of ! 7: * this material without the express written authorization of ! 8: * INETCO Systems or persuant to the license agreement is unlawful. ! 9: * ! 10: * Copyright (c) 1986 ! 11: * An unpublished work by INETCO Systems, Ltd. ! 12: * All rights reserved. ! 13: */ ! 14: ! 15: /* ! 16: * [Stream] Polling. ! 17: * ! 18: * void pollinit( ) -- allocate polling buffers ! 19: * int pollopen(qp) -- enable polling by current process on given queue ! 20: * int pollwake(qp) -- wake all processes waiting for poll on given queue ! 21: * int pollexit( ) -- terminate all polls enabled by current process ! 22: * event_t * ep; ! 23: * ! 24: * $Log: poll.c,v $ ! 25: * Revision 1.4 91/07/24 07:51:32 bin ! 26: * update prov by hal ! 27: * ! 28: * ! 29: * Revision 1.1 88/03/24 16:14:10 src ! 30: * Initial revision ! 31: * ! 32: * 86/11/19 Allan Cornish /usr/src/sys/coh/poll.c ! 33: * Ported to Coherent from RTX. ! 34: */ ! 35: ! 36: #include <sys/coherent.h> ! 37: #include <sys/proc.h> ! 38: #include <sys/uproc.h> ! 39: ! 40: /* ! 41: * Patchable data. ! 42: */ ! 43: int NPOLL = 0; ! 44: ! 45: /* ! 46: * Private data. ! 47: */ ! 48: static event_t * efreep; ! 49: ! 50: /** ! 51: * ! 52: * event_t * ! 53: * pollinit() -- allocate event buffers. ! 54: */ ! 55: event_t * ! 56: pollinit() ! 57: { ! 58: register event_t * ep; ! 59: register event_t * ap; ! 60: static int first = 1; ! 61: ! 62: /* ! 63: * If dynamically growing event pool is specified [NPOLL == 0], ! 64: * try to allocate an additional cluster of 32 on each call. ! 65: */ ! 66: if ( NPOLL == 0 ) { ! 67: if ( ep = kalloc( 32 * sizeof(event_t) ) ) ! 68: ap = ep + 32; ! 69: } ! 70: ! 71: /* ! 72: * If statically sized event pool is specified [NPOLL != 0], ! 73: * try to allocate the pool on the first call. ! 74: */ ! 75: else if ( first ) { ! 76: first = 0; ! 77: if ( ep = kalloc( NPOLL * sizeof(event_t) ) ) ! 78: ap = ep + NPOLL; ! 79: } ! 80: ! 81: /* ! 82: * If event cluster was allocated, insert into free event queue. ! 83: */ ! 84: if ( ep ) { ! 85: do { ! 86: ep->e_pnext = efreep; ! 87: efreep = ep; ! 88: } while ( ++ep < ap ); ! 89: } ! 90: ! 91: return efreep; ! 92: } ! 93: ! 94: /** ! 95: * ! 96: * int ! 97: * pollopen(qp) -- enable polling by current process on given event queue ! 98: * event_t * qp; ! 99: */ ! 100: pollopen( qp ) ! 101: register event_t * qp; ! 102: { ! 103: register event_t * ep; ! 104: ! 105: /* ! 106: * Initialize device queue if required. ! 107: */ ! 108: if ( qp->e_dnext == 0 ) ! 109: qp->e_dnext = qp->e_dlast = qp; ! 110: ! 111: /* ! 112: * Obtain a free event buffer, or return. ! 113: */ ! 114: if ( ((ep = efreep) == 0) && ((ep = pollinit()) == 0) ) { ! 115: printf("out of poll buffers\n"); ! 116: return; ! 117: } ! 118: ! 119: /* ! 120: * Remove event buffer from free queue. ! 121: */ ! 122: efreep = ep->e_pnext; ! 123: ! 124: /* ! 125: * Record process pointer in event buffer. ! 126: */ ! 127: ep->e_procp = cprocp; ! 128: ! 129: /* ! 130: * Insert event at head of process event singularly-linked queue. ! 131: */ ! 132: ep->e_pnext = cprocp->p_polls; ! 133: cprocp->p_polls = ep; ! 134: ! 135: /* ! 136: * Insert event at tail of circularly-linked device queue. ! 137: * This ensures that processes are first-in first-out. ! 138: */ ! 139: ep->e_dnext = qp; ! 140: (ep->e_dlast = qp->e_dlast)->e_dnext = ep; ! 141: qp->e_dlast = ep; ! 142: ! 143: /* ! 144: * Record last process to enable polling on device. ! 145: */ ! 146: qp->e_procp = cprocp; ! 147: } ! 148: ! 149: /** ! 150: * ! 151: * int ! 152: * pollwake( qp ) -- wake all processes waiting for poll on given queue ! 153: * event_t * qp; ! 154: */ ! 155: pollwake( qp ) ! 156: event_t * qp; ! 157: { ! 158: register event_t * ep = qp; ! 159: register PROC * pp; ! 160: ! 161: /* ! 162: * Clear device process pointer, indicating poll completed. ! 163: * NOTE: interrupt handlers may have already cleared it. ! 164: */ ! 165: qp->e_procp = 0; ! 166: ! 167: if ( ep = qp->e_dnext ) { ! 168: ! 169: /* ! 170: * Service circularly-linked polls on device queue. ! 171: */ ! 172: while ( ep != qp ) { ! 173: /* ! 174: * Wake process if it is sleeping. ! 175: */ ! 176: if ( (pp = ep->e_procp) && (pp->p_state == PSSLEEP) ) ! 177: wakeup( &pp->p_polls ); ! 178: ! 179: ep = ep->e_dnext; ! 180: } ! 181: } ! 182: } ! 183: ! 184: /** ! 185: * ! 186: * int ! 187: * pollexit() -- terminate all polls opened by current process ! 188: */ ! 189: int ! 190: pollexit() ! 191: { ! 192: register PROC * pp = cprocp; ! 193: register event_t * ep; ! 194: ! 195: /* ! 196: * Service all polling event buffers enabled by current process. ! 197: */ ! 198: while ( ep = pp->p_polls ) { ! 199: ! 200: /* ! 201: * Remove event buffer from circularly-linked device queue. ! 202: */ ! 203: (ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext; ! 204: ! 205: /* ! 206: * Remove event buffer from singularly-linked process queue. ! 207: */ ! 208: pp->p_polls = ep->e_pnext; ! 209: ! 210: /* ! 211: * Insert event buffer at head of free event buffer queue. ! 212: */ ! 213: ep->e_pnext = efreep; ! 214: efreep = ep; ! 215: } ! 216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.