Annotation of coherent/b/STREAMS/conf_79/streams/defer.c, revision 1.1

1.1     ! root        1: #define        _DDI_DKI        1
        !             2: #define        _DDI_DKI_IMPL   1
        !             3: #define        _SYSV4          1
        !             4: 
        !             5: /*
        !             6:  *-IMPORTS:
        !             7:  *     <common/ccompat.h>
        !             8:  *             __USE_PROTO__
        !             9:  *             __ARGS ()
        !            10:  *     <sys/debug.h>
        !            11:  *             ASSERT ()
        !            12:  *     <kernel/ddi_cpu.h>
        !            13:  *             dcdata_t
        !            14:  *             ddi_cpu_data ()
        !            15:  *     <kernel/ddi_glob.h>
        !            16:  *             dgdata_t
        !            17:  *             ddi_global_data ()
        !            18:  *     <kernel/ddi_lock.h>
        !            19:  *             defer_priority
        !            20:  *             defer_hierarchy
        !            21:  *     <sys/ksynch.h>
        !            22:  *             LOCK ()
        !            23:  *             UNLOCK ()
        !            24:  *     <sys/cmn_err.h>
        !            25:  *             CE_WARN
        !            26:  *             cmn_err ()
        !            27:  *     <sys/stdlib.h>
        !            28:  *             NULL
        !            29:  */
        !            30: 
        !            31: #include <common/ccompat.h>
        !            32: #include <kernel/ddi_cpu.h>
        !            33: #include <kernel/ddi_glob.h>
        !            34: #include <kernel/ddi_lock.h>
        !            35: #include <sys/debug.h>
        !            36: #include <sys/ksynch.h>
        !            37: #include <sys/cmn_err.h>
        !            38: #include <stddef.h>
        !            39: 
        !            40: #include <kernel/defer.h>
        !            41: 
        !            42: 
        !            43: /*
        !            44:  * This internal function queues a deferred function on a deferred-function
        !            45:  * queue.
        !            46:  */
        !            47: 
        !            48: #if    __USE_PROTO__
        !            49: __LOCAL__ int (DEFER) (defer_t * deferp, __deffuncp_t funcp)
        !            50: #else
        !            51: __LOCAL__ int
        !            52: DEFER __ARGS ((deferp, funcp))
        !            53: defer_t              * deferp;
        !            54: __deffuncp_t   funcp;
        !            55: #endif
        !            56: {
        !            57:        pl_t            prev_pl;
        !            58:        int             idx;
        !            59: 
        !            60:        ASSERT (funcp != NULL);
        !            61:        ASSERT (deferp != NULL);
        !            62:        ASSERT (deferp->df_tab != NULL && deferp->df_max > 0);
        !            63: 
        !            64:        prev_pl = LOCK (deferp->df_wlock, defer_priority);
        !            65: 
        !            66:        /*
        !            67:         * Write the function pointer into the next free slot in the table,
        !            68:         * and then move the write pointer to the next entry in the circular
        !            69:         * buffer.
        !            70:         */
        !            71: 
        !            72:        idx = ATOMIC_FETCH_UCHAR (deferp->df_write);
        !            73: 
        !            74:        deferp->df_tab [idx ++] = funcp;
        !            75: 
        !            76:        if (idx == ATOMIC_FETCH_UCHAR (deferp->df_max))
        !            77:                idx = 0;
        !            78: 
        !            79:        /*
        !            80:         * If the write pointer bumps into the read pointer, then the defer
        !            81:         * table is full and we should complain. A possible alternative
        !            82:         * strategy would be to wait for the other processor, but that is only
        !            83:         * a good idea if we have the machinery to interrupt it available,
        !            84:         * which we currently do not.
        !            85:         */
        !            86: 
        !            87:        if (idx != ATOMIC_FETCH_UCHAR (deferp->df_read)) {
        !            88:                /*
        !            89:                 * Store the updated write pointer and prepare to return
        !            90:                 * success.
        !            91:                 */
        !            92: 
        !            93:                ATOMIC_STORE_UCHAR (deferp->df_write, idx);
        !            94:                idx = 0;
        !            95:        } else {
        !            96: 
        !            97:                cmn_err (CE_WARN, "table overflow in DEFER ()");
        !            98:                idx = 1;        /* flag failure to the caller */
        !            99:        }
        !           100: 
        !           101:        UNLOCK (deferp->df_wlock, prev_pl);
        !           102: 
        !           103:        return idx;
        !           104: }
        !           105: 
        !           106: 
        !           107: /*
        !           108:  *-STATUS:
        !           109:  *     For the Implementors only.
        !           110:  *
        !           111:  *-NAME:
        !           112:  *     defer_int_cpu   Defer a routine on a specified CPU.
        !           113:  *
        !           114:  *-SYNOPSIS:
        !           115:  *     #include <kernel/defer.h>
        !           116:  *
        !           117:  *     int defer_int_cpu (void (* funcp) (void), processorid_t cpuid);
        !           118:  *
        !           119:  *-ARGUMENTS:
        !           120:  *     funcp           Pointer to the function to be executed upon the given
        !           121:  *                     processor's return from kernel execution to user-level
        !           122:  *                     execution.
        !           123:  *
        !           124:  *     cpuid           Processor on which "funcp" is to be executed.
        !           125:  *
        !           126:  *-DESCRIPTION:
        !           127:  *     defer_int_cpu () requests that a function be executed on the given CPU
        !           128:  *     at a priority higher than any user-level code. If the given CPU is
        !           129:  *     currently executing kernel code, the function will be run before user-
        !           130:  *     level execution is resumed. The routine is run at a priority lower
        !           131:  *     than any interrupt-level code; if the implementation permits, the
        !           132:  *     routine will be run at a priority higher than base kernel code, but
        !           133:  *     this is not guaranteed.
        !           134:  *
        !           135:  *     The implementation will make a best effort to ensure that the deferred
        !           136:  *     function is executed promptly. However, some hardware configurations
        !           137:  *     may not permit one CPU to interrupt another under software control, so
        !           138:  *     if the specified CPU is currently running at user level it may not
        !           139:  *     execute the deferred function for some time.
        !           140:  *
        !           141:  *-RETURN VALUE:
        !           142:  *     0 is returned on success. If the specified CPU is invalid, or the
        !           143:  *     deferred-function table for the specified CPU is full, then a non-zero
        !           144:  *     error value is returned.
        !           145:  *
        !           146:  *-LEVEL:
        !           147:  *     Base or interrupt.
        !           148:  *
        !           149:  *-NOTES:
        !           150:  *     Does not sleep.
        !           151:  *
        !           152:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           153:  *     is permitted to contend for locks held by the caller.
        !           154:  */
        !           155: 
        !           156: #if    __USE_PROTO__
        !           157: int (defer_int_cpu) (__deffuncp_t funcp, processorid_t cpuid)
        !           158: #else
        !           159: int
        !           160: defer_int_cpu __ARGS ((funcp, cpuid))
        !           161: __deffuncp_t   funcp;
        !           162: processorid_t  cpuid;
        !           163: #endif
        !           164: {
        !           165:        dcdata_t      * dcdatap;
        !           166:        int             retval;
        !           167: 
        !           168:        ASSERT (funcp != NULL);
        !           169: 
        !           170:        if ((dcdatap = ddi_cpu_ref (cpuid)) == NULL)
        !           171:                return -1;
        !           172: 
        !           173:        retval = DEFER (& dcdatap->dc_defint, funcp);
        !           174: 
        !           175:        ddi_cpu_unref (dcdatap);
        !           176:        return retval;
        !           177: }
        !           178: 
        !           179: 
        !           180: /*
        !           181:  *-STATUS:
        !           182:  *     For the Implementors only.
        !           183:  *
        !           184:  *-NAME:
        !           185:  *     defer_int_any   Defer a routine on an unspecified CPU.
        !           186:  *
        !           187:  *-SYNOPSIS:
        !           188:  *     #include <kernel/defer.h>
        !           189:  *
        !           190:  *     int defer_int_any (void (* funcp) (void));
        !           191:  *
        !           192:  *-ARGUMENTS:
        !           193:  *     funcp           Pointer to the function to be executed upon some
        !           194:  *                     processor's return from kernel execution to user-level
        !           195:  *                     execution.
        !           196:  *
        !           197:  *-DESCRIPTION:
        !           198:  *     defer_int_any () requests that a function be executed at some future
        !           199:  *     time convenient to the implementation. The routine will be run at a
        !           200:  *     priority higher than any user-level code, and lower than any
        !           201:  *     interrupt-level code; if the implementation permits, the function will
        !           202:  *     be run at a priority higher than base kernel code, but this is not
        !           203:  *     guaranteed.
        !           204:  *
        !           205:  *     The function will be executed on the first CPU available. However, a
        !           206:  *     typical implementation would not interrupt user-level execution on
        !           207:  *     any other CPUs merely to run deferred functions.
        !           208:  *
        !           209:  *-RETURN VALUE:
        !           210:  *     0 is returned on success. If the global deferred-function table is
        !           211:  *     full, then a non-zero error value is returned.
        !           212:  *
        !           213:  *-LEVEL:
        !           214:  *     Base or interrupt.
        !           215:  *
        !           216:  *-NOTES:
        !           217:  *     Does not sleep.
        !           218:  *
        !           219:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           220:  *     is permitted to contend for locks held by the caller.
        !           221:  */
        !           222: 
        !           223: #if    __USE_PROTO__
        !           224: int (defer_int_any) (__deffuncp_t funcp)
        !           225: #else
        !           226: int
        !           227: defer_int_any __ARGS ((funcp))
        !           228: __deffuncp_t   funcp;
        !           229: #endif
        !           230: {
        !           231:        return DEFER (& ddi_global_data ()->dg_defint, funcp);
        !           232: }
        !           233: 
        !           234: 
        !           235: /*
        !           236:  *-STATUS:
        !           237:  *     For the Implementors only.
        !           238:  *
        !           239:  *-NAME:
        !           240:  *     defer_int_here  Defer a routine on the current CPU.
        !           241:  *
        !           242:  *-SYNOPSIS:
        !           243:  *     #include <kernel/defer.h>
        !           244:  *
        !           245:  *     int defer_int_here (void (* funcp) (void));
        !           246:  *
        !           247:  *-ARGUMENTS:
        !           248:  *     funcp           Pointer to the function to be executed upon this
        !           249:  *                     processor's return from kernel execution to user-level
        !           250:  *                     execution.
        !           251:  *
        !           252:  *-DESCRIPTION:
        !           253:  *     defer_int_here () requests that a function be executed at some future
        !           254:  *     time convenient to the implementation on the current CPU. The routine
        !           255:  *     will be run at a priority higher than any user-level code, and lower
        !           256:  *     than any interrupt-level code; if the implementation permits, the
        !           257:  *     function will run at a level higher than base kernel code, but this is
        !           258:  *     not guaranteed.
        !           259:  *
        !           260:  *-RETURN VALUE:
        !           261:  *     0 is returned on success. If the current CPUs deferred-function table
        !           262:  *     is full, then a non-zero error value is returned.
        !           263:  *
        !           264:  *-LEVEL:
        !           265:  *     Base or interrupt.
        !           266:  *
        !           267:  *-NOTES:
        !           268:  *     Does not sleep.
        !           269:  *
        !           270:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           271:  *     is permitted to contend for locks held by the caller.
        !           272:  */
        !           273: 
        !           274: #if    __USE_PROTO__
        !           275: int (defer_int_here) (__deffuncp_t funcp)
        !           276: #else
        !           277: int
        !           278: defer_int_here __ARGS ((funcp))
        !           279: __deffuncp_t   funcp;
        !           280: #endif
        !           281: {
        !           282:        return DEFER (& ddi_cpu_data ()->dc_defint, funcp);
        !           283: }
        !           284: 
        !           285: 
        !           286: /*
        !           287:  *-STATUS:
        !           288:  *     For the Implementors only.
        !           289:  *
        !           290:  *-NAME:
        !           291:  *     defer_proc_cpu  Defer a routine on a specified CPU.
        !           292:  *
        !           293:  *-SYNOPSIS:
        !           294:  *     #include <kernel/defer.h>
        !           295:  *
        !           296:  *     int defer_proc_cpu (void (* funcp) (void), processorid_t cpuid);
        !           297:  *
        !           298:  *-ARGUMENTS:
        !           299:  *     funcp           Pointer to the function to be executed upon the given
        !           300:  *                     processor's return from kernel execution to user-level
        !           301:  *                     execution.
        !           302:  *
        !           303:  *     cpuid           Processor on which "funcp" is to be executed.
        !           304:  *
        !           305:  *-DESCRIPTION:
        !           306:  *     defer_proc_cpu () requests that a function be executed on the given CPU
        !           307:  *     at a priority higher than any user-level code. If the given CPU is
        !           308:  *     currently executing kernel code, the function will be run before user-
        !           309:  *     level execution is resumed.
        !           310:  *
        !           311:  *     The implementation will make a best effort to ensure that the deferred
        !           312:  *     function is executed promptly. However, some hardware configurations
        !           313:  *     may not permit one CPU to interrupt another under software control, so
        !           314:  *     if the specified CPU is currently running at user level it may not
        !           315:  *     execute the deferred function for some time.
        !           316:  *
        !           317:  *-RETURN VALUE:
        !           318:  *     0 is returned on success. If the specified CPU is invalid, or the
        !           319:  *     deferred-function table for the specified CPU is full, then a non-zero
        !           320:  *     error value is returned.
        !           321:  *
        !           322:  *-LEVEL:
        !           323:  *     Base or interrupt.
        !           324:  *
        !           325:  *-NOTES:
        !           326:  *     Does not sleep.
        !           327:  *
        !           328:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           329:  *     is permitted to contend for locks held by the caller.
        !           330:  */
        !           331: 
        !           332: #if    __USE_PROTO__
        !           333: int (defer_proc_cpu) (__deffuncp_t funcp, processorid_t cpuid)
        !           334: #else
        !           335: int
        !           336: defer_proc_cpu __ARGS ((funcp, cpuid))
        !           337: __deffuncp_t   funcp;
        !           338: processorid_t  cpuid;
        !           339: #endif
        !           340: {
        !           341:        dcdata_t      * dcdatap;
        !           342:        int             retval;
        !           343: 
        !           344:        ASSERT (funcp != NULL);
        !           345: 
        !           346:        if ((dcdatap = ddi_cpu_ref (cpuid)) == NULL)
        !           347:                return -1;
        !           348: 
        !           349:        retval = DEFER (& dcdatap->dc_defproc, funcp);
        !           350: 
        !           351:        ddi_cpu_unref (dcdatap);
        !           352:        return retval;
        !           353: }
        !           354: 
        !           355: 
        !           356: /*
        !           357:  *-STATUS:
        !           358:  *     For the Implementors only.
        !           359:  *
        !           360:  *-NAME:
        !           361:  *     defer_proc_any  Defer a routine on an unspecified CPU.
        !           362:  *
        !           363:  *-SYNOPSIS:
        !           364:  *     #include <kernel/defer.h>
        !           365:  *
        !           366:  *     int defer_proc_any (void (* funcp) (void));
        !           367:  *
        !           368:  *-ARGUMENTS:
        !           369:  *     funcp           Pointer to the function to be executed upon some
        !           370:  *                     processor's return from kernel execution to user-level
        !           371:  *                     execution.
        !           372:  *
        !           373:  *-DESCRIPTION:
        !           374:  *     defer_proc_any () requests that a function be executed at some future
        !           375:  *     time convenient to the implementation. The routine will be run at a
        !           376:  *     priority higher than any user-level code, and lower than any
        !           377:  *     interrupt-level code or kernel code.
        !           378:  *
        !           379:  *     The function will be executed on the first CPU available. However, a
        !           380:  *     typical implementation would not interrupt user-level execution on
        !           381:  *     any other CPUs merely to run deferred functions.
        !           382:  *
        !           383:  *-RETURN VALUE:
        !           384:  *     0 is returned on success. If the global deferred-function table is
        !           385:  *     full, then a non-zero error value is returned.
        !           386:  *
        !           387:  *-LEVEL:
        !           388:  *     Base or interrupt.
        !           389:  *
        !           390:  *-NOTES:
        !           391:  *     Does not sleep.
        !           392:  *
        !           393:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           394:  *     is permitted to contend for locks held by the caller.
        !           395:  */
        !           396: 
        !           397: #if    __USE_PROTO__
        !           398: int (defer_proc_any) (__deffuncp_t funcp)
        !           399: #else
        !           400: int
        !           401: defer_proc_any __ARGS ((funcp))
        !           402: __deffuncp_t   funcp;
        !           403: #endif
        !           404: {
        !           405:        return DEFER (& ddi_global_data ()->dg_defproc, funcp);
        !           406: }
        !           407: 
        !           408: 
        !           409: /*
        !           410:  *-STATUS:
        !           411:  *     For the Implementors only.
        !           412:  *
        !           413:  *-NAME:
        !           414:  *     defer_proc_here Defer a routine on the current CPU.
        !           415:  *
        !           416:  *-SYNOPSIS:
        !           417:  *     #include <kernel/defer.h>
        !           418:  *
        !           419:  *     int defer_proc_here (void (* funcp) (void));
        !           420:  *
        !           421:  *-ARGUMENTS:
        !           422:  *     funcp           Pointer to the function to be executed upon this
        !           423:  *                     processor's return from kernel execution to user-level
        !           424:  *                     execution.
        !           425:  *
        !           426:  *-DESCRIPTION:
        !           427:  *     defer_proc_here () requests that a function be executed at some futur
        !           428:  *     time convenient to the implementation on the current CPU. The routine
        !           429:  *     will be run at a priority higher than any user-level code, and lower
        !           430:  *     than any interrupt-level code or kernel code.
        !           431:  *
        !           432:  *-RETURN VALUE:
        !           433:  *     0 is returned on success. If the current CPUs deferred-function table
        !           434:  *     is full, then a non-zero error value is returned.
        !           435:  *
        !           436:  *-LEVEL:
        !           437:  *     Base or interrupt.
        !           438:  *
        !           439:  *-NOTES:
        !           440:  *     Does not sleep.
        !           441:  *
        !           442:  *     It is currently unspecified whether the function pointed to by "funcp"
        !           443:  *     is permitted to contend for locks held by the caller.
        !           444:  */
        !           445: 
        !           446: #if    __USE_PROTO__
        !           447: int (defer_proc_here) (__deffuncp_t funcp)
        !           448: #else
        !           449: int
        !           450: defer_proc_here __ARGS ((funcp))
        !           451: __deffuncp_t   funcp;
        !           452: #endif
        !           453: {
        !           454:        return DEFER (& ddi_cpu_data ()->dc_defproc, funcp);
        !           455: }

unix.superglobalmegacorp.com

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