[BACK]Return to rf_alloclist.c CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_alloclist.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: rf_alloclist.c,v 1.4 2002/12/16 07:01:03 tdeval Exp $ */
                      2: /*     $NetBSD: rf_alloclist.c,v 1.4 1999/08/13 03:41:53 oster Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Carnegie-Mellon University.
                      6:  * All rights reserved.
                      7:  *
                      8:  * Author: Mark Holland
                      9:  *
                     10:  * Permission to use, copy, modify and distribute this software and
                     11:  * its documentation is hereby granted, provided that both the copyright
                     12:  * notice and this permission notice appear in all copies of the
                     13:  * software, derivative works or modified versions, and any portions
                     14:  * thereof, and that both notices appear in supporting documentation.
                     15:  *
                     16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
                     18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     19:  *
                     20:  * Carnegie Mellon requests users of this software to return to
                     21:  *
                     22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     23:  *  School of Computer Science
                     24:  *  Carnegie Mellon University
                     25:  *  Pittsburgh PA 15213-3890
                     26:  *
                     27:  * any improvements or extensions that they make and grant Carnegie the
                     28:  * rights to redistribute these changes.
                     29:  */
                     30:
                     31: /****************************************************************************
                     32:  *
                     33:  * Alloclist.c -- Code to manipulate allocation lists.
                     34:  *
                     35:  * An allocation list is just a list of AllocListElem structures. Each
                     36:  * such structure contains a fixed-size array of pointers. Calling
                     37:  * FreeAList() causes each pointer to be freed.
                     38:  *
                     39:  ***************************************************************************/
                     40:
                     41: #include "rf_types.h"
                     42: #include "rf_threadstuff.h"
                     43: #include "rf_alloclist.h"
                     44: #include "rf_debugMem.h"
                     45: #include "rf_etimer.h"
                     46: #include "rf_general.h"
                     47: #include "rf_shutdown.h"
                     48:
                     49: RF_DECLARE_STATIC_MUTEX(alist_mutex);
                     50: static unsigned int fl_hit_count, fl_miss_count;
                     51:
                     52: static RF_AllocListElem_t *al_free_list = NULL;
                     53: static int al_free_list_count;
                     54:
                     55: #define        RF_AL_FREELIST_MAX      256
                     56:
                     57: #define        DO_FREE(_p,_sz)         RF_Free((_p), (_sz))
                     58:
                     59: void rf_ShutdownAllocList(void *);
                     60:
                     61: void
                     62: rf_ShutdownAllocList(void *ignored)
                     63: {
                     64:        RF_AllocListElem_t *p, *pt;
                     65:
                     66:        for (p = al_free_list; p;) {
                     67:                pt = p;
                     68:                p = p->next;
                     69:                DO_FREE(pt, sizeof(*pt));
                     70:        }
                     71:        rf_mutex_destroy(&alist_mutex);
                     72:        /*
                     73:         * printf("Alloclist: Free list hit count %lu (%lu %%) miss count %lu"
                     74:         *     " (%lu %%).\n", fl_hit_count,
                     75:         *     (100*fl_hit_count)/(fl_hit_count+fl_miss_count),
                     76:         *     fl_miss_count, (100*fl_miss_count)/(fl_hit_count+fl_miss_count));
                     77:         */
                     78: }
                     79:
                     80: int
                     81: rf_ConfigureAllocList(RF_ShutdownList_t **listp)
                     82: {
                     83:        int rc;
                     84:
                     85:        rc = rf_mutex_init(&alist_mutex);
                     86:        if (rc) {
                     87:                RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d.\n",
                     88:                    __FILE__, __LINE__, rc);
                     89:                return (rc);
                     90:        }
                     91:        al_free_list = NULL;
                     92:        fl_hit_count = fl_miss_count = al_free_list_count = 0;
                     93:        rc = rf_ShutdownCreate(listp, rf_ShutdownAllocList, NULL);
                     94:        if (rc) {
                     95:                RF_ERRORMSG3("Unable to add to shutdown list file %s line %d"
                     96:                    " rc=%d.\n", __FILE__, __LINE__, rc);
                     97:                rf_mutex_destroy(&alist_mutex);
                     98:                return (rc);
                     99:        }
                    100:        return (0);
                    101: }
                    102:
                    103:
                    104: /*
                    105:  * We expect the lists to have at most one or two elements, so we're willing
                    106:  * to search for the end. If you ever observe the lists growing longer,
                    107:  * increase POINTERS_PER_ALLOC_LIST_ELEMENT.
                    108:  */
                    109: void
                    110: rf_real_AddToAllocList(RF_AllocListElem_t *l, void *p, int size, int lockflag)
                    111: {
                    112:        RF_AllocListElem_t *newelem;
                    113:
                    114:        for (; l->next; l = l->next)
                    115:                RF_ASSERT(l->numPointers == RF_POINTERS_PER_ALLOC_LIST_ELEMENT);        /* Find end of list. */
                    116:
                    117:        RF_ASSERT(l->numPointers >= 0 &&
                    118:            l->numPointers <= RF_POINTERS_PER_ALLOC_LIST_ELEMENT);
                    119:        if (l->numPointers == RF_POINTERS_PER_ALLOC_LIST_ELEMENT) {
                    120:                newelem = rf_real_MakeAllocList(lockflag);
                    121:                l->next = newelem;
                    122:                l = newelem;
                    123:        }
                    124:        l->pointers[l->numPointers] = p;
                    125:        l->sizes[l->numPointers] = size;
                    126:        l->numPointers++;
                    127:
                    128: }
                    129:
                    130:
                    131: /*
                    132:  * We use the debug_mem_mutex here because we need to lock it anyway to call
                    133:  * free. This is probably a bug somewhere else in the code, but when I call
                    134:  * malloc/free outside of any lock, I have endless trouble with malloc
                    135:  * appearing to return the same pointer twice. Since we have to lock it
                    136:  * anyway, we might as well use it as the lock around the al_free_list.
                    137:  * Note that we can't call Free with the debug_mem_mutex locked.
                    138:  */
                    139: void
                    140: rf_FreeAllocList(RF_AllocListElem_t *l)
                    141: {
                    142:        int i;
                    143:        RF_AllocListElem_t *temp, *p;
                    144:
                    145:        for (p = l; p; p = p->next) {
                    146:                RF_ASSERT(p->numPointers >= 0 &&
                    147:                    p->numPointers <= RF_POINTERS_PER_ALLOC_LIST_ELEMENT);
                    148:                for (i = 0; i < p->numPointers; i++) {
                    149:                        RF_ASSERT(p->pointers[i]);
                    150:                        RF_Free(p->pointers[i], p->sizes[i]);
                    151:                }
                    152:        }
                    153:        while (l) {
                    154:                temp = l;
                    155:                l = l->next;
                    156:                if (al_free_list_count > RF_AL_FREELIST_MAX) {
                    157:                        DO_FREE(temp, sizeof(*temp));
                    158:                } else {
                    159:                        temp->next = al_free_list;
                    160:                        al_free_list = temp;
                    161:                        al_free_list_count++;
                    162:                }
                    163:        }
                    164: }
                    165:
                    166: RF_AllocListElem_t *
                    167: rf_real_MakeAllocList(int lockflag)
                    168: {
                    169:        RF_AllocListElem_t *p;
                    170:
                    171:        if (al_free_list) {
                    172:                fl_hit_count++;
                    173:                p = al_free_list;
                    174:                al_free_list = p->next;
                    175:                al_free_list_count--;
                    176:        } else {
                    177:                fl_miss_count++;
                    178:                RF_Malloc(p, sizeof(RF_AllocListElem_t),
                    179:                    (RF_AllocListElem_t *));    /*
                    180:                                                 * No allocation locking
                    181:                                                 * in kernel, so this is
                    182:                                                 * fine.
                    183:                                                 */
                    184:        }
                    185:        if (p == NULL) {
                    186:                return (NULL);
                    187:        }
                    188:        bzero((char *) p, sizeof(RF_AllocListElem_t));
                    189:        return (p);
                    190: }

CVSweb