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

📄 memory.c

📁 debug source code under unix platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
        return p;#endif /* TARGET */    return NULL;}/* Initialise the fields of a meminfo structure to describe the details * of the underlying memory architecture. */MP_GLOBALvoid__mp_newmemory(meminfo *i){#if MP_WATCH_SUPPORT    char b[64];#endif /* MP_WATCH_SUPPORT */#if MP_ARRAY_SUPPORT    memorysize = 0;#endif /* MP_ARRAY_SUPPORT */    i->align = minalign();    i->page = pagesize();    i->stackdir = stackdirection(NULL);    i->prog = progname();#if MP_MMAP_SUPPORT    /* On UNIX systems that support the mmap() function call, we default to     * using sbrk() for user memory and mmap() for internal memory.  If the     * MP_MMAP_ANONYMOUS macro is set then we don't need to open a file for     * mapping.     */#if MP_MMAP_ANONYMOUS    i->mfile = 0;#else /* MP_MMAP_ANONYMOUS */    i->mfile = open(MP_MMAP_FILENAME, O_RDWR);#endif /* MP_MMAP_ANONYMOUS */#else /* MP_MMAP_SUPPORT */    i->mfile = -1;#endif /* MP_MMAP_SUPPORT */#if MP_WATCH_SUPPORT    sprintf(b, MP_PROCFS_CTLNAME, __mp_processid());    i->wfile = open(b, O_WRONLY);#else /* MP_WATCH_SUPPORT */    i->wfile = -1;#endif /* MP_WATCH_SUPPORT */    i->flags = 0;}/* Free up any resources used by the meminfo structure. */MP_GLOBALvoid__mp_endmemory(meminfo *i){#if MP_MMAP_SUPPORT    if (i->mfile != -1)    {#if !MP_MMAP_ANONYMOUS        close(i->mfile);#endif /* MP_MMAP_ANONYMOUS */        i->mfile = -1;    }#endif /* MP_MMAP_SUPPORT */#if MP_WATCH_SUPPORT    if (i->wfile != -1)    {        close(i->wfile);        i->wfile = -1;    }#endif /* MP_WATCH_SUPPORT */}/* Return the process identifier. */MP_GLOBALunsigned long__mp_processid(void){#if TARGET == TARGET_UNIX || TARGET == TARGET_WINDOWS    return (unsigned long) getpid();#elif TARGET == TARGET_AMIGA    return (unsigned long) FindTask(NULL);#elif TARGET == TARGET_NETWARE    return (unsigned long) GetThreadId();#else /* TARGET */    /* We just assume that any other operating systems have no support for     * multiple processes and so anything we return here is irrelevant.     */    return 1;#endif /* TARGET */}#if MP_ARRAY_SUPPORT/* Provide sbrk()-like functionality for systems that have no system functions * for allocating heap memory.  The simulated heap grows upwards in this * implementation. */staticvoid *getmemory(long l){    void *p;    p = memoryarray + memorysize;    if (l > 0)        if (memorysize + l > MP_ARRAY_SIZE)            p = (void *) -1;        else            memorysize += l;    else if (l < 0)        if (memorysize < -l)            p = (void *) -1;        else            memorysize += l;    return p;}#elif TARGET == TARGET_UNIX#define getmemory(l) sbrk(l)#endif /* MP_ARRAY_SUPPORT && TARGET *//* Allocate a specified size of general-purpose memory from the system * with a required alignment. */MP_GLOBALvoid *__mp_memalloc(meminfo *i, size_t *l, size_t a, int u){    void *p;#if MP_ARRAY_SUPPORT || TARGET == TARGET_UNIX    void *t;    unsigned long n;#endif /* MP_ARRAY_SUPPORT && TARGET */    if (*l == 0)        *l = 1;#if MP_ARRAY_SUPPORT || TARGET == TARGET_UNIX || TARGET == TARGET_NETWARE    /* Round up the size of the allocation to a multiple of the system page     * size.     */    *l = __mp_roundup(*l, i->page);#elif TARGET == TARGET_WINDOWS    /* The VirtualAlloc() function on Windows only seems to allocate memory in     * blocks of 65536 bytes, so we round up the size of the allocation to this     * amount since otherwise the space would be wasted.     */    *l = __mp_roundup(*l, 0x10000);#elif TARGET == TARGET_AMIGA    /* We aren't guaranteed to allocate a block of memory that is page     * aligned on the Amiga, so we have to assume the worst case scenario     * and allocate more memory for the specified alignment.     */    if (a > i->page)        a = i->page;    if (a > MEM_BLOCKSIZE)        *l += __mp_poweroftwo(a) - MEM_BLOCKSIZE;#endif /* MP_ARRAY_SUPPORT && TARGET */#if MP_ARRAY_SUPPORT || TARGET == TARGET_UNIX    /* UNIX has a contiguous heap for a process, but we are not guaranteed to     * have full control over it, so we must assume that each separate memory     * allocation is independent.  If we are using sbrk() to allocate memory     * then we also try to ensure that all of our memory allocations are blocks     * of pages.     */#if MP_MMAP_SUPPORT    /* Decide if we are using mmap() or sbrk() to allocate the memory.  Requests     * for user memory will be allocated in the opposite way to internal memory.     */    if ((((i->flags & FLG_USEMMAP) != 0) == (u != 0)) && (i->mfile != -1))        u = 1;    else        u = 0;    if (u != 0)    {#if MP_MMAP_ANONYMOUS        if ((p = mmap(NULL, *l, PROT_READ | PROT_WRITE,              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == (void *) -1)#else /* MP_MMAP_ANONYMOUS */        if ((p = mmap(NULL, *l, PROT_READ | PROT_WRITE, MAP_PRIVATE, i->mfile,              0)) == (void *) -1)#endif /* MP_MMAP_ANONYMOUS */            p = NULL;    }    else#endif /* MP_MMAP_SUPPORT */    {        if (((t = getmemory(0)) == (void *) -1) ||            ((p = getmemory(*l)) == (void *) -1))            p = NULL;        else        {            if (p < t)                /* The heap has grown down, which is quite unusual except on                 * some weird systems where the stack grows up.                 */                n = (unsigned long) p - __mp_rounddown((unsigned long) p,                                                       i->page);            else            {                t = p;                n = __mp_roundup((unsigned long) p, i->page) -                    (unsigned long) p;            }            if (n > 0)                /* We need to allocate a little more memory in order to make the                 * allocation page-aligned.                 */                if ((p = getmemory(n)) == (void *) -1)                {                    /* We failed to allocate more memory, but we try to be nice                     * and return our original allocation back to the system.                     */                    getmemory(-*l);                    p = NULL;                }                else if (p >= t)                    p = (char *) t + n;        }    }#elif TARGET == TARGET_AMIGA    p = AllocMem(*l, MEMF_ANY | MEMF_CLEAR);#elif TARGET == TARGET_WINDOWS    /* The VirtualProtect() function won't allow us to protect a range of pages     * that span the allocation boundaries made by VirtualAlloc().  As mpatrol     * tries to merge all bordering free memory areas, we must prevent the     * pages allocated by different calls to VirtualAlloc() from being merged.     * The easiest way to do this is to reserve a page of virtual memory after     * each call to VirtualAlloc() since this won't actually take up any     * physical memory.  It's a bit of a hack, though!     */    p = VirtualAlloc(NULL, *l, MEM_COMMIT, PAGE_READWRITE);    VirtualAlloc(NULL, 0x10000, MEM_RESERVE, PAGE_NOACCESS);#elif TARGET == TARGET_NETWARE    p = NXPageAlloc(*l / i->page, 0);#endif /* MP_ARRAY_SUPPORT && TARGET */#if MP_ARRAY_SUPPORT || TARGET == TARGET_UNIX || TARGET == TARGET_NETWARE    /* UNIX's sbrk() and Netware's NXPageAlloc() do not zero the allocated     * memory, so we do this here for predictable behaviour.  This is also the     * case if we are using a simulated heap.     */#if MP_MMAP_SUPPORT    if ((p != NULL) && (u == 0))#else /* MP_MMAP_SUPPORT */    if (p != NULL)#endif /* MP_MMAP_SUPPORT */        __mp_memset(p, 0, *l);#endif /* MP_ARRAY_SUPPORT && TARGET */    if (p == NULL)        errno = ENOMEM;    return p;}/* Return a block of allocated memory back to the system. */MP_GLOBALvoid__mp_memfree(meminfo *i, void *p, size_t l){#if !MP_ARRAY_SUPPORT#if TARGET == TARGET_UNIX || TARGET == TARGET_WINDOWS || \    TARGET == TARGET_NETWARE    void *t;#endif /* TARGET */#endif /* MP_ARRAY_SUPPORT */    /* This function is hardly ever called except when the process is     * terminating as the heap manager will take care of reusing unused     * memory.  There is also no point in doing anything when we are using     * a simulated heap as it will automatically be returned to the system.     */#if !MP_ARRAY_SUPPORT    if (l == 0)        return;#if TARGET == TARGET_UNIX || TARGET == TARGET_WINDOWS || \    TARGET == TARGET_NETWARE    t = (void *) __mp_rounddown((unsigned long) p, i->page);#endif /* TARGET */#if TARGET == TARGET_UNIX    /* If we used sbrk() to allocate this memory then we can't shrink the     * break point since someone else might have allocated memory in between     * our allocations.  The next best thing is to unmap our freed allocations     * so that they no longer need to be handled by the virtual memory system.     * If we used mmap() to allocate this memory then we don't need to worry     * about the above problem.     */    l = __mp_roundup(l + ((char *) p - (char *) t), i->page);    mprotect(t, l, PROT_NONE);    munmap(t, l);#elif TARGET == TARGET_AMIGA    FreeMem(p, l);#elif TARGET == TARGET_WINDOWS    VirtualFree(t, 0, MEM_RELEASE);#elif TARGET == TARGET_NETWARE    NXPageFree(t);#endif /* TARGET */#endif /* MP_ARRAY_SUPPORT */}#if TARGET == TARGET_UNIX/* Handles any signals that result from illegal memory accesses whilst * querying the permissions of addresses. */staticvoidmemoryhandler(int s){    longjmp(memorystate, 1);}#endif /* TARGET *//* Return the access permission of an address. */MP_GLOBALmemaccess__mp_memquery(meminfo *i, void *p){#if TARGET == TARGET_UNIX#if MP_SIGINFO_SUPPORT    struct sigaction s;#endif /* MP_SIGINFO_SUPPORT */    char c;#elif TARGET == TARGET_WINDOWS    MEMORY_BASIC_INFORMATION m;#endif /* TARGET */    memaccess r;    r = MA_READWRITE;#if TARGET == TARGET_UNIX#if MP_MINCORE_SUPPORT    /* The mincore() system call allows us to determine if a page is in core,     * and if it is not and ENOMEM is set then it means that the page is not     * mapped.  Unfortunately, we can't tell if it's read-only.     */    if ((mincore((char *) __mp_rounddown((unsigned long) p, i->page), 1, &c) ==         -1) && (errno == ENOMEM))        return MA_NOACCESS;#endif /* MP_MINCORE_SUPPORT */    /* One generic way to determine the access permission of an address across     * all UNIX systems is to attempt to read from and write to the address and     * check the results using signals.     */#if MP_SIGINFO_SUPPORT    s.sa_flags = 0;    (void *) s.sa_handler = (void *) memoryhandler;    sigfillset(&s.sa_mask);    sigaction(SIGBUS, &s, &membushandler);    sigaction(SIGSEGV, &s, &memsegvhandler);#else /* MP_SIGINFO_SUPPORT */    membushandler = signal(SIGBUS, memoryhandler);    memsegvhandler = signal(SIGSEGV, memoryhandler);#endif /* MP_SIGINFO_SUPPORT */    if (setjmp(memorystate))        r = MA_NOACCESS;    else    {        c = *((char *) p);        if (setjmp(memorystate))            r = MA_READONLY;        else            *((char *) p) = c;    }#if MP_SIGINFO_SUPPORT    sigaction(SIGBUS, &membushandler, NULL);    sigaction(SIGSEGV, &memsegvhandler, NULL);#else /* MP_SIGINFO_SUPPORT */    signal(SIGBUS, membushandler);    signal(SIGSEGV, memsegvhandler);#endif /* MP_SIGINFO_SUPPORT */#elif TARGET == TARGET_WINDOWS    /* On Windows, the VirtualQuery() function allows us to determine the     * access permission of the page the address belongs to.     */    if (VirtualQuery(p, &m, sizeof(m)) >= sizeof(m))        if (!(m.State & MEM_COMMIT) || (m.Protect & PAGE_NOACCESS) ||            (m.Protect & PAGE_EXECUTE))            r = MA_NOACCESS;        else if ((m.Protect & PAGE_READONLY) || (m.Protect & PAGE_EXECUTE_READ))            r = MA_READONLY;#endif /* TARGET */    return r;}/* Protect a block of allocated memory with the supplied access permission. */MP_GLOBALint__mp_memprotect(meminfo *i, void *p, size_t l, memaccess a){#if TARGET == TARGET_UNIX || TARGET == TARGET_WINDOWS    void *t;    int n;#endif /* TARGET */#if TARGET == TARGET_UNIX || TARGET == TARGET_WINDOWS    if (l == 0)        return 1;    t = (void *) __mp_rounddown((unsigned long) p, i->page);

⌨️ 快捷键说明

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