Annotation of coherent/f/usr/include/kernel/ddi_cpu.h, revision 1.1.1.1

1.1       root        1: #ifndef        __KERNEL_DDI_CPU_H__
                      2: #define        __KERNEL_DDI_CPU_H__
                      3: 
                      4: /*
                      5:  * This internal header file defines structures and an access procedure for
                      6:  * DDI/DKI data that is global per CPU. In a multiprocessor system, each
                      7:  * CPU would have a distinct data region separate from all others.
                      8:  */
                      9: 
                     10: /*
                     11:  *-IMPORTS:
                     12:  *     <common/ccompat.h>
                     13:  *             __EXTERN_C_BEGIN__
                     14:  *             __EXTERN_C_END__
                     15:  *             __PROTO ()
                     16:  *     <common/__size.h>
                     17:  *             __size_t
                     18:  *     <common/_intmask.h>
                     19:  *             intmask_t
                     20:  *     <kernel/_lock.h>
                     21:  *             __lock_t
                     22:  *             __MAX_HIERARCHY__
                     23:  *             __MIN_HIERARCHY__
                     24:  *     <kernel/_cpuid.h>
                     25:  *             processorid_t
                     26:  *     <sys/debug.h>
                     27:  *             ASSERT ()
                     28:  */
                     29: 
                     30: #include <common/ccompat.h>
                     31: #include <common/__size.h>
                     32: #include <common/_intmask.h>
                     33: #include <kernel/_cpuid.h>
                     34: #include <kernel/_lock.h>
                     35: #include <kernel/ddi_data.h>
                     36: #include <sys/debug.h>
                     37: 
                     38: /*
                     39:  * Many DDI/DKI routines specify constraints on the circumstances in which
                     40:  * they may be called, for example.
                     41:  *     Base level only, eg SV_WAIT ().
                     42:  *     Pass interrupt priority level greater than the current level,
                     43:  *             eg LOCK ().
                     44:  *     Not called from within a streams service routine, eg putbq () with
                     45:  *             a high-priority STREAMS message.
                     46:  *
                     47:  * These assertions are important for maintaining system integrity, but it can
                     48:  * be difficult to detect when these constraints a violated under normal
                     49:  * circumstances, especially when the probability of failure is expected to
                     50:  * be low. Therefore, it is important for routines which specify such
                     51:  * constraints to be able to umambiguously detect constraint violations with
                     52:  * the highest level of probability possible.
                     53:  *
                     54:  * However, the testability of these assertions depends on cooperation from
                     55:  * a wide range of kernel facilities. In a highly multithreaded system with
                     56:  * either multiple processors or the ability to suspend interrupt contexts,
                     57:  * or both, it is necessary to be able to make detailed inquiries about the
                     58:  * system state to re-establish some of the certainty about system state that
                     59:  * is lost in the move to gain extra concurrency.
                     60:  */
                     61: 
                     62: /*
                     63:  * Returns true if we are at base level or if the system cannot distinguish
                     64:  * between base and interrupt level; if the system is definitely not at base
                     65:  * level, returns false.
                     66:  */
                     67: 
                     68: #define                IS_BASE_LEVEL()         (ddi_cpu_data ()->dc_int_level == 0)
                     69: 
                     70: 
                     71: /*
                     72:  * Returns true if we are at interrupt level or if the system cannot
                     73:  * distinguish between base and interrupt level; if the system is definitely
                     74:  * at base level, returns false.
                     75:  */
                     76: 
                     77: #define                IS_INTERRUPT_LEVEL()    (ddi_cpu_data ()->dc_int_level != 0)
                     78: 
                     79: 
                     80: /*
                     81:  * Most of the time we want to include the above in simple assertions.
                     82:  */
                     83: 
                     84: #define                ASSERT_BASE_LEVEL()     ASSERT (IS_BASE_LEVEL ())
                     85: 
                     86: 
                     87: /*
                     88:  * Here is a description of the per-CPU data we wish to record.
                     89:  *
                     90:  * In order to deal with lock-hierarchy assertions, we use a table of
                     91:  * counters instead of maintaining a list of held locks. We do this because
                     92:  * the nature of shared read/write locks permits even a single CPU to hold
                     93:  * the same lock multiple times, and because while TRYLOCK () and UNLOCK ()
                     94:  * allow out-of-order acquisition and release we want LOCK () to rigidly
                     95:  * check the hierarchy assertions. The array of counters is mostly O(1), a
                     96:  * desirable property.
                     97:  *
                     98:  * While a trace of held locks is not unreasonable, it is difficult to set a
                     99:  * fixed upper bound on the number of simultaneous locks. Even if we use a
                    100:  * counter for multiple acquisitions of shared locks, we can potentially need
                    101:  * as many trace records as allocated locks.
                    102:  */
                    103: 
                    104: struct ddi_cpu_data {
                    105:        /*
                    106:         * Interrupt-related data is at the front of this structure for easy
                    107:         * access by hand-coded assembly-language support routines. Same for
                    108:         * the defer-table stuff.
                    109:         */
                    110: 
                    111:        processorid_t   dc_cpuid;               /* who are we for? */
                    112: 
                    113:        intmask_t       dc_base_mask;           /* interrupt masks */
                    114:        unsigned char   dc_int_level;           /* processing interrupts */
                    115:        unsigned char   dc_user_level;          /* user level/kernel level */
                    116:        unsigned char   dc_ipl;                 /* current ipl */
                    117: 
                    118:        defer_t         dc_defint;              /* interrupt-deferred ops */
                    119:        defer_t         dc_defproc;             /* process-deferred ops */
                    120: 
                    121:        __lkhier_t      dc_max_hierarchy;       /*
                    122:                                                 * For basic-lock hierarchy
                    123:                                                 * assertions
                    124:                                                 */
                    125:        __lkhier_t    * dc_hierarchy_cnt;
                    126: 
                    127:        atomic_uchar_t  dc_run_timeouts;        /* run deferred timeouts */
                    128: 
                    129:        struct pollwait *
                    130:                        dc_pollwait;            /* task performing a poll */
                    131: 
                    132:        char          * dc_dynalloc;            /* for getting per-cpu data */
                    133:        char          * dc_dynend;              /* end of free per-cpu data */
                    134: };
                    135: 
                    136: typedef struct ddi_cpu_data    dcdata_t;
                    137: 
                    138: 
                    139: 
                    140: __EXTERN_C_BEGIN__
                    141: 
                    142: dcdata_t      *        ddi_cpu_data    __PROTO ((void));
                    143: 
                    144: #if    _DDI_DKI_IMPL
                    145:        /*
                    146:         * Functions for the implementation only.
                    147:         */
                    148: __VOID__      * ddi_cpu_alloc  __PROTO ((__size_t _size));
                    149: dcdata_t      *        ddi_cpu_ref     __PROTO ((processorid_t _cpu));
                    150: void           ddi_cpu_unref   __PROTO ((dcdata_t * _data));
                    151: processorid_t  ddi_cpu_id      __PROTO ((void));
                    152: 
                    153: #endif
                    154: 
                    155: __EXTERN_C_END__
                    156: 
                    157: 
                    158: extern dcdata_t                __ddi_cpu_data [];
                    159: 
                    160: #define        ddi_cpu_data()          (__ddi_cpu_data)
                    161: 
                    162: #endif /* ! defined (__KERNEL_DDI_CPU_H__) */

unix.superglobalmegacorp.com

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