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.28 2001/05/23 23:04:06 grog Exp grog $
   37  * $FreeBSD: releng/5.0/sys/dev/vinum/vinummemory.c 83366 2001-09-12 08:38:13Z julian $
   38  */
   39 
   40 #include <dev/vinum/vinumhdr.h>
   41 
   42 #ifdef VINUMDEBUG
   43 #undef longjmp                                              /* this was defined as LongJmp */
   44 
   45 #include <dev/vinum/request.h>
   46 extern struct rqinfo rqinfo[];
   47 extern struct rqinfo *rqip;
   48 int rqinfo_size = RQINFO_SIZE;                              /* for debugger */
   49 
   50 #ifdef __i386__                                             /* check for validity */
   51 void
   52 LongJmp(jmp_buf buf, int retval)
   53 {
   54 /*
   55    * longjmp is not documented, not even jmp_buf.
   56    * This is what's in i386/i386/support.s:
   57    * ENTRY(longjmp)
   58    *    movl    4(%esp),%eax
   59    *    movl    (%eax),%ebx                      restore ebx
   60    *    movl    4(%eax),%esp                     restore esp
   61    *    movl    8(%eax),%ebp                     restore ebp
   62    *    movl    12(%eax),%esi                    restore esi
   63    *    movl    16(%eax),%edi                    restore edi
   64    *    movl    20(%eax),%edx                    get rta
   65    *    movl    %edx,(%esp)                      put in return frame
   66    *    xorl    %eax,%eax                        return(1);
   67    *    incl    %eax
   68    *    ret
   69    *
   70    * from which we deduce the structure of jmp_buf:
   71  */
   72     struct JmpBuf {
   73         int jb_ebx;
   74         int jb_esp;
   75         int jb_ebp;
   76         int jb_esi;
   77         int jb_edi;
   78         int jb_eip;
   79     };
   80 
   81     struct JmpBuf *jb = (struct JmpBuf *) buf;
   82 
   83     if ((jb->jb_esp < 0xc0000000)
   84         || (jb->jb_ebp < 0xc0000000)
   85         || (jb->jb_eip < 0xc0000000))
   86         panic("Invalid longjmp");
   87     longjmp(buf, retval);
   88 }
   89 
   90 #else
   91 #define LongJmp longjmp                                     /* just use the kernel function */
   92 #endif
   93 #endif
   94 
   95 /* find the base name of a path name */
   96 char *
   97 basename(char *file)
   98 {
   99     char *f = rindex(file, '/');                            /* chop off dirname if present */
  100 
  101     if (f == NULL)
  102         return file;
  103     else
  104         return ++f;                                         /* skip the / */
  105 }
  106 
  107 void
  108 expand_table(void **table, int oldsize, int newsize)
  109 {
  110     if (newsize > oldsize) {
  111         int *temp;
  112         int s;
  113 
  114         s = splhigh();
  115         temp = (int *) Malloc(newsize);                     /* allocate a new table */
  116         CHECKALLOC(temp, "vinum: Can't expand table\n");
  117         bzero((char *) temp, newsize);                      /* clean it all out */
  118         if (*table != NULL) {                               /* already something there, */
  119             bcopy((char *) *table, (char *) temp, oldsize); /* copy it to the old table */
  120             Free(*table);
  121         }
  122         *table = temp;
  123         splx(s);
  124     }
  125 }
  126 
  127 #ifdef VINUMDEBUG                                           /* XXX debug */
  128 #define MALLOCENTRIES 16384
  129 int malloccount = 0;
  130 int highwater = 0;                                          /* highest index ever allocated */
  131 struct mc malloced[MALLOCENTRIES];
  132 
  133 #define FREECOUNT 64
  134 int freecount = FREECOUNT;                                  /* for debugger */
  135 int lastfree = 0;
  136 struct mc freeinfo[FREECOUNT];
  137 
  138 int total_malloced;
  139 static int mallocseq = 0;
  140 
  141 caddr_t
  142 MMalloc(int size, char *file, int line)
  143 {
  144     int s;
  145     caddr_t result;
  146     int i;
  147 
  148     if (malloccount >= MALLOCENTRIES) {                     /* too many */
  149         log(LOG_ERR, "vinum: can't allocate table space to trace memory allocation");
  150         return 0;                                           /* can't continue */
  151     }
  152     /* Wait for malloc if we can */
  153     result = malloc(size,
  154         M_DEVBUF,
  155         curthread->td_intr_nesting_level == 0 ? M_WAITOK : M_NOWAIT);
  156     if (result == NULL)
  157         log(LOG_ERR, "vinum: can't allocate %d bytes from %s:%d\n", size, file, line);
  158     else {
  159         s = splhigh();
  160         for (i = 0; i < malloccount; i++) {
  161             if (((result + size) > malloced[i].address)
  162                 && (result < malloced[i].address + malloced[i].size)) /* overlap */
  163                 Debugger("Malloc overlap");
  164         }
  165         if (result) {
  166             char *f = basename(file);
  167 
  168             i = malloccount++;
  169             total_malloced += size;
  170             microtime(&malloced[i].time);
  171             malloced[i].seq = mallocseq++;
  172             malloced[i].size = size;
  173             malloced[i].line = line;
  174             malloced[i].address = result;
  175             bcopy(f, malloced[i].file, min(strlen(f), MCFILENAMELEN - 1));
  176             malloced[i].file[MCFILENAMELEN - 1] = '\0';
  177         }
  178         if (malloccount > highwater)
  179             highwater = malloccount;
  180         splx(s);
  181     }
  182     return result;
  183 }
  184 
  185 void
  186 FFree(void *mem, char *file, int line)
  187 {
  188     int s;
  189     int i;
  190 
  191     s = splhigh();
  192     for (i = 0; i < malloccount; i++) {
  193         if ((caddr_t) mem == malloced[i].address) {         /* found it */
  194             bzero(mem, malloced[i].size);                   /* XXX */
  195             free(mem, M_DEVBUF);
  196             malloccount--;
  197             total_malloced -= malloced[i].size;
  198             if (debug & DEBUG_MEMFREE) {                    /* keep track of recent frees */
  199                 char *f = rindex(file, '/');                /* chop off dirname if present */
  200 
  201                 if (f == NULL)
  202                     f = file;
  203                 else
  204                     f++;                                    /* skip the / */
  205 
  206                 microtime(&freeinfo[lastfree].time);
  207                 freeinfo[lastfree].seq = malloced[i].seq;
  208                 freeinfo[lastfree].size = malloced[i].size;
  209                 freeinfo[lastfree].line = line;
  210                 freeinfo[lastfree].address = mem;
  211                 bcopy(f, freeinfo[lastfree].file, min(strlen(f), MCFILENAMELEN - 1));
  212                 freeinfo[lastfree].file[MCFILENAMELEN - 1] = '\0';
  213                 if (++lastfree == FREECOUNT)
  214                     lastfree = 0;
  215             }
  216             if (i < malloccount)                            /* more coming after */
  217                 bcopy(&malloced[i + 1], &malloced[i], (malloccount - i) * sizeof(struct mc));
  218             splx(s);
  219             return;
  220         }
  221     }
  222     splx(s);
  223     log(LOG_ERR,
  224         "Freeing unallocated data at 0x%p from %s, line %d\n",
  225         mem,
  226         file,
  227         line);
  228     Debugger("Free");
  229 }
  230 
  231 void
  232 vinum_meminfo(caddr_t data)
  233 {
  234     struct meminfo *m = (struct meminfo *) data;
  235 
  236     m->mallocs = malloccount;
  237     m->total_malloced = total_malloced;
  238     m->malloced = malloced;
  239     m->highwater = highwater;
  240 }
  241 
  242 int
  243 vinum_mallocinfo(caddr_t data)
  244 {
  245     struct mc *m = (struct mc *) data;
  246     unsigned int ent = m->seq;                              /* index of entry to return */
  247 
  248     if (ent >= malloccount)
  249         return ENOENT;
  250     m->address = malloced[ent].address;
  251     m->size = malloced[ent].size;
  252     m->line = malloced[ent].line;
  253     m->seq = malloced[ent].seq;
  254     bcopy(malloced[ent].file, m->file, MCFILENAMELEN);
  255     return 0;
  256 }
  257 
  258 /*
  259  * return the nth request trace buffer entry.  This
  260  * is indexed back from the current entry (which
  261  * has index 0)
  262  */
  263 int
  264 vinum_rqinfo(caddr_t data)
  265 {
  266     struct rqinfo *rq = (struct rqinfo *) data;
  267     int ent = *(int *) data;                                /* 1st word is index */
  268     int lastent = rqip - rqinfo;                            /* entry number of current entry */
  269 
  270     if (ent >= RQINFO_SIZE)                                 /* out of the table */
  271         return ENOENT;
  272     if ((ent = lastent - ent - 1) < 0)
  273         ent += RQINFO_SIZE;                                 /* roll over backwards */
  274     bcopy(&rqinfo[ent], rq, sizeof(struct rqinfo));
  275     return 0;
  276 }
  277 #endif

Cache object: 7b129cada58eb634afcd10818340cdb5


[ 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.