Annotation of coherent/b/STREAMS/conf/streams/src/strmem.c, revision 1.1.1.1

1.1       root        1: #define        _DDI_DKI        1
                      2: #define        _SYSV4          1
                      3: 
                      4: /*
                      5:  * STREAMS memory management code.
                      6:  *
                      7:  * This is layered on top of the fast first-fit heap allocator whose
                      8:  * implementation is described in <sys/st_alloc.h>. The particulars of how
                      9:  * STREAMS memory is allocated (including synchronisation and watermarks)
                     10:  * is kept here so that the generic allocator is just that, generic.
                     11:  */
                     12: 
                     13: /*
                     14:  *-IMPORTS:
                     15:  *     <common/ccompat.h>
                     16:  *             __USE_PROTO__
                     17:  *             __ARGS ()
                     18:  *     <common/ccompat.h>
                     19:  *             __LOCAL__
                     20:  *     <sys/debug.h>
                     21:  *             ASSERT ()
                     22:  *     <sys/types.h>
                     23:  *             _VOID
                     24:  *             size_t
                     25:  *     <sys/ksynch.h>
                     26:  *             lock_t
                     27:  *             LOCK_ALLOC ()
                     28:  *             LOCK ()
                     29:  *             UNLOCK ()
                     30:  *     <sys/cmn_err.h>
                     31:  *             CE_WARN
                     32:  *             cmn_err ()
                     33:  */
                     34: 
                     35: #include <common/ccompat.h>
                     36: #include <kernel/ddi_lock.h>
                     37: #include <sys/types.h>
                     38: #include <sys/debug.h>
                     39: #include <sys/ksynch.h>
                     40: #include <sys/cmn_err.h>
                     41: 
                     42: #include <sys/kmem.h>
                     43: #include <kernel/strmlib.h>
                     44: #include <string.h>
                     45: 
                     46: 
                     47: /*
                     48:  * This private function gathers some of the aspects of streams message memory
                     49:  * allocation into a single place (message blocks are allocated in allocb (),
                     50:  * dupb (), and esballoc ()). We leave the initialization of the newly
                     51:  * allocated memory up to the caller.
                     52:  */
                     53: 
                     54: #if    __USE_PROTO__
                     55: mblk_t * (STRMEM_ALLOC) (size_t size, int pri, int flag)
                     56: #else
                     57: mblk_t *
                     58: STRMEM_ALLOC __ARGS ((size, pri, flag))
                     59: size_t         size;
                     60: int            pri;
                     61: int            flag;
                     62: #endif
                     63: {
                     64:        pl_t            prev_pl;
                     65:        mblk_t        * mblkp;
                     66: 
                     67:        ASSERT (size > 0);
                     68:        ASSERT (flag == KM_SLEEP || flag == KM_NOSLEEP);
                     69: 
                     70:        /*
                     71:         * Note that if the size is one such that it cannot possibly ever be
                     72:         * satisfied given the allocation watermarks we have set, then we just
                     73:         * return failure now.
                     74:         */
                     75: 
                     76:        pri = MAP_PRI_LEVEL (pri);
                     77: 
                     78:        if (size > str_mem->sm_max [pri])
                     79:                return NULL;
                     80: 
                     81: 
                     82:        for (;;) {
                     83:                /*
                     84:                 * Lock the basic lock protecting access to the memory pool
                     85:                 * and attempt to acquire the memory we desire.
                     86:                 */
                     87: 
                     88:                prev_pl = LOCK (str_mem->sm_msg_lock, str_msg_pl);
                     89: 
                     90: 
                     91:                /*
                     92:                 * Before allocating any memory, we check to see that it makes
                     93:                 * sense to give out that memory to the given priority level.
                     94:                 */
                     95: 
                     96:                if (str_mem->sm_used + size <= str_mem->sm_max [pri]) {
                     97:                        /*
                     98:                         * Try to get the memory, and if we do update the
                     99:                         * priority bookkeeping information to record the
                    100:                         * amount of memory that we have allowed out.
                    101:                         */
                    102: 
                    103:                        mblkp = (mblk_t *) st_alloc (str_mem->sm_msg_heap,
                    104:                                                     size);
                    105: 
                    106:                        if (mblkp != NULL) {
                    107: 
                    108:                                str_mem->sm_used += size;
                    109:                                break;
                    110:                        }
                    111:                }
                    112: 
                    113: 
                    114:                /*
                    115:                 * Depending on the caller, we may sleep waiting for memory
                    116:                 * to become available.
                    117:                 */
                    118: 
                    119:                if (flag == KM_NOSLEEP) {
                    120: 
                    121:                        mblkp = NULL;
                    122:                        break;
                    123:                }
                    124: 
                    125: 
                    126:                /*
                    127:                 * RESEARCH NOTE: This policy is a guess, no more. We need to
                    128:                 * do some profiling to find out what effect other policies
                    129:                 * might have. In particular, the wakeup heuristic could be
                    130:                 * altered to broadcast when we can satisfy the largest
                    131:                 * request.
                    132:                 */
                    133: 
                    134:                if (str_mem->sm_msg_needed == 0 ||
                    135:                    str_mem->sm_msg_needed > size)
                    136:                        str_mem->sm_msg_needed = size;
                    137: 
                    138:                SV_WAIT (str_mem->sm_msg_sv, prilo, str_mem->sm_msg_lock);
                    139:        }
                    140: 
                    141:        UNLOCK (str_mem->sm_msg_lock, prev_pl);
                    142: 
                    143:        return mblkp;
                    144: }
                    145: 
                    146: 
                    147: /*
                    148:  * This simple function factors out some common code from different calls to
                    149:  * st_free () inside freeb (). This just reduces some of the cost of all the
                    150:  * error checking that is my custom, and consolidates the interface to the
                    151:  * bookkeeping for callback events and so forth.
                    152:  *
                    153:  * The streams heap must be locked on entry to this function.
                    154:  */
                    155: 
                    156: #if    __USE_PROTO__
                    157: void (STRMEM_FREE) (mblk_t * bp, size_t size)
                    158: #else
                    159: void
                    160: STRMEM_FREE __ARGS ((bp, size))
                    161: mblk_t       * bp;
                    162: size_t         size;
                    163: #endif
                    164: {
                    165:        int             free_ok;
                    166: 
                    167:        ASSERT (TRYLOCK (str_mem->sm_msg_lock, str_msg_pl) == invpl);
                    168: 
                    169:        free_ok = st_free (str_mem->sm_msg_heap, bp, size);
                    170: 
                    171:        if (free_ok != 0) {
                    172:                /*
                    173:                 * The heap manager has a problem with freeing the block that
                    174:                 * was passed to it, display a console diagnostic. For
                    175:                 * simplicity we display addresses as longs.
                    176:                 */
                    177: 
                    178:                cmn_err (CE_WARN,
                    179:                         "MSGB_FREE : st_free () complained with %d freeing %d bytes at %lx",
                    180:                         free_ok, size, (long) bp);
                    181:        } else {
                    182:                /*
                    183:                 * Update the allocation bookkeeping, and request that the
                    184:                 * routine that processes bufcall () events be run. This other
                    185:                 * procedure also has responsibility for waking up message and
                    186:                 * possibly "other" allocations if there is sufficient memory
                    187:                 * available.
                    188:                 */
                    189: 
                    190:                str_mem->sm_used -= size;
                    191: 
                    192:                SCHEDULE_BUFCALLS ();
                    193:        }
                    194: }
                    195: 

unix.superglobalmegacorp.com

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