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

Cache object: 15744c065023024d20fd352768418d41


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