memtrack.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 572 行 · 第 1/2 页

C
572
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdarg.h>

#define ALLOC_BYTE      0xA5
#define FREED_BYTE      0xBD
#define TRACK_SIZE      0xFF0

enum { FALSE = 0==1, TRUE = 0==0 };

#ifndef FAR
    #ifdef _EXTRA_MEM
        #define FAR far
    #else
        #define FAR
    #endif
#endif

typedef struct track_entry FAR * TRPTR;

typedef struct tracker {
        TRPTR                   mem_a_list;
        unsigned long           mem_used;
        unsigned long           max_mem;
        void                    *(*alloc)(int);
        void                    *(*realloc)(void *,int);
        void                    (*free)(void*);
        void                    (*prt_line)(char*,unsigned);
        char                    name[1];
} tracker;

typedef struct track_entry {
        TRPTR                   next;
        void                    *mem;
        void                    (*who)();
        unsigned int            size;
} track_entry;

#ifdef _SYS_CHKS

extern  char            MemOk(void *,int);
extern  void            *MemOtherOk();

#endif

#ifdef _EXTRA_MEM

extern  void FAR *      ExtMemAlloc(unsigned int);
#pragma aux ExtMemAlloc = \
        0xB4 0x48       /*      mov     ax,048H */ \
        0xCD 0x21       /*      int     21H */ \
        0x73 0x02       /*      jnb     L1 */ \
        0x31 0xC0       /*      xor     ax,ax */ \
        0x89 0xC2       /*L1:   mov     dx,ax */ \
        0x31 0xC0       /*      xor     ax,ax */ \
        parm routine [ bx ] \
        ;

extern  unsigned int    ExtMemAvail();
#pragma aux ExtMemAvail = \
        0xBB 0xFF 0xFF  /*      mov     bx,0FFFFH */ \
        0xB4 0x48       /*      mov     ah,48H */ \
        0xCD 0x21       /*      int     21H */ \
        0xD3 0xE3       /*      shl     bx,cl */ \
        value [ bx ] \
        ;

extern  void            ExtMemFree(void FAR *);
#pragma aux ExtMemFree = \
        0x06            /*      push    es */ \
        0x8E 0xC2       /*      mov     es,dx */ \
        0xB4 0x49       /*      mov     ah,49H */ \
        0xCD 0x21       /*      int     21H */ \
        0x07            /*      pop     es */ \
        parm routine [ dx ax ] \
        ;


static TRPTR    TrkFrl;
static TRPTR    ExtMem;
static TRPTR    TrkBeg;

#endif

#if defined(__SMALL__) || defined(__MEDIUM__)

#define _PtrAdd( p, i )     ((void *)((char *)(p) + i))
#define _PT( p )            ((void *) p)

#else

#define _PtrAdd( p, i )     ((void *)((char huge *)(p) + i))
#define _PT( p )            ((void huge *) p)


#endif

typedef void (*code_ptr)();

#define _PrtLine                trk->prt_line
#define _Free                   trk->free
#define _Alloc                  trk->alloc
#define _ReAlloc                trk->realloc

#define Next(trk)               trk->next
#define Size(trk)               trk->size
#define Who(trk)                trk->who
#define Mem(trk)                trk->mem

#define SetNext(trk,n)         trk->next = n
#define SetSize(trk,s)         trk->size = s
#define SetWho(trk,w)          trk->who = w
#define SetMem(trk,m)          trk->mem = m

#define TR_NO_ROUTINE       ((void (*)())0)


static char *CopyStr( char *src, char *dest )
{
    while( *dest = *src ) {
        ++src;
        ++dest;
    }
    return( dest );
}

static char *FormHex( char *ptr, unsigned long data, unsigned size )
{
    char            *str;

    size *= 2;
    ptr += size;
    str = ptr;
    for( ; size > 0; size-- ) {
        *--str = "0123456789abcdef"[data & 0x0f];
        data >>= 4;
    }
    return( ptr );
}

void TrPrt( tracker *trk, char *fmt, ... )
{
    va_list     args;
    char        buff[80];
    char        *ptr;
    char        ch;
    unsigned    ui;
    unsigned long ul;
    void        *dp;
    code_ptr    cp;

    va_start( args, fmt );
    ptr = buff;
    for( ;; ) {
        ch = *fmt++;
        if( ch == '\0' ) break;
        if( ch == '%' ) {
            ch = *fmt++;
            switch( ch ) {
            case 'N':   /* name of tracker invoker */
                ptr = CopyStr( trk->name, ptr );
                break;
            case 'W':   /* "%Na1(a2):" */
                ptr = CopyStr( trk->name, ptr );
                ptr = CopyStr( va_arg( args, char * ), ptr );
                cp = va_arg( args, code_ptr );
                if( cp != TR_NO_ROUTINE ) {
                    *ptr++ = '(';
                    ptr = FormHex( ptr, (unsigned long)cp, sizeof( cp ) );
                    *ptr++ = ')';
                }
                *ptr++ = ':';
                break;
            case 'C':   /* code pointer */
                cp = va_arg( args, code_ptr );
                ptr = FormHex( ptr, (unsigned long)cp, sizeof( cp ) );
                break;
            case 'D':   /* data pointer */
                dp = va_arg( args, void * );
                ptr = FormHex( ptr, (unsigned long)dp, sizeof( dp ) );
                break;
            case 'U':   /* unsigned integer */
                ui = va_arg( args, unsigned );
                ptr = FormHex( ptr, (unsigned long)ui, sizeof( ui ) );
                break;
            case 'L':   /* unsigned long */
                ul = va_arg( args, unsigned long );
                ptr = FormHex( ptr, (unsigned long)ul, sizeof( ul ) );
                break;
            default:
                *ptr++ = ch;
                break;
            }
        } else {
           *ptr++ = ch;
        }
    }
    va_end( args );
    *ptr = '\0';
    _PrtLine( buff, ptr - buff );
}


#pragma off(unreferenced);
static TRPTR   AllocTrk( tracker *trk ) {
#pragma on(unreferenced);
/***********************************/

    TRPTR       entry;

#ifdef _EXTRA_MEM
    if( TrkFrl != 0 ) {
        entry = TrkFrl;
        TrkFrl = Next( TrkFrl );
    } else {
        entry = TrkBeg++;
    }
#else
    entry = _Alloc( sizeof( track_entry ) );
#endif
    return( entry );
}

#pragma off(unreferenced);
static  void    FreeTrk( TRPTR  entry, tracker *trk ) {
#pragma on(unreferenced);
/*********************************************/

#ifdef _EXTRA_MEM
    SetNext( entry, TrkFrl );
    TrkFrl = entry;
#else
    _Free( entry );
#endif
}


static  void    Fill( void *start, unsigned len, char filler ) {
/**********************************************************/

    char    *ptr;

    ptr = start;
    while( len != 0 ) {
        *ptr++ = filler;
        --len;
    }
}

extern  tracker *TrMemInit( char *name,
                            void *(*alloc)(int),
                            void *(*realloc)(void *,int),
                            void (*free)(void *),
                            void (*prt_line)(char *, unsigned) ){

    tracker     *trk;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?