Annotation of coherent/b/STREAMS/conf_79/streams/v_proc.c, revision 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.