root/dev/raidframe/rf_alloclist.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rf_ShutdownAllocList
  2. rf_ConfigureAllocList
  3. rf_real_AddToAllocList
  4. rf_FreeAllocList
  5. rf_real_MakeAllocList

    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 }

/* [<][>][^][v][top][bottom][index][help] */