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

unix.superglobalmegacorp.com

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