Annotation of coherent/b/STREAMS/conf_79/streams/v_proc.c, revision 1.1.1.1

1.1       root        1: #define        _DDI_DKI        1
                      2: #define        _DDI_DKI_IMPL   1
                      3: #define        _SYSV3          1
                      4: 
                      5: /*
                      6:  * This file contains the implementations of the abstract scheduling
                      7:  * interface functions defined in <sys/v_proc.h>.
                      8:  *
                      9:  * The functions defined here are used only by the code that needs to sleep
                     10:  * processes to implement the DDI/DKI sleep lock and synchronization variable
                     11:  * functionality. The code here has been broken out into a separate file and
                     12:  * a formal interface specified purely to separate the abstract and
                     13:  * implementation-dependent aspects of the DDI/DKI locking functions, ie to
                     14:  * stop the original code being infected with #ifdefs.
                     15:  *
                     16:  * This module runs in the _SYSV3 compilation mode to interface with the iBCS2
                     17:  * Coherent kernel.
                     18:  */
                     19: 
                     20: /*
                     21:  *-IMPORTS:
                     22:  *     <common/ccompat.h>
                     23:  *             __CONST__
                     24:  *             __USE_PROTO__
                     25:  *             __ARGS ()
                     26:  *     <common/xdebug.h>
                     27:  *             __LOCAL__
                     28:  *     <kernel/ddi_proc.h>
                     29:  *             ddi_proc_data ()
                     30:  *     <kernel/ddi_glob.h>
                     31:  *             ddi_global_data ()
                     32:  *     <kernel/ddi_lock.h>
                     33:  *             proc_global_priority
                     34:  *     <sys/debug.h>
                     35:  *             ASSERT ()
                     36:  *     <sys/types.h>
                     37:  *             plhi
                     38:  *     <sys/inline.h>
                     39:  *             splbase ()
                     40:  *     <sys/ksynch.h>
                     41:  *             LOCK ()
                     42:  *             UNLOCK ()
                     43:  *     <sys/signal.h>
                     44:  *             SIGTSTP
                     45:  */
                     46: 
                     47: #include <common/ccompat.h>
                     48: #include <common/xdebug.h>
                     49: #include <kernel/ddi_proc.h>
                     50: #include <kernel/ddi_glob.h>
                     51: #include <kernel/ddi_lock.h>
                     52: #include <sys/debug.h>
                     53: #include <sys/types.h>
                     54: #include <sys/inline.h>
                     55: #include <sys/ksynch.h>
                     56: #include <sys/signal.h>
                     57: #include <stddef.h>
                     58: 
                     59: #include <kernel/v_proc.h>
                     60: 
                     61: /*
                     62:  * Type used in comparisons of process priority.
                     63:  */
                     64: 
                     65: typedef        unsigned short  pri_t;
                     66: 
                     67: 
                     68: #define        PROCESS_PNODE()         (& ddi_proc_data ()->dp_pnode)
                     69: 
                     70: 
                     71: /*
                     72:  * Here we deal with the implementation-specifics.
                     73:  */
                     74: 
                     75: #if    __COHERENT__
                     76: 
                     77: #define        __KERNEL__      2
                     78: #include <sys/sched.h>
                     79: #undef __KERNEL__
                     80: 
                     81: #define        PNODE_TO_PROC(pnode)    __DOWNCAST (PROC, p_nigel, \
                     82:                                      __DOWNCAST (dpdata_t, dp_pnode, pnode))
                     83: 
                     84: 
                     85: /*
                     86:  * Implementation-specific version of KERNEL_SLEEP ().
                     87:  */
                     88: 
                     89: #if    __USE_PROTO__
                     90: __LOCAL__ int (KERNEL_SLEEP) (plist_t * plistp, int priority, int flag)
                     91: #else
                     92: __LOCAL__ int
                     93: (KERNEL_SLEEP) __ARGS ((plistp, priority, flag))
                     94: plist_t              * plistp;
                     95: int            priority;
                     96: int            flag;
                     97: #endif
                     98: {
                     99:        pnode_t       * pnode = PROCESS_PNODE ();
                    100:        int             state;
                    101: 
                    102:        /*
                    103:         * Since Coherent's signal-checking causes a longjump out to the
                    104:         * top-level, we'll check for signals here ourself.
                    105:         */
                    106: 
                    107:        if (flag == SLEEP_INTERRUPTIBLE && nondsig ()) {
                    108:                /*
                    109:                 * We have pending signals that need processing, dequeue us
                    110:                 * from the plist, ulock the plist, and return an appropriate
                    111:                 * indication to the caller.
                    112:                 */
                    113: 
                    114:                plistp->pl_head = pnode->pn_next;
                    115:                pnode->pn_next->pn_prev = NULL;
                    116: 
                    117:                ATOMIC_CLEAR_PTR (pnode->pn_plistp);
                    118: 
                    119:                PLIST_UNLOCK (plistp, plbase);
                    120: 
                    121:                return PROCESS_SIGNALLED;
                    122:        }
                    123: 
                    124: 
                    125:        /*
                    126:         * We expect to be running with interrupts disabled, so there's no
                    127:         * reason not to just unlock the basic lock now and use the standard
                    128:         * off-the-shelf Coherent kernel sleep function.
                    129:         */
                    130: 
                    131:        for (;;) {
                    132:                PLIST_UNLOCK (plistp, plhi);
                    133: 
                    134:                x_sleep (pnode, priority, slpriNoSig, "STREAMS");
                    135: 
                    136:                /*
                    137:                 * The Coherent kernel won't dequeue us from the process list
                    138:                 * if it awakens us via a signal, so we use that fact to
                    139:                 * figure out why we are awake (sleep () does not return any
                    140:                 * useful value).
                    141:                 *
                    142:                 * To do anything about this in a multiprocessor-friendly
                    143:                 * fashion, we have to re-acquire the process list lock.
                    144:                 */
                    145: 
                    146:                (void) PLIST_LOCK (plistp, "KERNEL_SLEEP");
                    147: 
                    148:                if (ATOMIC_FETCH_PTR (pnode->pn_plistp) == 0) {
                    149:                        state = PROCESS_NORMAL_WAKE;
                    150:                        break;  /* dequeued, normal wakeup */
                    151:                }
                    152: 
                    153: 
                    154:                /*
                    155:                 * We were signalled; our caller may have requested non-
                    156:                 * interruptible sleep, so we go back to sleep on the caller's
                    157:                 * behalf (Coherent will always wake up a sleeper on receipt
                    158:                 * of a signal).
                    159:                 */
                    160: 
                    161:                if (flag == SLEEP_INTERRUPTIBLE) {
                    162:                        /*
                    163:                         * We were woken by a signal and the caller wants to
                    164:                         * know about it, so dequeue us from the list and
                    165:                         * return the indication.
                    166:                         */
                    167: 
                    168:                        plistp->pl_head = pnode->pn_next;
                    169:                        pnode->pn_next->pn_prev = NULL;
                    170: 
                    171:                        ATOMIC_CLEAR_PTR (pnode->pn_plistp);
                    172: 
                    173:                        state = PROCESS_SIGNALLED;
                    174:                        break;
                    175:                }
                    176:        }
                    177: 
                    178:        /*
                    179:         * Since we acquired a lock on the process list in order to safely
                    180:         * test the reason why we awoke, release that lock now. Since we can,
                    181:         * we'll set the interrupt priority down low.
                    182:         */
                    183: 
                    184:        PLIST_UNLOCK (plistp, plbase);
                    185: 
                    186:        return state;
                    187: }
                    188: 
                    189: 
                    190: /*
                    191:  * Implementation-specific version of KERNEL_WAKE ().
                    192:  */
                    193: 
                    194: #if    __USE_PROTO__
                    195: __LOCAL__ void (KERNEL_WAKE) (pnode_t * pnodep)
                    196: #else
                    197: __LOCAL__ void
                    198: KERNEL_WAKE __ARGS ((pnodep))
                    199: pnode_t              * pnodep;
                    200: #endif
                    201: {
                    202:        dwakeup (pnodep);               /* don't defer this */
                    203: }
                    204: 
                    205: 
                    206: /*
                    207:  * Implementation-specific code to send a signal to a process.
                    208:  */
                    209: 
                    210: #if    __USE_PROTO__
                    211: __LOCAL__ void (KERNEL_SIGNAL) (dpdata_t * dpdatap, int sig)
                    212: #else
                    213: __LOCAL__ void
                    214: KERNEL_SIGNAL __ARGS ((dpdatap, sig))
                    215: dpdata_t      *        dpdatap;
                    216: int            sig;
                    217: #endif
                    218: {
                    219:        /*
                    220:         * Since the Coherent process management system is ... not very
                    221:         * sophisticated, and fixing it is less important than getting STREAMS
                    222:         * out the door, we punt on some issues such as process reference
                    223:         * counts and state checking. This is just glue to the old, broken
                    224:          * system.
                    225:         */
                    226: 
                    227: }
                    228: 
                    229: 
                    230: #else
                    231: 
                    232: 
                    233: uarea_t                _dos_uarea_;
                    234: proc_t         _dos_proc_;
                    235: 
                    236: #define        PNODE_TO_PROC(pnodep)   __DOWNCAST (proc_t, p_nigel, \
                    237:                                    __DOWNCAST (dpdata_t, dp_pnode, pnodep))
                    238: 
                    239: #include <sys/cmn_err.h>
                    240: #include <bios.h>
                    241: 
                    242: 
                    243: /*
                    244:  * Implementation-specific version of KERNEL_SLEEP ().
                    245:  */
                    246: 
                    247: #if    __USE_PROTO__
                    248: __LOCAL__ int (KERNEL_SLEEP) (plist_t * plistp, int priority, int flag)
                    249: #else
                    250: __LOCAL__ int
                    251: (KERNEL_SLEEP) __ARGS ((plistp, priority, flag))
                    252: plist_t              * plistp;
                    253: int            priority;
                    254: int            flag;
                    255: #endif
                    256: {
                    257:        int     state;
                    258: 
                    259: 
                    260:        CURRENT_PROCESS ()->p_state = PS_SLEEP;
                    261: 
                    262:        PLIST_UNLOCK (plistp, plhi);
                    263:        (void) splbase ();
                    264: 
                    265:        while ((state = CURRENT_PROCESS ()->p_state) != PS_RUN &&
                    266:               state != PS_SIGNALLED)
                    267:                if (_bios_keybrd (_KEYBRD_READY))
                    268:                        switch (_bios_keybrd (_KEYBRD_READ) & 0xFF) {
                    269: 
                    270:                        case 0x1B:
                    271:                                cmn_err (CE_PANIC, "Abort!");
                    272:                                break;
                    273: 
                    274:                        default:
                    275:                                break;
                    276:                        }
                    277: 
                    278:        return (state == PS_RUN ? PROCESS_NORMAL_WAKE : PROCESS_SIGNALLED);
                    279: }
                    280: 
                    281: 
                    282: /*
                    283:  * Implementation-specific version of KERNEL_WAKE ()
                    284:  */
                    285: 
                    286: #if    __USE_PROTO__
                    287: __LOCAL__ void (KERNEL_WAKE) (pnode_t * pnodep)
                    288: #else
                    289: __LOCAL__ void
                    290: KERNEL_WAKE __ARGS ((pnodep))
                    291: pnode_t              * pnodep;
                    292: #endif
                    293: {
                    294:        ASSERT (pnodep == PROCESS_PNODE ());
                    295: 
                    296:        if (CURRENT_PROCESS ()->p_state == PS_SLEEP ||
                    297:            CURRENT_PROCESS ()->p_state == PS_SLEEP_NO_SIG)
                    298:                CURRENT_PROCESS ()->p_state = PS_RUN;
                    299: }
                    300: 
                    301: 
                    302: /*
                    303:  * Implementation-specific code to send a signal to a process.
                    304:  */
                    305: 
                    306: #if    __USE_PROTO__
                    307: __LOCAL__ int (KERNEL_SIGNAL) (dpdata_t * dpdatap, int sig)
                    308: #else
                    309: __LOCAL__ int
                    310: KERNEL_SIGNAL __ARGS ((dpdatap, sig))
                    311: dpdata_t      *        dpdatap;
                    312: int            sig;
                    313: #endif
                    314: {
                    315:        if (CURRENT_PROCESS ()->p_state == PS_SLEEP)
                    316:                CURRENT_PROCESS ()->p_state = PS_SIGNALLED;
                    317: 
                    318:         return 0;
                    319: }
                    320: 
                    321: #endif
                    322: 
                    323: 
                    324: /*
                    325:  * Table to define the mapping between abstract processor priority and the
                    326:  * priority levels used in the comparisons between priority levels.
                    327:  */
                    328: 
                    329: __LOCAL__ pri_t _pri_map [] = {
                    330:        0, 1, 2, 3, 4, 5, 6,            /* prilo */
                    331:        7, 8, 9, 10, 11, 12, 13,        /* pritape */
                    332:        14, 15, 16, 17, 18, 19, 20,     /* primed */
                    333:        21, 22, 23, 24, 25, 26, 27,     /* pritty */
                    334:        28, 29, 30, 31, 32, 33, 34,     /* pridisk */
                    335:        35, 36, 37, 38, 39, 40, 41,     /* prinet */
                    336:        42, 43, 44, 45, 46, 47, 48      /* prihi */
                    337: };
                    338: 
                    339: 
                    340: 
                    341: /*
                    342:  * This function is the abstract interface used by the DDI/DKI functions to
                    343:  * invoke kernel sleep.
                    344:  *
                    345:  * This function is charged with sleeping the current process (possibly such
                    346:  * that it may be interrupted by signals). It is passed a pointer to a locked
                    347:  * process list structure on which the current process is to be threaded if
                    348:  * it is actually going to sleep. After moving the process to a "slept"
                    349:  * state and saving the process context the process list is unlocked before
                    350:  * the main kernel dispatched is invoked.
                    351:  */
                    352: 
                    353: #define        ARRAY_MAX(array)        (sizeof (array) / sizeof ((array) [0]))
                    354: 
                    355: #if    __USE_PROTO__
                    356: int (MAKE_SLEEPING) (plist_t * plistp, int priority, int flag)
                    357: #else
                    358: int
                    359: MAKE_SLEEPING __ARGS ((plistp, priority, flag))
                    360: plist_t              * plistp;
                    361: int            priority;
                    362: int            flag;
                    363: #endif
                    364: {
                    365:        pnode_t       * pnodep = PROCESS_PNODE ();
                    366:        pnode_t       * pscan;
                    367:        pnode_t       * pprev;
                    368:        unsigned        my_pri = _pri_map [priority];
                    369: 
                    370:        ASSERT (plistp != NULL);
                    371:        PLIST_ASSERT_LOCKED (plistp);
                    372: 
                    373:        ASSERT (priority >= 0 && priority < ARRAY_MAX (_pri_map));
                    374:        ASSERT (flag == SLEEP_NO_SIGNALS || flag == SLEEP_INTERRUPTIBLE);
                    375: 
                    376:        /*
                    377:         * Walk down the list of processes until one is found with a lower
                    378:         * abstract priority than the process we are going to put to sleep.
                    379:         */
                    380: 
                    381:        for (pscan = plistp->pl_head, pprev = NULL ; pscan != NULL ;
                    382:             pscan = (pprev = pscan)->pn_next) {
                    383:                /*
                    384:                 * Don't forget to map the stored priority...
                    385:                 */
                    386: 
                    387:                if (_pri_map [pscan->pn_priority] < my_pri)
                    388:                        break;
                    389:        }
                    390: 
                    391: 
                    392:        /*
                    393:         * Now insert the current process between pprev and pscan.
                    394:         */
                    395: 
                    396:        if (pprev == NULL)
                    397:                plistp->pl_head = pnodep;
                    398:        else
                    399:                pprev->pn_next = pnodep;
                    400: 
                    401:        if (pscan != NULL)
                    402:                pscan->pn_prev = pnodep;
                    403: 
                    404:        pnodep->pn_prev = pprev;
                    405:        pnodep->pn_next = pscan;
                    406: 
                    407: 
                    408:        /*
                    409:         * We store the unmapped (abstract) priority since it should make more
                    410:         * sense for a "ps"-like utility, and mapping it is cheap.
                    411:         */
                    412: 
                    413:        pnodep->pn_priority = priority;
                    414:        pnodep->pn_flag = flag;
                    415:        ATOMIC_STORE_PTR (pnodep->pn_plistp, plistp);
                    416: 
                    417: 
                    418:        /*
                    419:         * Now we are going to actually perform the low-level sleep.
                    420:         *
                    421:         * This thing gets to perform the kernel-specific bit of sleeping the
                    422:         * process, possibly with signal checks and whatnot, unlocking the
                    423:         * plist, and running the next process.
                    424:         */
                    425: 
                    426:        return KERNEL_SLEEP (plistp, priority, flag);
                    427: }
                    428: 
                    429: 
                    430: /*
                    431:  * This function wakes one of the processes queued on a plist; since the
                    432:  * MAKE_SLEEPING () function queues them in priority order, let's wake up
                    433:  * the first...
                    434:  */
                    435: 
                    436: #if    __USE_PROTO__
                    437: __VOID__ * (WAKE_ONE) (plist_t * plistp)
                    438: #else
                    439: __VOID__ *
                    440: WAKE_ONE __ARGS ((plistp))
                    441: plist_t              * plistp;
                    442: #endif
                    443: {
                    444:        pnode_t       * pnodep;
                    445: 
                    446:        ASSERT (plistp != NULL);
                    447:        PLIST_ASSERT_LOCKED (plistp);
                    448: 
                    449:        if ((pnodep = plistp->pl_head) != NULL) {
                    450:                /*
                    451:                 * Given that we have something to awaken, dequeue it and
                    452:                 * make it runnable.
                    453:                 */
                    454: 
                    455:                plistp->pl_head = pnodep->pn_next;
                    456:                pnodep->pn_next->pn_prev = NULL;
                    457: 
                    458:                KERNEL_WAKE (pnodep);
                    459: 
                    460:                /*
                    461:                 * Return the identity of the person we gave the lock to.
                    462:                 */
                    463: 
                    464:                return pnodep;
                    465:        }
                    466: 
                    467:        /*
                    468:         * Indicate that we found no-one to take over the mantle...
                    469:         */
                    470: 
                    471:        return NULL;
                    472: }
                    473: 
                    474: 
                    475: /*
                    476:  * This function wakes all of the processes queued on a plist.
                    477:  */
                    478: 
                    479: #if    __USE_PROTO__
                    480: void (WAKE_ALL) (plist_t * plistp)
                    481: #else
                    482: void
                    483: WAKE_ALL __ARGS ((plistp))
                    484: plist_t              * plistp;
                    485: #endif
                    486: {
                    487:        pnode_t       * pnodep;
                    488:        pnode_t       * pnext;
                    489: 
                    490:        ASSERT (plistp != NULL);
                    491:        PLIST_ASSERT_LOCKED (plistp);
                    492: 
                    493:        for (pnodep = plistp->pl_head ; pnodep != NULL ; pnodep = pnext) {
                    494:                /*
                    495:                 * We take the value of the "pn_next" member now, because the
                    496:                 * MAKE_RUNNABLE () call has the freedom to alter any of the
                    497:                 * members of the pnode to deal with such things as
                    498:                 * signalling.
                    499:                 */
                    500: 
                    501:                pnext = pnodep->pn_next;
                    502: 
                    503:                KERNEL_WAKE (pnodep);
                    504:        }
                    505: 
                    506:        plistp->pl_head = NULL;
                    507: }
                    508: 
                    509: 
                    510: /*
                    511:  * This function returns a value suitable for use as a process identifier for
                    512:  * the DDI/DKI SLEEP_LOCKOWNED () function to identify the current context.
                    513:  */
                    514: 
                    515: #if    __USE_PROTO__
                    516: __VOID__ * (PROC_HANDLE) (void)
                    517: #else
                    518: __VOID__ *
                    519: PROC_HANDLE __ARGS (())
                    520: #endif
                    521: {
                    522:        return PROCESS_PNODE ();
                    523: }
                    524: 
                    525: 
                    526: /*
                    527:  *-STATUS:
                    528:  *     DDI/DKI
                    529:  *
                    530:  *-NAME:
                    531:  *     proc_ref        Obtain a reference to a process for signalling.
                    532:  *
                    533:  *-SYNOPSIS:
                    534:  *     #include <sys/types.h>
                    535:  *
                    536:  *     void * proc_ref ();
                    537:  *
                    538:  *-DESCRIPTION:
                    539:  *     A non-STREAMS character driver can call proc_ref () to obtain a
                    540:  *     reference to the process in whose context it is running. The value
                    541:  *     returned can be used in subsequent calls to proc_signal () to post a
                    542:  *     signal to the process. The return value should not be used in any
                    543:  *     other way (ie, the driver should not attempt to interpret its
                    544:  *     meaning).
                    545:  *
                    546:  *-RETURN VALUE:
                    547:  *     An identifier that can be used in calls to proc_signal () and
                    548:  *     proc_unref ().
                    549:  *
                    550:  *-LEVEL:
                    551:  *     Base only.
                    552:  *
                    553:  *-NOTES:
                    554:  *     Processes can exit even though they are referenced by drivers. In this
                    555:  *     event, reuse of the identifier will be deferred until all driver
                    556:  *     references are given up.
                    557:  *
                    558:  *     There must be a matching call to proc_unref () for every call to
                    559:  *     proc_ref (), when the driver no longer needs to reference the process.
                    560:  *     This is typically done as part of close () processing.
                    561:  *
                    562:  *     Requires user context.
                    563:  *
                    564:  *     Does not sleep.
                    565:  *
                    566:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    567:  *     held across calls to this function.
                    568:  *
                    569:  *-SEE ALSO:
                    570:  *     proc_signal (), proc_unref ()
                    571:  */
                    572: 
                    573: #if    __USE_PROTO__
                    574: __VOID__ * (proc_ref) (void)
                    575: #else
                    576: __VOID__ *
                    577: proc_ref __ARGS (())
                    578: #endif
                    579: {
                    580:        pl_t            prev_pl;
                    581:        dpdata_t      * dpdatap;
                    582: 
                    583:        ASSERT_BASE_LEVEL ();
                    584: 
                    585: 
                    586:        /*
                    587:         * This implementation is a really just a stub for testing. Later
                    588:         * revisions of the code (especially in proc_unref () will deal with
                    589:         * the synchronization and storage management issues properly.
                    590:         *
                    591:         * In addition, leaving the multiprocessor rewrite of the process
                    592:         * system for another time will be good for ensuring that proper
                    593:         * encapsulation boundaries are created and respected, and will ensure
                    594:         * that the ideas prototypes here have been properly tested before
                    595:         * they are incorporated into other kernel areas.
                    596:         */
                    597: 
                    598:        dpdatap = ddi_proc_data ();
                    599: 
                    600:        prev_pl = LOCK (ddi_global_data ()->dg_proclock,
                    601:                        proc_global_priority);
                    602: 
                    603:        dpdatap->dp_refcount ++;
                    604: 
                    605:        UNLOCK (ddi_global_data ()->dg_proclock, prev_pl);
                    606: 
                    607:        return dpdatap;
                    608: }
                    609: 
                    610: 
                    611: /*
                    612:  *-STATUS:
                    613:  *     DDI/DKI
                    614:  *
                    615:  *-NAME:
                    616:  *     proc_signal     Send a signal to a process.
                    617:  *
                    618:  *-SYNOPSIS:
                    619:  *     #include <sys/types.h>
                    620:  *     #include <sys/signal.h>
                    621:  *
                    622:  *     int proc_signal (void * pref, int sig);
                    623:  *
                    624:  *-ARGUMENTS:
                    625:  *     pref            Identifier obtained by a previous call to proc_ref ().
                    626:  *
                    627:  *     sig             Signal number to be sent. Valid signal numbers to be
                    628:  *                     sent are:
                    629:  *                         SIGHUP      The device has been disconnected.
                    630:  *                         SIGINT      The interrupt character has been
                    631:  *                                     received.
                    632:  *                         SIGQUIT     The quit character has been received.
                    633:  *                         SIGWINCH    The window size has changed.
                    634:  *                         SIGURG      Urgent data are available.
                    635:  *                         SIGPOLL     A pollable event has occurred.
                    636:  *
                    637:  *-DESCRIPTION:
                    638:  *     The proc_signal () function can be used to post a signal to the
                    639:  *     process represented by "pref". This will interrupt any process blocked
                    640:  *     in SV_WAIT_SIG () or SLEEP_LOCK_SIG () at the time the signal is
                    641:  *     posted, causing those functions to return prematurely in most cases.
                    642:  *     If the process has exited then this function has no effect.
                    643:  *
                    644:  *-RETURN VALUE:
                    645:  *     If the process still exists, 0 is returned. Otherwise, -1 is returned
                    646:  *     to indicate that the process no longer exists.
                    647:  *
                    648:  *-LEVEL:
                    649:  *     Base or interrupt.
                    650:  *
                    651:  *-NOTES:
                    652:  *     STREAMS drivers and modules should not use this mechanism for
                    653:  *     signalling processes. Instead, they can send M_SIG or M_PCSIG STREAMS
                    654:  *     messages to the stream head.
                    655:  *
                    656:  *     proc_signal () must not be used to send SIGTSTP to a process.
                    657:  *
                    658:  *     Does not sleep.
                    659:  *
                    660:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    661:  *     held across calls to this function.
                    662:  *
                    663:  *-SEE ALSO:
                    664:  *     proc_ref (), proc_unref ()
                    665:  */
                    666: 
                    667: #if    __USE_PROTO__
                    668: int (proc_signal) (__VOID__ * pref, int sig)
                    669: #else
                    670: int
                    671: proc_signal __ARGS ((pref, sig))
                    672: __VOID__      *        pref;
                    673: int            sig;
                    674: #endif
                    675: {
                    676:        dpdata_t      * dpdatap = (dpdata_t *) pref;
                    677: 
                    678:        ASSERT (pref != NULL);
                    679:        ASSERT (sig != SIGTSTP);
                    680: 
                    681:        return KERNEL_SIGNAL (dpdatap, sig);
                    682: }
                    683: 
                    684: 
                    685: /*
                    686:  *-STATUS:
                    687:  *     DDI/DKI
                    688:  *
                    689:  *-SYNOPSIS:
                    690:  *     #include <sys/types.h>
                    691:  *
                    692:  *     void proc_unref (void * pref);
                    693:  *
                    694:  *-ARGUMENTS:
                    695:  *     pref            Identifier obtained by a previous call to proc_ref ().
                    696:  *
                    697:  *-DESCRIPTION:
                    698:  *     The proc_unref () function can be used to release a reference to a
                    699:  *     process identified by the parameter "pref". There must be a matching
                    700:  *     call to proc_unref () for every previous call to proc_ref ().
                    701:  *
                    702:  *-RETURN VALUE:
                    703:  *     None.
                    704:  *
                    705:  *-LEVEL:
                    706:  *     Base or interrupt.
                    707:  *
                    708:  *-NOTE:
                    709:  *     Processes can exit even though they are referenced by drivers. In this
                    710:  *     event, reuse of "pref" will be deferred until all driver references
                    711:  *     are given up.
                    712:  *
                    713:  *     Does not sleep.
                    714:  *
                    715:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    716:  *     held across calls to this function.
                    717:  *
                    718:  *-SEE ALSO:
                    719:  *     proc_ref (), proc_signal ()
                    720:  */
                    721: 
                    722: #if    __USE_PROTO__
                    723: void (proc_unref) (__VOID__ * pref)
                    724: #else
                    725: void
                    726: proc_unref __ARGS ((pref))
                    727: __VOID__      *        pref;
                    728: #endif
                    729: {
                    730:        pl_t            prev_pl;
                    731:        dpdata_t      * dpdatap = (dpdata_t *) pref;
                    732: 
                    733:        ASSERT (pref != NULL);
                    734: 
                    735:        /*
                    736:         * This implementation is a really just a stub for testing. Later
                    737:         * revisions of the code will deal with the synchronization and
                    738:         * storage management issues properly.
                    739:         */
                    740: 
                    741:        prev_pl = LOCK (ddi_global_data ()->dg_proclock,
                    742:                        proc_global_priority);
                    743: 
                    744:        dpdatap->dp_refcount --;
                    745: 
                    746:        UNLOCK (ddi_global_data ()->dg_proclock, prev_pl);
                    747: }
                    748: 
                    749: 
                    750: /*
                    751:  *-STATUS:
                    752:  *     Internal
                    753:  *
                    754:  *-SYNOPSIS:
                    755:  *     #include <sys/types.h>
                    756:  *
                    757:  *     void proc_kill_group (pid_t group, int sig);
                    758:  *
                    759:  *-ARGUMENTS:
                    760:  *     group           Process group ID to which the signal will be sent. All
                    761:  *                     members of the indicated process group will be sent
                    762:  *                     the signal.
                    763:  *
                    764:  *     sig             Signal number to be sent. Valid signal numbers are:
                    765:  *                         SIGHUP      The device has been disconnected.
                    766:  *                         SIGINT      The interrupt character has been
                    767:  *                                     received.
                    768:  *                         SIGQUIT     The quit character has been received.
                    769:  *                         SIGWINCH    The window size has changed.
                    770:  *                         SIGURG      Urgent data are available.
                    771:  *                         SIGPOLL     A pollable event has occurred.
                    772:  *
                    773:  *-DESCRIPTION:
                    774:  *     The proc_kill_group () function can be used to post a signal to a
                    775:  *     group of processes. This will interrupt any process blocked in
                    776:  *     SV_WAIT_SIG () or SLEEP_LOCK_SIG () at the time the signal is posted,
                    777:  *     causing those functions to return prematurely in most cases.
                    778:  *
                    779:  *-RETURN VALUE:
                    780:  *     None.
                    781:  *
                    782:  *-LEVEL:
                    783:  *     Base or interrupt.
                    784:  *
                    785:  *-NOTES:
                    786:  *     STREAMS drivers and modules should not use this mechanism for
                    787:  *     signalling processes. Instead, they can send M_SIG or M_PCSIG STREAMS
                    788:  *     messages to the stream head.
                    789:  *
                    790:  *     proc_kill_group () must not be used to send SIGTSTP to a process.
                    791:  *
                    792:  *     Does not sleep.
                    793:  *
                    794:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    795:  *     held across calls to this function.
                    796:  *
                    797:  *-SEE ALSO:
                    798:  *     proc_ref (), proc_signal (), proc_unref ()
                    799:  */
                    800: 
                    801: #if    __USE_PROTO__
                    802: void (proc_kill_group) (pid_t group, int sig)
                    803: #else
                    804: void
                    805: proc_kill_group __ARGS ((group, sig))
                    806: pid_t          group;
                    807: int            sig;
                    808: #endif
                    809: {
                    810:        ASSERT ("proc_kill_group () : not implemented" == 0);
                    811: }

unix.superglobalmegacorp.com

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