mem.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 443 行

C
443
字号
/****************************************************************************
*
*                            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:  Internal editor memory management routines.
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "vi.h"
#include "colors.h"
#include "fcbmem.h"
#include "win.h"
#ifdef __WATCOMC__
    #include <malloc.h>
#endif
#ifdef TRMEM
    #include <fcntl.h>
    #include <unistd.h>
    #include "trmem.h"

    static int                  trmemOutput;
    static _trmem_hdl           trmemHandle;
    #define MSIZE( x )          _trmem_msize( x, trmemHandle )
#else
    typedef void *_trmem_who;
    #define _trmem_guess_who() 0
    #define MSIZE( x )          _msize( x )
#endif

/*
 * getMem - get and clear memory
 */
static void *getMem( unsigned size, _trmem_who who )
{
    void        *tmp;

#ifdef TRMEM
    tmp = _trmem_alloc( size, who, trmemHandle );
#else
    who = who;
    tmp = malloc( size );
#endif
    if( tmp != NULL ) {
#ifdef __WATCOMC__
        size = MSIZE( tmp );
#endif
        memset( tmp, 0, size );
    }
    return( tmp );

} /* getMem */

/*
 * getLRU - get lru block from fcb list
 */
static fcb *getLRU( unsigned upper_bound )
{
    long lru=MAX_LONG;
    fcb *cfcb,*tfcb=NULL;
    int bootlimit = MAX_IO_BUFFER/2;

    while( 1 ) {

        cfcb = FcbThreadHead;
        while( cfcb != NULL ) {
            if( !cfcb->on_display && !cfcb->non_swappable && cfcb->in_memory
                && cfcb->byte_cnt >= bootlimit && cfcb != CurrentFcb ) {
                    if( cfcb->last_swap == 0 ) {
                        return( cfcb );
                    }
                    if( cfcb->last_swap < lru ) {
                        lru = cfcb->last_swap;
                        tfcb = cfcb;
                    }
            }
            cfcb = cfcb->thread_next;
        }
        if( tfcb == NULL && bootlimit > 64 ) {
            bootlimit /= 2;
            if( bootlimit < upper_bound ) {
                return( NULL );
            }
            continue;
        }
        return( tfcb );
    }

} /* getLRU */

/*
 * trySwap - try to swap an fcb
 */
static void *trySwap( unsigned size, unsigned upper_bound, _trmem_who who )
{
    void        *tmp=NULL;
    fcb         *tfcb;

    while( 1 ) {

        /*
         * find LRU fcb
         */
        tfcb = getLRU( upper_bound );
        if( tfcb == NULL ) {
            break;
        }

        /*
         * swap the LRU fcb, and re-attempt allocation
         */
        SwapFcb( tfcb );
        tmp = getMem( size, who );
        if( tmp != NULL ) {
            break;
        }

    }

    return( tmp );

} /* trySwap */

/*
 * tossBoundData - get rid of bound data
 */
static void tossBoundData( void )
{
    if( EditFlags.BoundData ) {
        if( !EditFlags.BndMemoryLocked ) {
            MemFree2( &BndMemory );
        }
    }

} /* tossBoundData */



/*
 * doMemAllocUnsafe - see above
 */
void *doMemAllocUnsafe( unsigned size, _trmem_who who )
{
    void        *tmp;

    tmp = getMem( size, who );
    if( tmp == NULL ) {
        tossBoundData();
        tmp = trySwap( size, 1, who );
        if( tmp == NULL ) {
            SwapAllWindows();
            tmp = getMem( size, who );
            while( tmp == NULL ) {
                if( !TossUndos() ) {
                    return( NULL );
                }
                tmp = getMem( size, who );
            }
        }
    }
    return( tmp );
}

/*
 * MemAlloc - allocate some memory (always works, or editor aborts)
 */
void *MemAlloc( unsigned size )
{
    void        *tmp;

    tmp = doMemAllocUnsafe( size, _trmem_guess_who() );
    if( tmp == NULL ) {
        AbandonHopeAllYeWhoEnterHere( ERR_NO_MEMORY );
    }
    return( tmp );

} /* MemAlloc */

/*
 * MemAllocUnsafe - allocate some memory, return null if it fails
 */
void *MemAllocUnsafe( unsigned size )
{
    return( doMemAllocUnsafe( size, _trmem_guess_who() ) );
} /* MemAllocUnsafe */

/*
 * MemFree - free up memory
 */
void MemFree( void *ptr )
{
#ifdef TRMEM
    _trmem_free( ptr, _trmem_guess_who(), trmemHandle );
#else
    free( ptr );
#endif
} /* MemFree */

/*
 * MemFreeList - free up memory
 */
void MemFreeList( int hi, void **ptr )
{
    int i;

    if( ptr == NULL ) {
        return;
    }
    for( i=0;i<hi;i++ ) {
        MemFree( ptr[i] );
    }
    MemFree( ptr );

} /* MemFreeList */

/*
 * MemFree2 - free up memory, setting ptr to null
 */
void MemFree2( void **ptr )
{

    MemFree( *ptr );
    *ptr = NULL;

} /* MemFree2 */

/*
 * doMemReallocUnsafe - reallocate a block, return NULL if it fails
 */
void *doMemReAllocUnsafe( void *ptr, unsigned size, _trmem_who who )
{
    void        *tmp;

    unsigned    orig_size;
    unsigned    tsize;

    if( ptr != NULL ) {
#ifdef __WATCOMC__
        orig_size = MSIZE( ptr );
#else
        orig_size = 0xffffffff;
#endif
    } else {
        orig_size = 0;
    }

#ifdef TRMEM
    tmp = _trmem_realloc( ptr, size, who, trmemHandle );
#else
    tmp = realloc( ptr, size );
#endif
#ifdef __WATCOMC__
    if( tmp == NULL ) {
        tmp = doMemAllocUnsafe( size, who );
        if( tmp == NULL ) {
            return( NULL );
        }
        size = MSIZE( tmp );
        if( orig_size != 0 ) {
            tsize = orig_size;
            if( tsize > size ) {
                tsize = size;
            }
            memcpy( tmp, ptr, tsize );
            MemFree( ptr );
        }
    } else
#endif
    {
#ifdef __WATCOMC__
        size = MSIZE( tmp );
#endif
        if( size > orig_size ) {
            memset( &(((char *)tmp)[orig_size]), 0, size-orig_size );
        }
    }
    return( tmp );

} /* doMemReAllocUnsafe */

void *MemReAllocUnsafe( void *ptr, unsigned size )
{
    return( doMemReAllocUnsafe( ptr, size, _trmem_guess_who() ) );
}

/*
 * MemReAlloc - reallocate a block, and it will succeed.
 */
void *MemReAlloc( void *ptr, unsigned size )
{
    void        *tmp;

    tmp = doMemReAllocUnsafe( ptr, size, _trmem_guess_who() );
    if( tmp == NULL ) {
        AbandonHopeAllYeWhoEnterHere( ERR_NO_MEMORY );
    }
    return( tmp );

} /* MemReAlloc */

static char *staticBuffs[ MAX_STATIC_BUFFERS ];
static bool staticUse[ MAX_STATIC_BUFFERS ];
int maxStatic=0;

/*
 * StaticAlloc - allocate one of the static buffers
 */
void *StaticAlloc( void )
{
    int i;

    for( i=0;i<MAX_STATIC_BUFFERS;i++ ) {
        if( !staticUse[i] ) {
            staticUse[i] = TRUE;
            {
                int j,k=0;
                for( j=0;j<MAX_STATIC_BUFFERS;j++ ) {
                    if( staticUse[j] ) {
                        k++;
                    }
                }
                if( k > maxStatic ) {
                    maxStatic = k;
                }
            }
            return( staticBuffs[i] );
        }
    }
    return( NULL );

} /* StaticAlloc */

/*
 * StaticFree - free a static buffer
 */
void StaticFree( char *item )
{
    int i;

    for( i=0;i<MAX_STATIC_BUFFERS;i++ ) {
        if( item == staticBuffs[i] ) {
            staticUse[i] = FALSE;
            return;
        }
    }

} /* StaticFree */

/*
 * StaticStart - start up static buffer
 */
void StaticStart( void )
{
    int i,bs;

    MemFree( StaticBuffer );
    bs = MaxLine+2;
    StaticBuffer = MemAlloc( MAX_STATIC_BUFFERS* bs );
    for( i=0;i<MAX_STATIC_BUFFERS;i++ ) {
        staticUse[i] = FALSE;
        staticBuffs[i] = &StaticBuffer[i*bs];
    }

} /* StaticStart */

void StaticFini( void ) {
    MemFree( StaticBuffer );
}

/*
 * MemStrDup - Safe strdup()
 */
char *MemStrDup( char *string ){
    char *rptr;

    if( string == NULL ){
        rptr = NULL;
    } else {
        rptr = (char *)MemAlloc( strlen( string ) + 1 );
        strcpy( rptr, string );
    }
    return rptr;
}


#ifdef TRMEM

extern void trmemPrint( int * handle, const char * buff, size_t len )
/********************************************************************/
{
    write( *handle, buff, len );
}

void DumpTRMEM( void )
{
    _trmem_prt_list( trmemHandle );
    _trmem_close( trmemHandle );
    if( trmemOutput != -1 ) {
        close( trmemOutput );
    }
}

void InitTRMEM( void )
{
    char        file[ FILENAME_MAX ];

    strcpy( file, getenv( "EDPATH" ) );
    strcat( file, "\\trmem.out" );
    trmemOutput = open( file, O_RDWR | O_CREAT | O_TEXT );

    trmemHandle = _trmem_open( malloc, free, realloc, _expand,
            &trmemOutput, trmemPrint,
            _TRMEM_ALLOC_SIZE_0 | _TRMEM_REALLOC_SIZE_0 |
            _TRMEM_OUT_OF_MEMORY | _TRMEM_CLOSE_CHECK_FREE );
    // atexit( DumpTRMEM );
}
#endif

⌨️ 快捷键说明

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