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

unix.superglobalmegacorp.com

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