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