|
|
1.1 ! root 1: #define _DDI_DKI 1 ! 2: #define _SYSV4 1 ! 3: ! 4: ! 5: /* ! 6: * Functions related to device polling support in the DDI/DKI. ! 7: */ ! 8: /* ! 9: *-IMPORTS: ! 10: * <common/ccompat.h> ! 11: * __USE_PROTO__ ! 12: * __ARGS () ! 13: * <kernel/ddi_cpu.h> ! 14: * ddi_cpu_data () ! 15: * <kernel/ddi_glob.h> ! 16: * ddi_global_data () ! 17: * <kernel/ddi_lock.h> ! 18: * pollglob_hierarchy ! 19: * pollglob_priority ! 20: * pollhead_hierarchy ! 21: * pollhead_priority ! 22: * pollwait_hierarchy ! 23: * pollwait_priority ! 24: * <sys/debug.h> ! 25: * ASSERT () ! 26: * <sys/kmem.h> ! 27: * KM_SLEEP ! 28: * kmem_alloc () ! 29: * kmem_free () ! 30: * <sys/ksynch.h> ! 31: * lkinfo_t ! 32: * LOCK () ! 33: * LOCK_ALLOC () ! 34: * LOCK_DEALLOC () ! 35: * SV_ALLOC () ! 36: * SV_DEALLOC () ! 37: * SV_WAIT_SIG () ! 38: * UNLOCK () ! 39: * <sys/errno.h> ! 40: * EAGAIN ! 41: */ ! 42: ! 43: #include <common/ccompat.h> ! 44: #include <kernel/ddi_cpu.h> ! 45: #include <kernel/ddi_glob.h> ! 46: #include <kernel/ddi_lock.h> ! 47: #include <sys/debug.h> ! 48: #include <sys/kmem.h> ! 49: #include <sys/ksynch.h> ! 50: #include <sys/errno.h> ! 51: ! 52: #include <sys/inline.h> ! 53: #include <stddef.h> ! 54: #include <limits.h> ! 55: ! 56: #include <common/_poll.h> ! 57: #include <sys/poll.h> ! 58: #include <poll.h> ! 59: #include <stropts.h> ! 60: ! 61: ! 62: /* ! 63: * The definition of the "pollhead" structure is kept private to this source ! 64: * file to avoid the temptation for other code to look at its members or ! 65: * allocate their own. ! 66: * ! 67: * Since we want to keep things fast, we use a circular-list scheme here, ! 68: * unlike most other places lists are maintained. For the DDI/DKI polling ! 69: * system, this is not a problem because list head items are allocated via ! 70: * phalloc (), which ensures that they are properly set up. For the old-style ! 71: * Coherent versions, we hope that they have been initialised to NULL and try ! 72: * and detect when they need setting up properly. ! 73: * ! 74: * The 'event_t' structure used in old-style Coherent polling is defined in ! 75: * <sys/poll.h>. ! 76: */ ! 77: ! 78: typedef struct pollwait pwait_t; ! 79: typedef struct pollev pevent_t; ! 80: typedef struct pollhead phead_t; ! 81: ! 82: ! 83: /* ! 84: * For DDI/DKI polling, drivers get to deal in terms of a head of a list of ! 85: * events. ! 86: */ ! 87: ! 88: struct pollhead { ! 89: poll_t ph_node; ! 90: lock_t * ph_lock; ! 91: }; ! 92: ! 93: ! 94: /* ! 95: * Structure of a polled event for DDI/DKI polling. Since these structures are ! 96: * allocated from a pool in the "pollwait" structure, there is no explicit ! 97: * per-process linkage between events. ! 98: */ ! 99: ! 100: struct pollev { ! 101: poll_t pe_node; ! 102: pwait_t * pe_pwait; ! 103: phead_t * pe_head; ! 104: short pe_events; ! 105: }; ! 106: ! 107: ! 108: #if _OLD_COH_POLLING ! 109: ! 110: /* ! 111: * For old-style polling, we need a cell per event being waited on; however, ! 112: * since old-style polling only supported POLLIN, POLLOUT, and POLLPRI there ! 113: * is a small upper bound on the number we need. ! 114: */ ! 115: ! 116: typedef struct old_poll o_event_t; ! 117: ! 118: struct old_poll { ! 119: poll_t op_node; ! 120: pwait_t * op_pwait; ! 121: }; ! 122: ! 123: #endif /* _OLD_COH_POLLING */ ! 124: ! 125: ! 126: /* ! 127: * A polling process allocates a 'pollwait' structure and goes to sleep on it ! 128: * after checking with all the items being polled. The 'pollwait' structure ! 129: * records if any events have been triggered after being checked but before ! 130: * the process has actually gone to sleep (ie, when it is checking other ! 131: * devices). ! 132: */ ! 133: ! 134: enum { ! 135: PW_POLLING, ! 136: PW_SLEEPING, ! 137: PW_WOKEN ! 138: }; ! 139: ! 140: ! 141: struct pollwait { ! 142: lock_t * pw_lock; ! 143: sv_t * pw_sleep; ! 144: int pw_sleeping; ! 145: ! 146: pevent_t * pw_events; ! 147: int pw_nevents; ! 148: ! 149: size_t pw_size; /* allocated size of structure */ ! 150: ! 151: #if _OLD_COH_POLLING ! 152: /* ! 153: * The old-style events are allocated down from the top of the same ! 154: * chunk of memory used for the new-style events. 'pw_oevents' is the ! 155: * current base and is moved down each time a new entry is allocated. ! 156: */ ! 157: ! 158: o_event_t * pw_oevents; ! 159: int pw_noevents; ! 160: #endif /* _OLD_COH_POLLING */ ! 161: }; ! 162: ! 163: ! 164: /* ! 165: * Declare the lock information structures at file scope. ! 166: */ ! 167: ! 168: __LOCAL__ lkinfo_t _pollhead_lkinfo = { ! 169: "polling pollhead lock", INTERNAL_LOCK ! 170: }; ! 171: ! 172: __LOCAL__ lkinfo_t _pollwait_lkinfo = { ! 173: "polling pollwait lock", INTERNAL_LOCK ! 174: }; ! 175: ! 176: ! 177: /* ! 178: * Utility routine to initialize a 'pnode' for use as a circular list head. ! 179: */ ! 180: ! 181: #define INIT_PNODE(pnp) ((pnp)->pn_next = (pnp)->pn_prev = (pnp)) ! 182: ! 183: ! 184: /* ! 185: * Currently, we store the user's "pollwait" structure in the per-CPU data ! 186: * area. However, it seems prudent to encapsulate this fact. Note that the ! 187: * case to "pwait_t *" in GET_POLLWAIT () exists to satisfy PC-Lint's notion ! 188: * of strong typing. ! 189: */ ! 190: ! 191: #define GET_POLLWAIT() ((pwait_t *) ddi_cpu_data ()->dc_pollwait) ! 192: #define SET_POLLWAIT(pw) (void) (ddi_cpu_data ()->dc_pollwait = (pw)) ! 193: ! 194: ! 195: /* ! 196: * Some macros to save typing given the long, descriptive names of the lock- ! 197: * related constants. ! 198: */ ! 199: ! 200: #define POLLWAIT_LOCK(pw) LOCK ((pw)->pw_lock, pollwait_priority) ! 201: #define POLLWAIT_UNLOCK(pw,p) UNLOCK ((pw)->pw_lock, (p)) ! 202: ! 203: #define POLLHEAD_LOCK(ph) LOCK ((ph)->ph_lock, pollhead_priority) ! 204: #define POLLHEAD_UNLOCK(ph,p) UNLOCK ((ph)->ph_lock, (p)) ! 205: ! 206: #define POLL_GLOBAL_LOCK() LOCK (ddi_global_data ()->dg_polllock, \ ! 207: poll_global_priority) ! 208: #define POLL_GLOBAL_UNLOCK(p) UNLOCK (ddi_global_data ()->dg_polllock, (p)) ! 209: ! 210: ! 211: #if 1 ! 212: ! 213: /* ! 214: * Utility routine to fetch the address of the 'pollwait' structure allocated ! 215: * by the currently polling process, with extra checking. ! 216: */ ! 217: ! 218: #if __USE_PROTO__ ! 219: __LOCAL__ pwait_t * (GET_POLLWAIT) (void) ! 220: #else ! 221: __LOCAL__ pwait_t * ! 222: GET_POLLWAIT __ARGS (()) ! 223: #endif ! 224: { ! 225: pwait_t * pwaitp; ! 226: ! 227: /* ! 228: * Since the current 'pollwait' value is recorded in the per-CPU data ! 229: * area, no locking is really necessary to ensure atomic access to the ! 230: * data. Actually, this might not be true for some CPUs such as Intel ! 231: * 80x86's, but access to the value is only defined within certain ! 232: * limited contexts anyway. ! 233: * ! 234: * Note that we cast from a "struct pollwait *" to a "pwait_t *" in ! 235: * order to be able to satisfy PC-lint's strong typing. ! 236: */ ! 237: ! 238: pwaitp = GET_POLLWAIT (); ! 239: ! 240: ASSERT (pwaitp != NULL); ! 241: ! 242: return pwaitp; ! 243: } ! 244: ! 245: #undef GET_POLLWAIT ! 246: ! 247: #endif ! 248: ! 249: ! 250: /* ! 251: * Utility routine to deal with signalling an event to a process that has ! 252: * begun polling (but may not have gone to sleep yet). ! 253: */ ! 254: ! 255: #if __USE_PROTO__ ! 256: void (POLL_WAKE) (pwait_t * pwaitp) ! 257: #else ! 258: void ! 259: POLL_WAKE __ARGS ((pwaitp)) ! 260: pwait_t * pwaitp; ! 261: #endif ! 262: { ! 263: pl_t prev_pl; ! 264: ! 265: prev_pl = POLLWAIT_LOCK (pwaitp); ! 266: ! 267: if (pwaitp->pw_sleeping == PW_SLEEPING) ! 268: SV_SIGNAL (pwaitp->pw_sleep, 0); ! 269: ! 270: pwaitp->pw_sleeping = PW_WOKEN; ! 271: ! 272: POLLWAIT_UNLOCK (pwaitp, prev_pl); ! 273: } ! 274: ! 275: ! 276: #if _OLD_COH_POLLING ! 277: /* ! 278: * The original Coherent polling system allocated event records at the time of ! 279: * the first call to pollopen () based on a patchable variable. If the ! 280: * patchable value was 0, then more event cells would be allocated (in blocks ! 281: * of 32) on demand and added to the event cell pool. ! 282: * ! 283: * In the new system, event cells are allocated at the time of entry to the ! 284: * poll () system call, meaning that there is some fixed allocation overhead ! 285: * per system call but that the event cells will be returned to a general ! 286: * pool. ! 287: */ ! 288: ! 289: ! 290: /* ! 291: * This function (called by old-style device drivers) requests an association ! 292: * between the polling process and the device's list of polling processes. The ! 293: * contents of the list head and the method of association are opaque, except ! 294: * for the "e_procp" member of the event cell and the fact that the list head ! 295: * structure is used directly in data structure declarations in the driver ! 296: * rather than being managed by constructor/destructor routines. ! 297: * ! 298: * To get around the initialization problems, we must assume that such driver ! 299: * structures will be initially zero-filled. ! 300: * ! 301: * Callable ONLY from base level within a Coherent old-style device-driver ! 302: * poll () entry point. ! 303: */ ! 304: ! 305: #if __USE_PROTO__ ! 306: void (pollopen) (event_t * elistp) ! 307: #else ! 308: void ! 309: pollopen __ARGS ((elistp)) ! 310: event_t * elistp; ! 311: #endif ! 312: { ! 313: pwait_t * pwaitp = GET_POLLWAIT (); ! 314: o_event_t * eventp; ! 315: pl_t prev_pl; ! 316: ! 317: /* ! 318: * Detect a zero-filled (hence uninitialised) list head. We use the ! 319: * circular list property to detect initialization. ! 320: */ ! 321: ! 322: if (elistp->e_node.pn_next == NULL) ! 323: INIT_PNODE (& elistp->e_node); ! 324: ! 325: /* ! 326: * Take an event from the 'pollwait' structure. ! 327: */ ! 328: ! 329: eventp = -- pwaitp->pw_oevents; ! 330: pwaitp->pw_noevents ++; ! 331: ! 332: ASSERT ((pevent_t *) eventp > & pwaitp->pw_events [pwaitp->pw_nevents]); ! 333: ! 334: /* ! 335: * String it all together. We use interrupt priority level to protect ! 336: * the insertion, because code that uses this code isn't going to be ! 337: * multiprocessor-safe anyway. ! 338: */ ! 339: ! 340: eventp->op_pwait = pwaitp; /* link to polling process */ ! 341: ! 342: prev_pl = splhi (); ! 343: ! 344: eventp->op_node.pn_next = elistp->e_node.pn_next; ! 345: eventp->op_node.pn_prev = & elistp->e_node; ! 346: eventp->op_node.pn_next->pn_prev = & eventp->op_node; ! 347: elistp->e_node.pn_next = & eventp->op_node; ! 348: ! 349: /* ! 350: * Set the magic flag. ! 351: */ ! 352: ! 353: elistp->e_procp = (__VOID__ *) 1; ! 354: ! 355: (void) splx (prev_pl); ! 356: } ! 357: ! 358: ! 359: /* ! 360: * This routine signals all the polling processes that have been queued on ! 361: * this event list by pollopen () that an event they are interested in has ! 362: * occurred. ! 363: */ ! 364: ! 365: #if __USE_PROTO__ ! 366: void (pollwake) (event_t * elistp) ! 367: #else ! 368: void ! 369: pollwake __ARGS ((elistp)) ! 370: event_t * elistp; ! 371: #endif ! 372: { ! 373: poll_t * pnodep; ! 374: ! 375: /* ! 376: * Since we have to maintain the magic header flag, we may as well use ! 377: * it as well. ! 378: */ ! 379: ! 380: if (elistp->e_procp == 0) ! 381: return; ! 382: ! 383: elistp->e_procp = 0; ! 384: ! 385: ! 386: /* ! 387: * Service circularly-linked polls on device queue. It may be that the ! 388: * driver's circular list has not yet been initialized. ! 389: * ! 390: * We don't take out a lock because this system doesn't support them, ! 391: * and we don't need to manipulate interrupts because we don't modify ! 392: * the structure. ! 393: */ ! 394: ! 395: if ((pnodep = elistp->e_node.pn_next) != NULL) { ! 396: /* ! 397: * We detect the end of the list when the circular walk has ! 398: * taken us back to the list head. ! 399: */ ! 400: ! 401: while (pnodep != & elistp->e_node) { ! 402: /* ! 403: * Downcast from the node to the queued event cell, ! 404: * and wake the process. ! 405: */ ! 406: ! 407: POLL_WAKE (__DOWNCAST (o_event_t, op_node, ! 408: pnodep)->op_pwait); ! 409: ! 410: pnodep = pnodep->pn_next; ! 411: } ! 412: } ! 413: } ! 414: ! 415: ! 416: /* ! 417: * This routine cleans up any old-style events. ! 418: */ ! 419: ! 420: #if __USE_PROTO__ ! 421: __LOCAL__ void (oldpollclean) (o_event_t * oevents, int noevents) ! 422: #else ! 423: __LOCAL__ void ! 424: oldpollclean __ARGS ((oevents, noevents)) ! 425: o_event_t * oevents; ! 426: int noevents; ! 427: #endif ! 428: { ! 429: pl_t prev_pl; ! 430: ! 431: ASSERT (oevents != NULL); ! 432: ! 433: /* ! 434: * Iterate over the list of queued old-style events and dequeue each ! 435: * one. ! 436: */ ! 437: ! 438: prev_pl = splhi (); ! 439: ! 440: while (noevents > 0) { ! 441: ! 442: oevents->op_node.pn_next->pn_prev = oevents->op_node.pn_prev; ! 443: oevents->op_node.pn_prev->pn_next = oevents->op_node.pn_next; ! 444: ! 445: noevents --; ! 446: oevents ++; ! 447: } ! 448: ! 449: splx (prev_pl); ! 450: } ! 451: ! 452: #endif /* _OLD_COH_POLLING */ ! 453: ! 454: ! 455: /* ! 456: *-STATUS: ! 457: * DDI/DKI ! 458: * ! 459: *-NAME: ! 460: * phalloc Allocate and initialize a pollhead structure. ! 461: * ! 462: *-SYNOPSIS: ! 463: * #include <sys/poll.h> ! 464: * #include <sys/kmem.h> ! 465: * ! 466: * struct pollhead * phalloc (int flag); ! 467: * ! 468: *-ARGUMENTS: ! 469: * flag Specifies whether the caller is willing to sleep ! 470: * waiting for memory. If "flag" is set to "KM_SLEEP", ! 471: * the caller will sleep if necessary until sufficient ! 472: * memory is available. If "flag" is set to "KM_NOSLEEP", ! 473: * the caller will not sleep, but phalloc () will return ! 474: * NULL if sufficient memory is not immediately ! 475: * available. ! 476: * ! 477: *-DESCRIPTION: ! 478: * phalloc () allocates and initializes a "pollhead" structure for use by ! 479: * non-STREAMS character drivers that wish to support polling. The "flag" ! 480: * argument indicates whether the caller is willing to sleep waiting for ! 481: * memory as described above. ! 482: * ! 483: *-RETURN VALUE: ! 484: * Upon successful completion, phalloc () returns a pointer to the newly ! 485: * allocated "pollhead" structure. If "KM_NOSLEEP" is specified and ! 486: * sufficient memory is not immediately available, phalloc () returns a ! 487: * NULL pointer. ! 488: * ! 489: *-LEVEL: ! 490: * Base only if "flag" is set to "KM_SLEEP". Base or interrupt if "flag" ! 491: * is set to "KM_NOSLEEP". ! 492: * ! 493: *-NOTES: ! 494: * May sleep if slag is set to "KM_SLEEP". ! 495: * ! 496: * Driver-defined basic locks and read/write locks may be held across ! 497: * calls to this function if "flag" is "KM_NOSLEEP" but may not be held ! 498: * if "flag" is "KM_SLEEP". ! 499: * ! 500: * Driver-defined sleep locks may be held across calls to this function ! 501: * regardless of the value of "flag". ! 502: * ! 503: * DDI/DKI conforming drivers may only use "pollhead" structures which ! 504: * have been allocated and initialized using phalloc (). Use of ! 505: * "pollhead" structures which have been obtained by any other means is ! 506: * prohibited. ! 507: * ! 508: *-SEE ALSO: ! 509: * phfree (), pollwakeup () ! 510: */ ! 511: ! 512: #if __USE_PROTO__ ! 513: struct pollhead * (phalloc) (int flag) ! 514: #else ! 515: struct pollhead * ! 516: phalloc __ARGS ((flag)) ! 517: int flag; ! 518: #endif ! 519: { ! 520: struct pollhead * php; ! 521: ! 522: if ((php = (struct pollhead *) kmem_alloc (sizeof (* php), flag)) ! 523: != NULL) { ! 524: ! 525: if ((php->ph_lock = LOCK_ALLOC (pollhead_hierarchy, ! 526: pollhead_priority, ! 527: & _pollhead_lkinfo, ! 528: flag)) == NULL) { ! 529: kmem_free (php, sizeof (* php)); ! 530: return NULL; ! 531: } ! 532: ! 533: INIT_PNODE (& php->ph_node); ! 534: } ! 535: ! 536: return php; ! 537: } ! 538: ! 539: ! 540: /* ! 541: *-STATUS: ! 542: * DDI/DKI ! 543: * ! 544: *-NAME: ! 545: * phfree Free a pollhead structure. ! 546: * ! 547: *-SYNOPSIS: ! 548: * #include <sys/poll.h> ! 549: * ! 550: * void phfree (struct pollhead * php); ! 551: * ! 552: *-ARGUMENTS: ! 553: * php Pointer to the "pollhead" structure to be freed. The ! 554: * structure pointed to by "php" must have been ! 555: * previously allocated by a call to phalloc (). ! 556: * ! 557: *-DESCRIPTION: ! 558: * phfree () frees the "pollhead" structure specified by "php". ! 559: * ! 560: *-RETURN VALUE: ! 561: * None. ! 562: * ! 563: *-LEVEL: ! 564: * Base or interrupt. ! 565: * ! 566: *-NOTES: ! 567: * Does not sleep. ! 568: * ! 569: * Driver-defined basic locks, read/write locks, and sleep locks may be ! 570: * held across calls to this function. ! 571: * ! 572: * DDI/DKI conforming drivers may only use "pollhead" structures which ! 573: * have been allocated and initialized using phalloc (). Use of ! 574: * "pollhead" structures which have been obtained by any other means is ! 575: * prohibited. ! 576: * ! 577: *-SEE ALSO: ! 578: * phalloc (), pollwakeup () ! 579: */ ! 580: ! 581: #if __USE_PROTO__ ! 582: void (phfree) (struct pollhead * php) ! 583: #else ! 584: void ! 585: phfree __ARGS ((php)) ! 586: struct pollhead * php; ! 587: #endif ! 588: { ! 589: poll_t * pnodep; ! 590: poll_t * next; ! 591: ! 592: ASSERT (php != NULL); ! 593: ! 594: /* ! 595: * Since phalloc () and phfree () are not constrained to be used only ! 596: * in driver open/close routines, the possibility exists for a poll ! 597: * head structure to be deallocated while processes are waiting on it. ! 598: * This isn't very desirable, but it seems to be legal. ! 599: * ! 600: * After acquiring the global lock, we request a lock on the pollhead ! 601: * structure to ensure that all activity on the structure has ! 602: * completed before we begin to tear it down. Since the caller has ! 603: * requested deallocation of the structure, the caller should be ! 604: * confident that no-one will try and access it after any current ! 605: * activity has ceased. ! 606: * ! 607: * We engage in some subterfuge here in order to create a situation ! 608: * where we can detect any mistaken access. ! 609: */ ! 610: ! 611: ! 612: { ! 613: pl_t prev_pl; ! 614: lock_t * lock = php->ph_lock; ! 615: ! 616: prev_pl = POLL_GLOBAL_LOCK (); ! 617: (void) LOCK (lock, pollhead_priority); ! 618: ! 619: php->ph_lock = NULL; ! 620: ! 621: POLL_GLOBAL_UNLOCK (pollhead_priority); ! 622: UNLOCK (lock, prev_pl); ! 623: ! 624: LOCK_DEALLOC (lock); ! 625: } ! 626: ! 627: ! 628: /* ! 629: * Walking over an entire circular list removing all the queue nodes ! 630: * allows a few simple optimizations; because we will be touching ! 631: * *every* node an dequeueing it, we don't need to engage in any ! 632: * real manipulation of the first/next nodes. In fact, since we almost ! 633: * immediately deallocate the structure, we don't have to touch the ! 634: * list head at all. ! 635: */ ! 636: ! 637: next = php->ph_node.pn_next; ! 638: ! 639: while ((pnodep = next) != & php->ph_node) { ! 640: /* ! 641: * Doing this ensures that multiple attempts to dequeue this ! 642: * node (such as from the process polling cleanup routine) ! 643: * will have no effect. We could use the "pe_events" member of ! 644: * the event structure for this, but that would need a ! 645: * downcast and probably wouldn't result in higher ! 646: * performance. ! 647: */ ! 648: ! 649: next = pnodep->pn_next; ! 650: pnodep->pn_prev = pnodep->pn_next = pnodep; ! 651: } ! 652: ! 653: kmem_free (php, sizeof (* php)); ! 654: } ! 655: ! 656: ! 657: /* ! 658: *-STATUS: ! 659: * DDI/DKI ! 660: * ! 661: *-NAME: ! 662: * pollwakeup Inform polling process that an event has occurred. ! 663: * ! 664: *-SYNOPSIS: ! 665: * #include <sys/poll.h> ! 666: * ! 667: * void pollwakeup (struct pollhead * php, short event); ! 668: * ! 669: *-ARGUMENTS: ! 670: * php Pointer to a "pollhead" structure. ! 671: * ! 672: * event Event to notify the process about. ! 673: * ! 674: *-DESCRIPTION: ! 675: * The pollwakeup () function provides non-STREAMS character drivers with ! 676: * a way to notify processes polling for the occurrence of an event. ! 677: * pollwakeup () should be called from the driver for each occurrence of ! 678: * an event. ! 679: * ! 680: * The "pollhead" structure will usually be associated with the driver's ! 681: * private data structure for the particular minor device where the event ! 682: * has occurred. ! 683: * ! 684: *-RETURN VALUE: ! 685: * None. ! 686: * ! 687: *-LEVEL: ! 688: * Base or interrupt. ! 689: * ! 690: *-NOTES: ! 691: * Does not sleep. ! 692: * ! 693: * Driver-defined basic locks, read/write locks, and sleep locks may be ! 694: * held across calls to this function. ! 695: * ! 696: * pollwakeup () should only be called with one event at a time. ! 697: * ! 698: *-SEE ALSO: ! 699: * phalloc (), phfree () ! 700: */ ! 701: ! 702: #if __USE_PROTO__ ! 703: void (pollwakeup) (struct pollhead * php, short event) ! 704: #else ! 705: void ! 706: pollwakeup __ARGS ((php, event)) ! 707: struct pollhead * php; ! 708: short event; ! 709: #endif ! 710: { ! 711: poll_t * pnodep; ! 712: poll_t * next; ! 713: pl_t prev_pl; ! 714: ! 715: ASSERT (php != NULL); ! 716: ASSERT (event == POLLIN || event == POLLPRI || event == POLLOUT || ! 717: event == POLLRDNORM || event == POLLWRNORM || ! 718: event == POLLRDBAND || event == POLLWRBAND || ! 719: event == POLLERR || event == POLLHUP); ! 720: ! 721: /* ! 722: * Acquire a lock on the pollhead structure after getting a global ! 723: * lock on the polling system. ! 724: */ ! 725: ! 726: prev_pl = POLL_GLOBAL_LOCK (); ! 727: ! 728: POLLHEAD_LOCK (php); ! 729: ! 730: POLL_GLOBAL_UNLOCK (pollhead_priority); ! 731: ! 732: ! 733: /* ! 734: * Scan the list of queued processes and wake up (and dequeue) any ! 735: * that are waiting for the event being signalled. ! 736: */ ! 737: ! 738: next = php->ph_node.pn_next; ! 739: ! 740: while ((pnodep = next) != & php->ph_node) { ! 741: pevent_t * eventp; ! 742: ! 743: next = pnodep->pn_next; ! 744: eventp = __DOWNCAST (pevent_t, pe_node, pnodep); ! 745: ! 746: if ((eventp->pe_events & event) != 0) { ! 747: ! 748: POLL_WAKE (eventp->pe_pwait); ! 749: ! 750: /* ! 751: * Perform a full general dequeue, and also change ! 752: * the node pointers so that a second request to ! 753: * dequeue the node has no effect. ! 754: */ ! 755: ! 756: next->pn_prev = pnodep->pn_prev; ! 757: pnodep->pn_prev->pn_next = next; ! 758: ! 759: pnodep->pn_prev = pnodep->pn_next = pnodep; ! 760: } ! 761: } ! 762: ! 763: POLLHEAD_UNLOCK (php, prev_pl); ! 764: } ! 765: ! 766: ! 767: /* ! 768: * This internal function allocates and initializes a 'pollwait' structure on ! 769: * behalf of a process that wants to perform polling operations. The 'fds' ! 770: * argument specifies the number of devices/streams that are being polled. ! 771: * ! 772: * The newly-allocated structure is recorded in the per-CPU DDI/DKI data area, ! 773: * so that it is an error for the caller to sleep between a call to pwalloc () ! 774: * and a call to pwsleep (). ! 775: * ! 776: * The return value is 0 on success, or an error number on failure (due to ! 777: * insufficient kernel memory). This function may sleep for memory to become ! 778: * available. Callable from base level only. ! 779: */ ! 780: ! 781: #define _max(a,b) ((a) < (b) ? (b) : (a)) ! 782: ! 783: enum { ! 784: #if _OLD_COH_POLLING ! 785: cellsize = _max (sizeof (pevent_t), 3 * sizeof (o_event_t)) ! 786: #else ! 787: cellsize = sizeof (pevent_t) ! 788: #endif ! 789: }; ! 790: ! 791: #if __USE_PROTO__ ! 792: int (pwalloc) (int fds) ! 793: #else ! 794: int ! 795: pwalloc __ARGS ((fds)) ! 796: int fds; ! 797: #endif ! 798: { ! 799: size_t size; ! 800: pwait_t * pwaitp; ! 801: ! 802: ASSERT (fds >= 0 && fds < INT_MAX / cellsize); ! 803: ASSERT (GET_POLLWAIT () == NULL); ! 804: ! 805: /* ! 806: * How much memory to allocate; we assume that at most three old-style ! 807: * event cells could be allocated per stream, or one new event cell. ! 808: */ ! 809: ! 810: size = fds * cellsize + sizeof (pwait_t); ! 811: ! 812: if ((pwaitp = (pwait_t *) kmem_alloc (size, KM_SLEEP)) != NULL) { ! 813: ! 814: if ((pwaitp->pw_lock = ! 815: LOCK_ALLOC (pollwait_hierarchy, ! 816: pollwait_priority, ! 817: & _pollwait_lkinfo, ! 818: KM_SLEEP)) != NULL) { ! 819: if ((pwaitp->pw_sleep = SV_ALLOC (KM_SLEEP)) ! 820: != NULL) { ! 821: ! 822: ASSERT (GET_POLLWAIT () == NULL); ! 823: ! 824: pwaitp->pw_sleeping = PW_POLLING; ! 825: pwaitp->pw_events = (pevent_t *) (pwaitp + 1); ! 826: pwaitp->pw_nevents = 0; ! 827: pwaitp->pw_size = size; ! 828: #if _OLD_COH_POLLING ! 829: pwaitp->pw_oevents = (o_event_t *) ! 830: ((char *) pwaitp + size); ! 831: pwaitp->pw_noevents = 0; ! 832: #endif ! 833: SET_POLLWAIT (pwaitp); ! 834: return 0; ! 835: } ! 836: ! 837: LOCK_DEALLOC (pwaitp->pw_lock); ! 838: } ! 839: ! 840: kmem_free (pwaitp, size); ! 841: } ! 842: ! 843: return EAGAIN; ! 844: } ! 845: ! 846: ! 847: /* ! 848: * This internal function is used by user-level polling code to go to sleep ! 849: * after checking with each device being polled (thus registering any event ! 850: * cells as necessary). ! 851: * ! 852: * May sleep. Callable from base level only. Returns 0 if woken by an ! 853: * indication that an event has occurred, or 1 if woken by a signal. ! 854: */ ! 855: ! 856: #if __USE_PROTO__ ! 857: int (pollsleep) (void) ! 858: #else ! 859: int ! 860: pollsleep __ARGS (()) ! 861: #endif ! 862: { ! 863: pwait_t * pwaitp = GET_POLLWAIT (); ! 864: int sigwake = 0; ! 865: ! 866: ASSERT (pwaitp != NULL); ! 867: ! 868: /* ! 869: * Lock the structure before checking to see whether we want to go ! 870: * to sleep or not. ! 871: */ ! 872: ! 873: (void) POLLWAIT_LOCK (pwaitp); ! 874: ! 875: if (pwaitp->pw_sleeping == PW_POLLING) { ! 876: /* ! 877: * No events were triggered while we were scanning all the ! 878: * requested channels, so we do actually have to sleep. ! 879: */ ! 880: ! 881: SET_POLLWAIT (NULL); ! 882: pwaitp->pw_sleeping = PW_SLEEPING; ! 883: ! 884: sigwake = SV_WAIT_SIG (pwaitp->pw_sleep, prilo, ! 885: pwaitp->pw_lock) == 0; ! 886: ! 887: ASSERT (GET_POLLWAIT () == NULL); ! 888: ! 889: pwaitp->pw_sleeping = PW_WOKEN; ! 890: SET_POLLWAIT (pwaitp); ! 891: } else { ! 892: ! 893: ASSERT (pwaitp->pw_sleeping == PW_WOKEN); ! 894: ! 895: POLLWAIT_UNLOCK (pwaitp, plbase); ! 896: } ! 897: ! 898: return sigwake; ! 899: } ! 900: ! 901: ! 902: /* ! 903: * This local function deals with dequeuing event cells from device polling ! 904: * lists. ! 905: */ ! 906: ! 907: #if __USE_PROTO__ ! 908: __LOCAL__ void (pollclean) (pevent_t * events, int nevents) ! 909: #else ! 910: __LOCAL__ void ! 911: pollclean __ARGS ((events, nevents)) ! 912: pevent_t * events; ! 913: int nevents; ! 914: #endif ! 915: { ! 916: pl_t prev_pl; ! 917: ! 918: ASSERT (events != NULL); ! 919: ! 920: /* ! 921: * Iterate over the list of queued events and dequeue each one. ! 922: */ ! 923: ! 924: while (nevents > 0) { ! 925: ! 926: prev_pl = POLLHEAD_LOCK (events->pe_head); ! 927: ! 928: events->pe_node.pn_next->pn_prev = events->pe_node.pn_prev; ! 929: events->pe_node.pn_prev->pn_next = events->pe_node.pn_next; ! 930: ! 931: POLLHEAD_UNLOCK (events->pe_head, prev_pl); ! 932: ! 933: nevents --; ! 934: events ++; ! 935: } ! 936: } ! 937: ! 938: ! 939: /* ! 940: * This function destroys and deallocates all the resources taken up by a ! 941: * user poll-wait structure. ! 942: */ ! 943: ! 944: #if __USE_PROTO__ ! 945: void (pwfree) (void) ! 946: #else ! 947: void ! 948: pwfree __ARGS (()) ! 949: #endif ! 950: { ! 951: pwait_t * pwaitp = GET_POLLWAIT (); ! 952: ! 953: ASSERT (pwaitp != NULL); ! 954: ! 955: #if _OLD_COH_POLLING ! 956: oldpollclean (pwaitp->pw_oevents, pwaitp->pw_noevents); ! 957: #endif ! 958: ! 959: pollclean (pwaitp->pw_events, pwaitp->pw_nevents); ! 960: ! 961: /* ! 962: * Now there is no way that an interrupt-level context could try and ! 963: * access the pollwait structure, we can safely deallocate it. ! 964: */ ! 965: ! 966: SV_DEALLOC (pwaitp->pw_sleep); ! 967: ! 968: LOCK_DEALLOC (pwaitp->pw_lock); ! 969: ! 970: kmem_free (pwaitp, pwaitp->pw_size); ! 971: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.