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