|
|
1.1 ! root 1: /* $Header: /y/coh.386/RCS/poll.c,v 1.3 93/04/14 10:06:42 root Exp $ */ ! 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.3 93/04/14 10:06:42 root ! 26: * r75 ! 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: * Go through extra step of deferring the pollwake to avoid race condition ! 157: * (in case interrupt handler does a pollwake() during upoll()). ! 158: */ ! 159: pollwake(qp) ! 160: event_t * qp; ! 161: { ! 162: void dpollwake(); ! 163: ! 164: defer(dpollwake, qp); ! 165: } ! 166: ! 167: void ! 168: dpollwake(qp) ! 169: event_t * qp; ! 170: { ! 171: register event_t * ep = qp; ! 172: register PROC * pp; ! 173: ! 174: /* ! 175: * Clear device process pointer, indicating poll completed. ! 176: * NOTE: interrupt handlers may have already cleared it. ! 177: */ ! 178: qp->e_procp = 0; ! 179: ! 180: if (ep = qp->e_dnext) { ! 181: ! 182: /* ! 183: * Service circularly-linked polls on device queue. ! 184: */ ! 185: while (ep != qp) { ! 186: /* ! 187: * Wake process if it is sleeping. ! 188: */ ! 189: if ((pp = ep->e_procp) && ASLEEP(pp)) ! 190: wakeup(&pp->p_polls); ! 191: ! 192: ep = ep->e_dnext; ! 193: } ! 194: } ! 195: } ! 196: ! 197: /** ! 198: * ! 199: * int ! 200: * pollexit() -- terminate all polls opened by current process ! 201: */ ! 202: int ! 203: pollexit() ! 204: { ! 205: register PROC * pp = cprocp; ! 206: register event_t * ep; ! 207: ! 208: /* ! 209: * Service all polling event buffers enabled by current process. ! 210: */ ! 211: while (ep = pp->p_polls) { ! 212: ! 213: /* ! 214: * Remove event buffer from circularly-linked device queue. ! 215: */ ! 216: (ep->e_dnext->e_dlast = ep->e_dlast)->e_dnext = ep->e_dnext; ! 217: ! 218: /* ! 219: * Remove event buffer from singularly-linked process queue. ! 220: */ ! 221: pp->p_polls = ep->e_pnext; ! 222: ! 223: /* ! 224: * Insert event buffer at head of free event buffer queue. ! 225: */ ! 226: ep->e_pnext = efreep; ! 227: efreep = ep; ! 228: } ! 229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.