⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcsl_memory.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 	 * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * * PCSL memory functions. * * With these functions, we have the ability to manage our own * memory pool. This avoids memory fragmentation in the overall * system. However, it does not address the potential problem * of memory fragmentation within the PCSL application itself. * * The memory pool is one contiguous chunk of memory split up * into various free or allocated blocks. All blocks have the * same layout. * * <table border=1> * <tr><th scope=col>Contents of the Memory Block</th></tr> * <tr><td>magic (value of 0xCAFE)</td></tr> * <tr><td>free (value of 0 or 1)</td></tr> * <tr><td>reserved/<sup>[*]</sup>guardSize</td></tr> * <tr><td>size</td></tr> * <tr><td><sup>[*]</sup>filename</td></tr> * <tr><td><sup>[*]</sup>lineno</td></tr> * <tr><td>1 .. size</td></tr> * <tr><td><sup>[*]</sup>1 .. guardSize</td></tr> * </table> * * <p>Items that have the prefix <sup>[*]</sup> are only enabled if memory * tracing is enabled. * * @warning This code is not thread safe. */#include <stdio.h>#include <stdarg.h>#include <string.h>#include <pcsl_memory.h>#include <pcsl_print.h>#include <pcsl_memory_port.h>#ifdef PCSL_DEBUG/*  * define debug macros and function which use pcsl_print() for output  */#define REPORT(msg) report(msg)#define REPORT1(msg, a1) report(msg, a1)#define REPORT2(msg, a1, a2) report(msg, a1, a2)#define REPORT3(msg, a1, a2, a3) report(msg, a1, a2, a3)#define REPORT4(msg, a1, a2, a3, a4) report(msg, a1, a2, a3, a4)/* * maximum lenght of debug output using report methods */#define RPT_BUF_LEN 200/* * buffer for constructing report strings */static char buf[RPT_BUF_LEN];/** * Report a variable argument message via pcsl_print. * * The <code>message</code> parameter is treated as a format * string to the standard C library call printf would be, with * conversion specifications (%s, %d, %c, etc) causing the  * conversion and output of each successive argument after * <code>message</code>  As with printf, having a conversion * character in <code>message</code> without an associated argument * following it is an error. * * To ensure that no character in <code>message</code> is  * interpreted as requiring conversion, a safe way to call * this method is: * <code> report("%s", message); </code> * @param message detail message to go with the report *                should not be NULL */static void report(char* message, ...){      va_list ap;    if (message != NULL) {        va_start(ap, message);        #ifdef _WIN32        _vsnprintf(buf, RPT_BUF_LEN, message, ap);#else        vsnprintf(buf, RPT_BUF_LEN, message, ap);#endif        pcsl_print(buf);                va_end(ap);    }}/** * An internal helper function used when PCSL_DEBUG is defined. *  * print_alloc( what, filename, lineno); */static void print_alloc(const char* what, char* filename, int lineno) {    report("alloc: %s at %s line %d\n",            what, filename, lineno);}#else  /* PCSL_DEBUG is not defined */#define REPORT(msg)#define REPORT1(msg, a1)#define REPORT2(msg, a1, a2)#define REPORT3(msg, a1, a2, a3)#define REPORT4(msg, a1, a2, a3, a4)#endif #ifdef PCSL_DEBUG/** *  If you are interested in very verbose output about every block allocated/coalesced/freed you can enable this define *	Keep it zero otherwise */#define PCSL_TRACE_MEMORY  0#endif /** * If defined as non-zero, memory allocator will use best-fit algorithm. * If defined as zero, memory allocator will use first-fit algorithm. * * When first-fit algorithm is used, Java heap allocation can fail in SVM mode  * even though there is enough free memory in the pool (see CR 6735718). * This is because first-fit allocation cause bad fragmentation for allocation * request patterns typical for SVM mode. */#define PCSL_BEST_FIT_ALLOCATION 1/** * Structure to hold memory blocks */typedef struct _pcslMemStruct {    unsigned short magic;                                    /* magic number */    char           free;           /* 1 == block is free, 0 == block is used */#ifdef PCSL_DEBUG    char           guardSize;           /* Size of tail guard data; in bytes */#else    char           reserved;#endif     unsigned int   size;                                    /* size of block */#ifdef PCSL_DEBUG    char*          filename;         /* filename where allocation took place */    unsigned int   lineno;        /* line number wehre allocation took place */    unsigned int   guard;                                    /* memory guard */#endif} _PcslMemHdr, *_PcslMemHdrPtr;/* * Default size of pool usable for allocations; in bytes */#define DEFAULT_POOL_SIZE (8024*1024)/* * Byte boundary for word alignment */#define ALIGNMENT     0x00000003                  /* Assumes word is 4-bytes *//* * Constant to verify a header's validity */#define MAGIC         0xCAFE/* * Constants to guard memory */#define GUARD_WORD    0x9A9A9A9A                  /* Assumes word is 4-bytes */#define GUARD_BYTE    0x9A/* * Minimum number of guard bytes to put at end of the memory block */#define GUARD_SIZE    4#ifdef PCSL_MEMORY_USE_STATIC/* Cannot allocate dynamic memory on the phone. Use static array. */static char PcslMemory[DEFAULT_POOL_SIZE];       /* Where PCSL memory starts */#else  /* use malloc or similar function provided */static char* PcslMemory;                         /* Where PCSL memory starts */#endifstatic char* PcslMemoryStart;                /* Aligned start of PCSL memory */static char* PcslMemoryEnd;                                 /* End of memory */static int PcslMemoryHighWaterMark;static int PcslMemoryAllocated;static int pcsl_end_memory(int* count, int* size);static int verify_tail_guard_data(_PcslMemHdrPtr pcslMemoryHdr);/** * @internal * * FUNCTION:      pcsl_end_memory() * TYPE:          private operation * OVERVIEW:      Finalize the PCSL memory pool * INTERFACE: *   parameters:  count   address to store memory leak count *                size    address to store totol bytes of memory leaked *   returns:     the number of memory leaks detected *                 */static intpcsl_end_memory(int* count, int* size) {    _PcslMemHdrPtr pcslMemoryHdr;    char*          pcslMemoryPtr;    *count = 0;    *size  = 0;    for (pcslMemoryPtr = PcslMemoryStart;          pcslMemoryPtr < PcslMemoryEnd;         pcslMemoryPtr += pcslMemoryHdr->size + sizeof(_PcslMemHdr)) {        pcslMemoryHdr = (_PcslMemHdrPtr)pcslMemoryPtr;        if (pcslMemoryHdr->magic != MAGIC) {            REPORT1("ERROR: Corrupted start of memory header: 0x%p\n",                     pcslMemoryPtr);            return -1;        }#ifdef PCSL_DEBUG        if (pcslMemoryHdr->guard != GUARD_WORD) {            report("ERROR: Corrupted end of memory header: 0x%p\n",                   pcslMemoryPtr);            return -1;        }        /* The memory block header is valid, now check the guard data */        if (verify_tail_guard_data(pcslMemoryHdr)) {            report("ERROR: Memory overrun: 0x%p\n",                   pcslMemoryPtr);            print_alloc("allocated",                         pcslMemoryHdr->filename,                         pcslMemoryHdr->lineno);        }#endif         if (pcslMemoryHdr->free != 1) {#ifdef PCSL_DEBUG            report("WARNING: memory leak: size= %d  address= 0x%p\n",                   pcslMemoryHdr->size,                   (void*)((char*)pcslMemoryHdr + sizeof(_PcslMemHdr)));            print_alloc("allocated",                         pcslMemoryHdr->filename, pcslMemoryHdr->lineno);#endif            pcsl_mem_free((void*)((char*)pcslMemoryHdr + sizeof(_PcslMemHdr)));            *count += 1;            *size  += pcslMemoryHdr->size;        }    }    return *count;}/** * FUNCTION:      pcsl_mem_initialize_impl0() * TYPE:          public operation * OVERVIEW:      Initialize the PCSL memory pool *                 NOTE: This must only be called once * INTERFACE: * parameters:   *                 startAddr Starting address of memory pool. If NULL, it will *                           be either dynamically or statically allocated. *                 size   Size of memory pool to use; if size is <= 0, *                        the default memory pool size will be used *   returns:     0 on succes; != 0 on failure *                 */intpcsl_mem_initialize_impl0(void *startAddr, int size) {    _PcslMemHdrPtr pcslMemoryHdr;    if (PcslMemoryStart != NULL) {        /* avoid a double init */        return 0;    }    if (size <= 0) {        /* size not specified, use the default */        size = DEFAULT_POOL_SIZE;    }    if (startAddr != NULL) {        PcslMemory = (char *)startAddr;    } else {        #ifndef PCSL_MEMORY_USE_STATIC        /* allocate the chunk of memory to C heap */        PcslMemory = (char*)pcsl_heap_allocate_port(size,&size);        if (PcslMemory == NULL) {            return -1;        }#endif /* ! PCSL_MEMORY_USE_STATIC */    }    PcslMemoryStart = PcslMemory;    PcslMemoryEnd   = PcslMemory + size - sizeof(_PcslMemHdr);    /* Word alignment */    while (((long)PcslMemoryStart & ALIGNMENT) != 0) {        PcslMemoryStart++;    }    pcslMemoryHdr = (_PcslMemHdrPtr)PcslMemoryStart;    pcslMemoryHdr->magic = MAGIC;    pcslMemoryHdr->free  = 1;    pcslMemoryHdr->size  = (PcslMemory - PcslMemoryStart)                           + size - sizeof(_PcslMemHdr);#ifdef PCSL_DEBUG    pcslMemoryHdr->guard = GUARD_WORD;    pcslMemoryHdr->guardSize = 0;#endif    return 0;}/** * FUNCTION:      pcsl_mem_finalize_impl0() * TYPE:          public operation * OVERVIEW:      Finalize the PCSL memory pool * INTERFACE: *   parameters:  <none> *   returns:     <nothing> *                 */voidpcsl_mem_finalize_impl0() {    int count, size, ret;    ret = pcsl_end_memory(&count, &size);#ifdef PCSL_DEBUG    if (ret > 0) {      report("WARNING: %d memory leak(s); %d bytes!\n",             count, size);    }    report("** Total memory: %d\n** Highwater mark:%d",           pcsl_mem_get_total_heap_impl0(), PcslMemoryHighWaterMark);#endif #ifndef PCSL_MEMORY_USE_STATIC           pcsl_heap_deallocate_port(PcslMemory);    PcslMemory = NULL;#endif    PcslMemoryStart = NULL;    PcslMemoryEnd = NULL;}/** * FUNCTION:      pcsl_mem_malloc_impl0() * TYPE:          public operation * OVERVIEW:      Allocate memory from the private PCSL memory pool * INTERFACE: *   parameters:  size       Number of byte to allocate *                filename   Filename where allocation occured *                lineno     Line number where allocation occured *   returns:     pointer to the newly allocated memory *                 */#ifdef PCSL_DEBUGvoid*pcsl_mem_malloc_impl0(unsigned int size, char* filename, int lineno) {#elsevoid*pcsl_mem_malloc_impl0(unsigned int size) {#endif    unsigned int   numBytesToAllocate = size;    void*          loc     = NULL;    _PcslMemHdrPtr tempHdr = NULL;    char*          temp    = NULL;    char*          pcslMemoryPtr;    _PcslMemHdrPtr pcslMemoryHdr;    _PcslMemHdrPtr fitBlockHdr = NULL;#ifdef PCSL_DEBUG    int   guardSize = 0;    void* guardPos = NULL;    int   i = 0;    numBytesToAllocate += GUARD_SIZE;#endif    while ( (numBytesToAllocate & ALIGNMENT) != 0 ) {        numBytesToAllocate++;    }    /* find a free slot */    for (pcslMemoryPtr = PcslMemoryStart;         pcslMemoryPtr < PcslMemoryEnd;         pcslMemoryPtr += pcslMemoryHdr->size + sizeof(_PcslMemHdr)) {                pcslMemoryHdr = (_PcslMemHdrPtr)pcslMemoryPtr;        if (pcslMemoryHdr->magic != MAGIC) {            REPORT1("ERROR: Memory corruption at 0x%p\n", pcslMemoryPtr);             return((void *) 0);        } else {            while ( 1 ) {                /* coalescing */                if (pcslMemoryHdr->free == 1) {                    /* if current block is free */                    temp = (char*)pcslMemoryHdr;                    temp += pcslMemoryHdr->size + sizeof(_PcslMemHdr);                    tempHdr = (_PcslMemHdrPtr)temp;                    if ((temp < PcslMemoryEnd) &&                         (tempHdr->free == 1) && (tempHdr->magic == MAGIC)) {                        /* and the next block is free too */                        /* then coalesce */                        pcslMemoryHdr->size += tempHdr->size                            + sizeof(_PcslMemHdr);#ifdef PCSL_DEBUG                        pcslMemoryHdr->guardSize = 0;#if PCSL_TRACE_MEMORY                        REPORT2("DEBUG: Coalescing blocks 0x%p and 0x%p\n",                                pcslMemoryHdr, tempHdr);#endif #endif                    } else {                        break;                    }                } else {                    break;

⌨️ 快捷键说明

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