pspmem.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 376 行
C
376 行
/*************************************************************************** * * * db.linux * * open source platform support package for Linux (tm) * * * * Copyright (c) 2000 Centura Software Corporation. All rights reseved. * * * * Use of this software, whether in source code format, or in executable, * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this * * distribution of source code files. * * * **************************************************************************//* pspmem.c - Contains the standard memory routines of the PSP */#include "psp.h"#include "pspint.h"#define TAG_USED 1#define TAG_ERRJMP 2typedef struct _HDR { struct _HDR *prev; /* prev block on this tag */ struct _HDR *next; /* next block on this tag */} HDR;typedef struct _TAG_ENTRY { struct _TAG_ENTRY *t_next; /* next tag in tag list */ struct _TAG_ENTRY *t_prev; /* prev tag in tag list */ PSP_SEM t_sem; /* semaphore for tag */ HDR *t_first; /* head of memory block list */ jmp_buf t_jmpbuf; /* jump buffer for out of memory error */ short t_state; /* tag state */} TAG_ENTRY;static PSP_SEM tagTabSem = NO_PSP_SEM;static TAG_ENTRY *tag0 = NULL;static TAG_ENTRY *tagN = NULL;/* ========================================================================== Initialize memory handling*/int psp_memInit( void){ tag0 = tagN = (TAG_ENTRY *) calloc(1, sizeof(TAG_ENTRY)); if (tag0 == NULL) { /* TBD: Log out of memory error */ vtprintf(DB_TEXT("Out of memory initializing PSP memory module\n")); return PSP_FAILED; } tag0->t_state = TAG_USED; tag0->t_sem = NO_PSP_SEM; if ((tag0->t_sem = psp_syncCreate(PSP_MUTEX_SEM)) == NO_PSP_SEM) { free(tag0); tag0 = tagN = NULL; return PSP_FAILED; } if ((tagTabSem = psp_syncCreate(PSP_MUTEX_SEM)) == NO_PSP_SEM) { psp_syncDelete(tag0->t_sem); free(tag0); tag0 = tagN = NULL; return PSP_FAILED; } return PSP_OKAY;}/* ========================================================================== Terminate memory handling*/void psp_memTerm( void){ while (tag0) psp_freeTagMemory(tag0, 1); /* Do not delete the tagTabSem or tag0->t_sem semaphores because they will have been deleted by psp_syncShutdown */}/* ========================================================================== Create a new tag*/PSP_MEMTAG psp_createTag( jmp_buf jb, short flags){ register TAG_ENTRY *tt; if (!psp_inited) return NULL_MEMTAG; if ((tt = (TAG_ENTRY *) calloc(1, sizeof(TAG_ENTRY))) == NULL) { /* log out of memory error */ return NULL_MEMTAG; } psp_syncEnterExcl(tagTabSem); tt->t_prev = tagN; tagN->t_next = tt; tagN = tt; psp_syncExitExcl(tagTabSem); if (jb != NULL) { memcpy(tt->t_jmpbuf, jb, sizeof(jmp_buf)); tt->t_state = TAG_ERRJMP; } else tt->t_state = TAG_USED; if (flags & PSP_TAG_USESEM) { tt->t_sem = psp_syncCreate(PSP_MUTEX_SEM); psp_syncStart(tt->t_sem); } else tt->t_sem = NO_PSP_SEM; return tt;}/* ========================================================================== Free all allocated memory on a tag*/void psp_freeTagMemory( PSP_MEMTAG tag, short freetag){ PSP_SEM sem; HDR *curr; HDR *prev; TAG_ENTRY *tt = tag; if (!psp_inited) return; if (tt->t_sem != NO_PSP_SEM && !psp_terminating) psp_syncEnterExcl(tt->t_sem); /* free all blocks allocated on this tag */ for (curr = tt->t_first; curr; ) { prev = curr; curr = curr->next; free(prev); } tt->t_first = NULL; if (freetag) { if (tt->t_prev) tt->t_prev->t_next = tt->t_next; else tag0 = tt->t_next; if (tt->t_next) tt->t_next->t_prev = tt->t_prev; else tagN = tt->t_prev; sem = tt->t_sem; free(tt); if (sem != NO_PSP_SEM && !psp_terminating) { psp_syncExitExcl(sem); psp_syncDelete(sem); } } else if (tt->t_sem != NO_PSP_SEM && !psp_terminating) psp_syncExitExcl(tt->t_sem);}/* ========================================================================== Reset the jump buffer on a tag*/void psp_resetTag( jmp_buf jb, PSP_MEMTAG tag){ register TAG_ENTRY *tt; if (!psp_inited) return; tt = tag ? tag : tag0; if (tt->t_sem != NO_PSP_SEM) psp_syncEnterExcl(tt->t_sem); if (jb) { memcpy(tt->t_jmpbuf, jb, sizeof(jmp_buf)); tt->t_state = TAG_ERRJMP; } else tt->t_state = TAG_USED; if (tt->t_sem != NO_PSP_SEM) psp_syncExitExcl(tt->t_sem);}/* ========================================================================== Allocate a block of memory*/void *psp_getMem( size_t size, PSP_MEMTAG tag, int mode, const DB_TCHAR *data, long locid){ HDR *pHdr; TAG_ENTRY *tt; if (!psp_inited || (!size && mode != MEM_STRDUP)) return NULL; tt = tag ? tag : tag0; if (tt->t_sem != NO_PSP_SEM) psp_syncEnterExcl(tt->t_sem); switch (mode) { case MEM_ALLOC: pHdr = malloc(size + sizeof(HDR)); break; case MEM_CALLOC: pHdr = calloc(1, size + sizeof(HDR)); break; case MEM_STRDUP: size = sizeof(DB_TCHAR) * (vtstrlen(data) + 1); /* fall through */ case MEM_MEMDUP: if ((pHdr = malloc(size + sizeof(HDR))) != NULL) memcpy((char *) pHdr + sizeof(HDR), data, size); break; default: return NULL; } if (!pHdr) { if (tt->t_sem != NO_PSP_SEM) psp_syncExitExcl(tt->t_sem); /* TBD: Log out of memory error using locid for location info */ vtprintf(DB_TEXT("Out of memory\n")); if (tt->t_state == TAG_ERRJMP) longjmp(tt->t_jmpbuf, 1); return NULL; } pHdr->prev = NULL; pHdr->next = tt->t_first; if (pHdr->next) pHdr->next->prev = pHdr; tt->t_first = pHdr; if (tt->t_sem != NO_PSP_SEM) psp_syncExitExcl(tt->t_sem); return pHdr + 1;}/* ========================================================================== Reallocate a block of memory*/void *psp_extendMem( const void *ptr, size_t newsize, PSP_MEMTAG tag, int clear, size_t incsize, long locid){ HDR *pHdr; HDR *prev; HDR *next; HDR *new; TAG_ENTRY *tt; if (!psp_inited) return NULL; if (!ptr) return psp_getMem(newsize, tag, clear ? MEM_CALLOC : MEM_ALLOC, NULL, locid); tt = tag ? tag : tag0; if (tt->t_sem != NO_PSP_SEM) psp_syncEnterExcl(tt->t_sem); pHdr = (HDR *) ptr - 1; prev = pHdr->prev; next = pHdr->next; if ((new = realloc(pHdr, newsize + sizeof(HDR))) == NULL) { if (tt->t_sem != NO_PSP_SEM) psp_syncExitExcl(tt->t_sem); /* TBD: Log out memory error using locid for location information. */ vtprintf(DB_TEXT("Out of memory\n")); if (tt->t_state == TAG_ERRJMP) longjmp(tt->t_jmpbuf, 1); return NULL; } if (new != pHdr) { if (prev) prev->next = new; else tt->t_first = new; if (next) next->prev = new; } if (tt->t_sem != NO_PSP_SEM) psp_syncExitExcl(tt->t_sem); if (clear) memset((char *) (new + 1) + newsize - incsize, 0, incsize); return new + 1;}/* ========================================================================== Free a block of memory*/void psp_freeMemory( const void *ptr, PSP_MEMTAG tag){ HDR *pHdr; TAG_ENTRY *tt; if (!psp_inited) return; tt = tag ? tag : tag0; if (tt->t_sem != NO_PSP_SEM && !psp_terminating) psp_syncEnterExcl(tt->t_sem); pHdr = (HDR *) ptr - 1; if (!pHdr->next && !pHdr->prev && tt->t_first != pHdr) { /* TBD: Log out memory error using locid for location information. */ vtprintf(DB_TEXT("Attempting to free previously freed memory\n")); return; } if (pHdr->prev) pHdr->prev->next = pHdr->next; else tt->t_first = pHdr->next; if (pHdr->next) pHdr->next->prev = pHdr->prev; pHdr->next = pHdr->prev = NULL; free(pHdr); if (tt->t_sem != NO_PSP_SEM && !psp_terminating) psp_syncExitExcl(tt->t_sem);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?