Annotation of coherent/f/etc/conf/streams/src/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:  *     <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.