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