Annotation of coherent/b/STREAMS/conf/streams/src/poll.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.