The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/vinum/vinummemory.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1997, 1998
    3  *      Nan Yang Computer Services Limited.  All rights reserved.
    4  *
    5  *  This software is distributed under the so-called ``Berkeley
    6  *  License'':
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Nan Yang Computer
   19  *      Services Limited.
   20  * 4. Neither the name of the Company nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * This software is provided ``as is'', and any express or implied
   25  * warranties, including, but not limited to, the implied warranties of
   26  * merchantability and fitness for a particular purpose are disclaimed.
   27  * In no event shall the company or contributors be liable for any
   28  * direct, indirect, incidental, special, exemplary, or consequential
   29  * damages (including, but not limited to, procurement of substitute
   30  * goods or services; loss of use, data, or profits; or business
   31  * interruption) however caused and on any theory of liability, whether
   32  * in contract, strict liability, or tort (including negligence or
   33  * otherwise) arising in any way out of the use of this software, even if
   34  * advised of the possibility of such damage.
   35  *
   36  * $Id: vinummemory.c,v 1.1.1.1 2003/10/10 03:08:44 grog Exp $
   37  * $FreeBSD$
   38  */
   39 
   40 #include <dev/vinum/vinumhdr.h>
   41 
   42 #ifdef VINUMDEBUG
   43 #include <dev/vinum/request.h>
   44 extern struct rqinfo rqinfo[];
   45 extern struct rqinfo *rqip;
   46 int rqinfo_size = RQINFO_SIZE;                              /* for debugger */
   47 
   48 #undef longjmp                                              /* this was defined as LongJmp */
   49 /* XXX add tests for buf validity */
   50 void
   51 LongJmp(label_t * buf)
   52 {
   53     longjmp(buf);
   54 }
   55 
   56 #endif /* VINUMDEBUG */
   57 
   58 /* find the base name of a path name */
   59 char *
   60 basename(char *file)
   61 {
   62     char *f = strrchr(file, '/');                           /* chop off dirname if present */
   63 
   64     if (f == NULL)
   65         return file;
   66     else
   67         return ++f;                                         /* skip the / */
   68 }
   69 
   70 void
   71 expand_table(void **table, int oldsize, int newsize)
   72 {
   73     if (newsize > oldsize) {
   74         int *temp;
   75         int s;
   76 
   77         s = splhigh();
   78         temp = (int *) Malloc(newsize);                     /* allocate a new table */
   79         CHECKALLOC(temp, "vinum: Can't expand table\n");
   80         bzero((char *) temp, newsize);                      /* clean it all out */
   81         if (*table != NULL) {                               /* already something there, */
   82             bcopy((char *) *table, (char *) temp, oldsize); /* copy it to the old table */
   83             Free(*table);
   84         }
   85         *table = temp;
   86         splx(s);
   87     }
   88 }
   89 
   90 #ifdef VINUMDEBUG                                           /* XXX debug */
   91 #define MALLOCENTRIES 16384
   92 int malloccount = 0;
   93 int highwater = 0;                                          /* highest index ever allocated */
   94 struct mc malloced[MALLOCENTRIES];
   95 
   96 #define FREECOUNT 64
   97 int freecount = FREECOUNT;                                  /* for debugger */
   98 int lastfree = 0;
   99 struct mc freeinfo[FREECOUNT];
  100 
  101 int total_malloced;
  102 static int mallocseq = 0;
  103 
  104 caddr_t
  105 MMalloc(int size, char *file, int line)
  106 {
  107     int s;
  108     caddr_t result;
  109     int i;
  110 
  111     if (malloccount >= MALLOCENTRIES) {                     /* too many */
  112         log(LOG_ERR, "vinum: can't allocate table space to trace memory allocation");
  113         return 0;                                           /* can't continue */
  114     }
  115     /* Wait for malloc if we can */
  116     /*
  117      * XXX We can wait if we're in process context.  How do we tell?
  118      */
  119     result = malloc(size, M_DEVBUF, M_NOWAIT);
  120     if (result == NULL)
  121         log(LOG_ERR, "vinum: can't allocate %d bytes from %s:%d\n", size, file, line);
  122     else {
  123         s = splhigh();
  124         for (i = 0; i < malloccount; i++) {
  125             if (((result + size) > malloced[i].address)
  126                 && (result < malloced[i].address + malloced[i].size)) /* overlap */
  127                 panic("Malloc overlap");
  128         }
  129         if (result) {
  130             char *f = basename(file);
  131 
  132             i = malloccount++;
  133             total_malloced += size;
  134             microtime(&malloced[i].time);
  135             malloced[i].seq = mallocseq++;
  136             malloced[i].size = size;
  137             malloced[i].line = line;
  138             malloced[i].address = result;
  139             bcopy(f, malloced[i].file, min(strlen(f), MCFILENAMELEN - 1));
  140             malloced[i].file[MCFILENAMELEN - 1] = '\0';
  141         }
  142         if (malloccount > highwater)
  143             highwater = malloccount;
  144         splx(s);
  145     }
  146     return result;
  147 }
  148 
  149 void
  150 FFree(void *mem, char *file, int line)
  151 {
  152     int s;
  153     int i;
  154 
  155     s = splhigh();
  156     for (i = 0; i < malloccount; i++) {
  157         if ((caddr_t) mem == malloced[i].address) {         /* found it */
  158             bzero(mem, malloced[i].size);                   /* XXX */
  159             free(mem, M_DEVBUF);
  160             malloccount--;
  161             total_malloced -= malloced[i].size;
  162             if (debug & DEBUG_MEMFREE) {                    /* keep track of recent frees */
  163                 char *f = strrchr(file, '/');               /* chop off dirname if present */
  164 
  165                 if (f == NULL)
  166                     f = file;
  167                 else
  168                     f++;                                    /* skip the / */
  169 
  170                 microtime(&freeinfo[lastfree].time);
  171                 freeinfo[lastfree].seq = malloced[i].seq;
  172                 freeinfo[lastfree].size = malloced[i].size;
  173                 freeinfo[lastfree].line = line;
  174                 freeinfo[lastfree].address = mem;
  175                 bcopy(f, freeinfo[lastfree].file, min(strlen(f), MCFILENAMELEN - 1));
  176                 freeinfo[lastfree].file[MCFILENAMELEN - 1] = '\0';
  177                 if (++lastfree == FREECOUNT)
  178                     lastfree = 0;
  179             }
  180             if (i < malloccount)                            /* more coming after */
  181                 bcopy(&malloced[i + 1], &malloced[i], (malloccount - i) * sizeof(struct mc));
  182             splx(s);
  183             return;
  184         }
  185     }
  186     splx(s);
  187     log(LOG_ERR,
  188         "Freeing unallocated data at 0x%p from %s, line %d\n",
  189         mem,
  190         file,
  191         line);
  192     panic("Free");
  193 }
  194 
  195 void
  196 vinum_meminfo(caddr_t data)
  197 {
  198     struct meminfo *m = (struct meminfo *) data;
  199 
  200     m->mallocs = malloccount;
  201     m->total_malloced = total_malloced;
  202     m->malloced = malloced;
  203     m->highwater = highwater;
  204 }
  205 
  206 int
  207 vinum_mallocinfo(caddr_t data)
  208 {
  209     struct mc *m = (struct mc *) data;
  210     unsigned int ent = m->seq;                              /* index of entry to return */
  211 
  212     if (ent >= malloccount)
  213         return ENOENT;
  214     m->address = malloced[ent].address;
  215     m->size = malloced[ent].size;
  216     m->line = malloced[ent].line;
  217     m->seq = malloced[ent].seq;
  218     bcopy(malloced[ent].file, m->file, MCFILENAMELEN);
  219     return 0;
  220 }
  221 
  222 /*
  223  * return the nth request trace buffer entry.  This
  224  * is indexed back from the current entry (which
  225  * has index 0)
  226  */
  227 int
  228 vinum_rqinfo(caddr_t data)
  229 {
  230     struct rqinfo *rq = (struct rqinfo *) data;
  231     int ent = *(int *) data;                                /* 1st word is index */
  232     int lastent = rqip - rqinfo;                            /* entry number of current entry */
  233 
  234     if (ent >= RQINFO_SIZE)                                 /* out of the table */
  235         return ENOENT;
  236     if ((ent = lastent - ent - 1) < 0)
  237         ent += RQINFO_SIZE;                                 /* roll over backwards */
  238     bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo));
  239     return 0;
  240 }
  241 #endif

Cache object: 1fad9bdfa70303d1941afc9d691c1994


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.