📄 prmem.c
字号:
} } phony.s.requestedSize = bytes; mb = &phony; ours = 0; } else { size_t blockSize = mb->s.blockSize; MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); PR_ASSERT(mt->s.magic == ZONE_MAGIC); PR_ASSERT(mt->s.zone == mb->s.zone); PR_ASSERT(mt->s.blockSize == blockSize); if (bytes <= blockSize) { /* The block is already big enough. */ mt->s.requestedSize = mb->s.requestedSize = bytes; return oldptr; } ours = 1; } rv = pr_ZoneMalloc(bytes); if (rv) { if (oldptr && mb->s.requestedSize) memcpy(rv, oldptr, mb->s.requestedSize); if (ours) pr_ZoneFree(oldptr); else if (oldptr) free(oldptr); } return rv;}static voidpr_ZoneFree(void *ptr){ MemBlockHdr *mb, *mt; MemoryZone *mz; size_t blockSize; PRUint32 wasLocked; if (!ptr) return; mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb)); if (mb->s.magic != ZONE_MAGIC) { /* maybe this came from ordinary malloc */#ifdef DEBUG fprintf(stderr, "Warning: freeing memory block %p from ordinary malloc\n", ptr);#endif free(ptr); return; } blockSize = mb->s.blockSize; mz = mb->s.zone; mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize); PR_ASSERT(mt->s.magic == ZONE_MAGIC); PR_ASSERT(mt->s.zone == mz); PR_ASSERT(mt->s.blockSize == blockSize); if (!mz) { PR_ASSERT(blockSize > 65536); /* This block was not in any zone. Just free it. */ free(mb); return; } PR_ASSERT(mz->blockSize == blockSize); wasLocked = mz->locked; pthread_mutex_lock(&mz->lock); mz->locked = 1; if (wasLocked) mz->contention++; mt->s.next = mb->s.next = mz->head; /* put on head of list */ mz->head = mb; mz->elements++; mz->locked = 0; pthread_mutex_unlock(&mz->lock);}PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size){ if (!_pr_initialized) _PR_ImplicitInitialization(); return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size);}PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize){ if (!_pr_initialized) _PR_ImplicitInitialization(); return use_zone_allocator ? pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);}PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size){ if (!_pr_initialized) _PR_ImplicitInitialization(); return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size);}PR_IMPLEMENT(void) PR_Free(void *ptr){ if (use_zone_allocator) pr_ZoneFree(ptr); else free(ptr);}#else /* !defined(_PR_ZONE_ALLOCATOR) *//*** The PR_Malloc, PR_Calloc, PR_Realloc, and PR_Free functions simply** call their libc equivalents now. This may seem redundant, but it** ensures that we are calling into the same runtime library. On** Win32, it is possible to have multiple runtime libraries (e.g.,** objects compiled with /MD and /MDd) in the same process, and** they maintain separate heaps, which cannot be mixed.*/PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size){#if defined (WIN16) return PR_MD_malloc( (size_t) size);#else return malloc(size);#endif}PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize){#if defined (WIN16) return PR_MD_calloc( (size_t)nelem, (size_t)elsize ); #else return calloc(nelem, elsize);#endif}PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size){#if defined (WIN16) return PR_MD_realloc( ptr, (size_t) size);#else return realloc(ptr, size);#endif}PR_IMPLEMENT(void) PR_Free(void *ptr){#if defined (WIN16) PR_MD_free( ptr );#else free(ptr);#endif}#endif /* _PR_ZONE_ALLOCATOR *//*** Complexity alert!**** If malloc/calloc/free (etc.) were implemented to use pr lock's then** the entry points could block when called if some other thread had the** lock.**** Most of the time this isn't a problem. However, in the case that we** are using the thread safe malloc code after PR_Init but before** PR_AttachThread has been called (on a native thread that nspr has yet** to be told about) we could get royally screwed if the lock was busy** and we tried to context switch the thread away. In this scenario** PR_CURRENT_THREAD() == NULL**** To avoid this unfortunate case, we use the low level locking** facilities for malloc protection instead of the slightly higher level** locking. This makes malloc somewhat faster so maybe it's a good thing** anyway.*/#ifdef _PR_OVERRIDE_MALLOC/* Imports */extern void *_PR_UnlockedMalloc(size_t size);extern void *_PR_UnlockedMemalign(size_t alignment, size_t size);extern void _PR_UnlockedFree(void *ptr);extern void *_PR_UnlockedRealloc(void *ptr, size_t size);extern void *_PR_UnlockedCalloc(size_t n, size_t elsize);static PRBool _PR_malloc_initialised = PR_FALSE;#ifdef _PR_PTHREADSstatic pthread_mutex_t _PR_MD_malloc_crustylock;#define _PR_Lock_Malloc() { \ if(PR_TRUE == _PR_malloc_initialised) { \ PRStatus rv; \ rv = pthread_mutex_lock(&_PR_MD_malloc_crustylock); \ PR_ASSERT(0 == rv); \ }#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ PRStatus rv; \ rv = pthread_mutex_unlock(&_PR_MD_malloc_crustylock); \ PR_ASSERT(0 == rv); \ } \ }#else /* _PR_PTHREADS */static _MDLock _PR_MD_malloc_crustylock;#ifdef IRIX#define _PR_Lock_Malloc() { \ PRIntn _is; \ if(PR_TRUE == _PR_malloc_initialised) { \ if (_PR_MD_GET_ATTACHED_THREAD() && \ !_PR_IS_NATIVE_THREAD( \ _PR_MD_GET_ATTACHED_THREAD())) \ _PR_INTSOFF(_is); \ _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ }#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ if (_PR_MD_GET_ATTACHED_THREAD() && \ !_PR_IS_NATIVE_THREAD( \ _PR_MD_GET_ATTACHED_THREAD())) \ _PR_INTSON(_is); \ } \ }#else /* IRIX */#define _PR_Lock_Malloc() { \ PRIntn _is; \ if(PR_TRUE == _PR_malloc_initialised) { \ if (_PR_MD_CURRENT_THREAD() && \ !_PR_IS_NATIVE_THREAD( \ _PR_MD_CURRENT_THREAD())) \ _PR_INTSOFF(_is); \ _PR_MD_LOCK(&_PR_MD_malloc_crustylock); \ }#define _PR_Unlock_Malloc() if(PR_TRUE == _PR_malloc_initialised) { \ _PR_MD_UNLOCK(&_PR_MD_malloc_crustylock); \ if (_PR_MD_CURRENT_THREAD() && \ !_PR_IS_NATIVE_THREAD( \ _PR_MD_CURRENT_THREAD())) \ _PR_INTSON(_is); \ } \ }#endif /* IRIX */#endif /* _PR_PTHREADS */PR_IMPLEMENT(PRStatus) _PR_MallocInit(void){ PRStatus rv = PR_SUCCESS; if( PR_TRUE == _PR_malloc_initialised ) return PR_SUCCESS;#ifdef _PR_PTHREADS { int status; pthread_mutexattr_t mattr; status = _PT_PTHREAD_MUTEXATTR_INIT(&mattr); PR_ASSERT(0 == status); status = _PT_PTHREAD_MUTEX_INIT(_PR_MD_malloc_crustylock, mattr); PR_ASSERT(0 == status); status = _PT_PTHREAD_MUTEXATTR_DESTROY(&mattr); PR_ASSERT(0 == status); }#else /* _PR_PTHREADS */ _MD_NEW_LOCK(&_PR_MD_malloc_crustylock);#endif /* _PR_PTHREADS */ if( PR_SUCCESS == rv ) { _PR_malloc_initialised = PR_TRUE; } return rv;}void *malloc(size_t size){ void *p; _PR_Lock_Malloc(); p = _PR_UnlockedMalloc(size); _PR_Unlock_Malloc(); return p;}#if defined(IRIX)void *memalign(size_t alignment, size_t size){ void *p; _PR_Lock_Malloc(); p = _PR_UnlockedMemalign(alignment, size); _PR_Unlock_Malloc(); return p;}void *valloc(size_t size){ return(memalign(sysconf(_SC_PAGESIZE),size));}#endif /* IRIX */void free(void *ptr){ _PR_Lock_Malloc(); _PR_UnlockedFree(ptr); _PR_Unlock_Malloc();}void *realloc(void *ptr, size_t size){ void *p; _PR_Lock_Malloc(); p = _PR_UnlockedRealloc(ptr, size); _PR_Unlock_Malloc(); return p;}void *calloc(size_t n, size_t elsize){ void *p; _PR_Lock_Malloc(); p = _PR_UnlockedCalloc(n, elsize); _PR_Unlock_Malloc(); return p;}void cfree(void *p){ _PR_Lock_Malloc(); _PR_UnlockedFree(p); _PR_Unlock_Malloc();}void _PR_InitMem(void){ PRStatus rv; rv = _PR_MallocInit(); PR_ASSERT(PR_SUCCESS == rv);}#endif /* _PR_OVERRIDE_MALLOC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -