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

📄 rvmem.c

📁 h.248协议源码
💻 C
字号:
#if (0)
************************************************************************
Filename:
Description:
************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
************************************************************************
************************************************************************
$Revision:$
$Date:$
$Author: S. Cipolli$
************************************************************************
#endif

#include "rvplatform.h"
#include "rvtypes.h"
#include "rvmem.h"

#if defined(RV_MEM_ANSI)
#include <stdlib.h>
#	if defined(RV_MEMTRACE_ON)
#include <stdio.h>
#include "rvmutex.h"

static int rvMemTraceCnt = 0;
static int rvMemTraceMax = 0;
static RvMutex rvMemTraceMutex;
static FILE * rvMemTraceLog = NULL;
static char rvMemTraceChkpName[50];
static int	rvMemTraceChkpStart;

typedef struct RvMemTraceRecord_ {
	int size;
	struct RvMemTraceRecord_ * last;
	struct RvMemTraceRecord_ * next;
} RvMemTraceRecord;

static RvMemTraceRecord   rvMemTraceFirst = {0,NULL,NULL};
static RvMemTraceRecord * rvMemTraceHead = &rvMemTraceFirst;
static RvMemTraceRecord * rvMemTraceTail = &rvMemTraceFirst;

void rvMemTraceConstruct(void) {
	rvMutexConstruct(&rvMemTraceMutex);
	rvMemTraceLog = fopen("rvmem.log","w+");
}

void rvMemTraceCheckpoint(const char * chkpname) {
	if(rvMemTraceLog!=NULL)
		fprintf(rvMemTraceLog,"%-26s %-10u\n",chkpname,rvMemTraceCnt);
}

void rvMemTraceStart(const char * chkpname) {
	rvMutexLock(&rvMemTraceMutex);
	strcpy(rvMemTraceChkpName,chkpname);
	rvMemTraceChkpStart = rvMemTraceCnt;
	if(rvMemTraceLog!=NULL)
		fprintf(rvMemTraceLog,"Start %-20s %-10u\n",chkpname,rvMemTraceCnt);
	rvMutexUnlock(&rvMemTraceMutex);
}

void rvMemTraceStop(const char * chkpname) {
	rvMutexLock(&rvMemTraceMutex);
	if(rvMemTraceLog!=NULL) {
		if(!strcmp(chkpname,rvMemTraceChkpName) )
			fprintf(rvMemTraceLog,"Stop  %-20s %-10u diff: %-10d max:%-10u\n",rvMemTraceChkpName,
				rvMemTraceCnt,rvMemTraceCnt-rvMemTraceChkpStart,rvMemTraceMax);
		else
			fprintf(rvMemTraceLog,"Stop  %-20s %-10u max:%-10u\n",chkpname,rvMemTraceCnt,rvMemTraceMax);
	}
	rvMutexUnlock(&rvMemTraceMutex);
}

void rvMemTraceDestruct(void) {
	FILE * fp;
	RvMemTraceRecord * cur = rvMemTraceHead->next;

	rvMutexDestruct(&rvMemTraceMutex);
	fprintf(rvMemTraceLog,"\nUnreleased memory: %u, Maximal memory used: %u\n",rvMemTraceCnt,rvMemTraceMax);
	fclose(rvMemTraceLog);

	/* Dump unreleased blocks */
	if(rvMemTraceCnt) {
		fp = fopen("rvmem_alloc.log","w+");
		if(fp) {
			fprintf(fp,"Unreleased blocks\n");
			while(cur!=NULL) {
				fprintf(fp,"Unreleased: address=%p, size=%u\n",
					(char *)cur+sizeof(RvMemTraceRecord),cur->size);
				cur=cur->next;
			}
		}
		fclose(fp);
	}
}

void rvMemTraceSetRecord(size_t n,void * p) {
	RvMemTraceRecord * record = (RvMemTraceRecord*)p; 
	record->size = n;
	record->next = NULL;
	record->last = rvMemTraceTail;
	rvMemTraceTail->next = record;
	rvMemTraceTail = record;
}

void* rvMemAlloc_(size_t n) { 
	size_t n_ = n+sizeof(RvMemTraceRecord);
	char * p  = malloc(n_);
	char * buf;

	rvMutexLock(&rvMemTraceMutex);
	rvMemTraceCnt+=n;
	if(rvMemTraceCnt>rvMemTraceMax)
		rvMemTraceMax=rvMemTraceCnt;
	rvMemTraceSetRecord(n,p);

	rvMutexUnlock(&rvMemTraceMutex);
	buf = (char*)p+sizeof(RvMemTraceRecord);
	return buf;
}

void rvMemFree_(void* p) { 
	char * p_ = (char*)p-sizeof(RvMemTraceRecord);
	RvMemTraceRecord * record = (RvMemTraceRecord *)p_;
	rvMutexLock(&rvMemTraceMutex);

	rvMemTraceCnt-=record->size;
	/* Free record from linked list */
	record->last->next = record->next;
	if(record->next!=NULL) 
		record->next->last = record->last;
	else
		rvMemTraceTail = record->last;

	free(p_); 
	rvMutexUnlock(&rvMemTraceMutex);
}

RvBool rvMemInit_(void)
{
	return rvTrue;
}

void rvMemEnd_(void)
{
}

int rvMemTraceGetMemOut()
{
	return rvMemTraceCnt;
}

int rvMemTraceGetPeakMemUsage()
{
	return rvMemTraceMax;
}

#	else
#		define rvMemAlloc_(n)		(malloc(n))
#		define rvMemFree_(p)		(free(p))

RvBool rvMemInit_(void)
{
	return rvTrue;
}

void rvMemEnd_(void)
{
}
#	endif
#elif defined(RV_MEM_OSE)
#include "ose.h"
#include "heapapi.h"

#define rvMemAlloc_(n)		(heap_alloc_shared((n), (__FILE__), (__LINE__)))
#define rvMemFree_(p)		(heap_free_shared(p))
RvBool rvMemInit_(void)
{
	return rvTrue;
}

void rvMemEnd_(void)
{
}
#elif defined(RV_MEM_NUCLEUS)
#include "nucleus.h"
extern NU_MEMORY_POOL System_Memory;

void *rvMemAlloc_(size_t n)
{
	int status;
	void *ptr;
	
	status = NU_Allocate_Memory(&System_Memory, &ptr, n, NU_NO_SUSPEND);
	if(status != NU_SUCCESS) return NULL;
	return ptr;
}

#define rvMemFree_(p)		(NU_Deallocate_Memory(p))

RvBool rvMemInit_(void)
{
	return rvTrue;
}

void rvMemEnd_(void)
{
}
#elif defined(RV_MEM_PSOS)
#include <psos.h>
#include "rvpool.h"
#include "rvalloc.h"

/* Which psos memory region to use */
#define PSOS_MEM_REGION 0

/* Smallest sub-allocation buffer pool to create. Must be a power */
/* of 2 >= 4 as per pSOS */
#define RVMEM_MINBUFSIZE 32

static RvPool *mempools;
static int numpools;
static unsigned long region_unit_size; /* pSOS forces size to power of 2 >= 16 */
static RvAlloc pSOSalloc;

static void *rvMempSOSrnAlloc(void *rnid, size_t size) {
	void *result;
	if(rn_getseg((unsigned long)rnid, size, RN_NOWAIT, 0, &result) != 0)
		return NULL;
	return result;
}

static void rvMempSOSrnFree(void *rnid, size_t size, void *ptr){
	rn_retseg((unsigned long)rnid, ptr);
}

void *rvMemAlloc_(size_t request_size)
{
	int pool;
	int *poolptr;
	unsigned long bufsize;
	size_t required_size;
	char *result;

	required_size = request_size + sizeof(pool);
	bufsize = RVMEM_MINBUFSIZE;
	for(pool = 0; pool < numpools; pool++) {
		if(required_size <= bufsize) {
			result = (char *)rvPoolAllocate(&mempools[pool]);
			if(result == NULL)
				return NULL;
			poolptr = (int *)result;
			*poolptr = pool; /* save pool number for memfree */
			result = result + sizeof(*poolptr);
			return (void *)result;
		}
		bufsize = bufsize * 2;
	}
	/* Go directly to pSOS memory manager */
	if(rn_getseg(PSOS_MEM_REGION, required_size, RN_NOWAIT, 0, &result) != 0)
		return NULL;
	poolptr = (int *)result;
	*poolptr = -1; /* store -1 as pool number to indicate direct allocation */
	result = result + sizeof(*poolptr);
	return (void *)result;
}

void *rvMemFree_(void *p)
{
	int *poolptr;
	char *result;

	if(p == NULL)
		return;
	result = (char *)p - sizeof(*poolptr);
	poolptr = (int *)result;
	if(*poolptr == -1) {
		/* memory allocated directly from pSOS */
		rn_retseg(PSOS_MEM_REGION, result);
		return;
	}
	rvPoolDeallocate(&mempools[*poolptr], result);
}

RvBool rvMemInit_(void)
{
	struct rninfo rbuf;
	unsigned long bufsize;
	int pool;

	mempools = NULL;
	numpools = 0;
	region_unit_size = 0;
	rvAllocConstruct(&pSOSalloc, PSOS_MEM_REGION, ~0U, rvMempSOSrnAlloc, rvMempSOSrnFree);
	
	if(rn_info(PSOS_MEM_REGION, &rbuf) != 0)
		return rvFalse;
	region_unit_size = rbuf.unit_size;

	/* figure out number of buffer pools to use */
	bufsize = region_unit_size;
	for(numpools = 0; bufsize > RVMEM_MINBUFSIZE; numpools++) {
		bufsize = bufsize / 2;
	}

	/* special case, we'll just send calls directly to pSOS */
	if(numpools == 0)
		return rvTrue;
	
	/* Initialize memory pools */
	if(rn_getseg(PSOS_MEM_REGION, numpools * sizeof(RvPool), RN_NOWAIT, 0, (void **)&mempools) != 0) {
		return rvFalse;
	}
	bufsize = RVMEM_MINBUFSIZE;
	for(pool = 0; pool < numpools; pool++) {
		rvPoolConstructEx1(&mempools[pool], bufsize, region_unit_size * 2, NULL, NULL, NULL, &pSOSalloc);
		bufsize = bufsize * 2;
	}
	return rvTrue;
}

void rvMemEnd_(void)
{
	int pool;

	if(numpools == 0)
		return;
	for(pool = 0; pool < numpools; pool++)
		rvPoolDestruct(&mempools[pool]);
	numpools = 0;
	rn_retseg(PSOS_MEM_REGION, mempools);
	mempools = NULL;
}
#endif

static RvMemHandler rvMemHandler = NULL;

/*$
{function:
	{name: rvMemAlloc}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Allocate memory from the "default" dynamic heap.  The "default" 
			dynamic heap is the standard C library functions malloc/free
			on most OS's.
		}

	}
	{proto: void* rvMemAlloc(size_t n);}
	{params:
		{param: {n: n} {d: The number of bytes to allocate.}}
	}
	{returns: 
		A pointer to a suitably sized and aligned block of memory or 
		NULL if memory exhaustion occurs.
	}
}
$*/
void* rvMemAlloc(size_t n) { 
	void* p;

	do {
		p = rvMemAlloc_(n);
	} while ((p == NULL) && (rvMemHandler) && (rvMemHandler(n)));

	return p;
}

void* rvMemCalloc(size_t num, size_t size) {
	void* p;
	size_t total;

	total = num * size;
	p = rvMemAlloc(total);
	if(p != NULL)
		memset(p, 0, total);
	return p;
}

/*$
{function:
	{name: rvMemFree}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Deallocate a block of memory pointed to by p.  The memory 
			must have been previously allocated with rvMemAlloc. 
		}
	}
	{proto: void rvMemFree(void* p);}
	{params:
		{param: {n: p} {d: A pointer to the memory block to deallocate.}}
	}
}
$*/
void rvMemFree(void* p) { 
	rvMemFree_(p); 
}

/*$
{function scope="protected":
	{name: rvMemInit}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Initializes memory allocation routines. Must be called
			before any allocations.
		}
	}
	{proto: RvBool rvMemInit(void);}
	{returns:
	        rvTrue if successfull, rvFalse if initialization failed.
	}
}
$*/
RvBool rvMemInit(void)
{
	return rvMemInit_();
}

/*$
{function scope="protected":
	{name: rvMemEnd}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Cleans up memory allocation routines. Must be called
			before system exits.
		}
	}
	{proto: void rvMemEnd(void);}
}
$*/
void rvMemEnd(void)
{
	rvMemEnd_();
}

/*$
{function:
	{name: rvMemGetHandler}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Get the "handler" for the dynamic heap.  The handler is a function 
			pointer, that is called when the heap is exhausted.  The handler
			can log the event, initiate a safe-shutdown, or take action to
			collect enough memory to satisfy the rvMemAlloc that caused the
			heap exhaustion.
		}
	}
	{proto: RvMemHandler rvMemGetHandler(void);}
	{returns:
		A pointer to the "handler" function or NULL if not set.
	}
    {see_also:
        {n: RvMemHandler}
    }
}
$*/
RvMemHandler rvMemGetHandler(void) {
	return rvMemHandler;
}

/*$
{function:
	{name: rvMemSetHandler}	
    {superpackage: Util}
	{include: rvmem.h}
	{description:
		{p: 
			Set the "handler" for the dynamic heap.  The handler is a function 
			pointer, that is called when the heap is exhausted.  The handler
			can log the event, initiate a safe-shutdown, or take action to
			collect enough memory to satisfy the rvMemAlloc that caused the
			heap exhaustion.
		}
	}
	{proto: RvMemHandler rvMemSetHandler(RvMemHandler h);}
	{params:
		{param: {n: h} {d: A pointer to the new "handler" function.}}
	}

	{returns:
		A pointer to the previous "handler" function or NULL if not set.
	}
    {see_also:
        {n: RvBool RvMemHandler(size_t n);}
    }
}
$*/
RvMemHandler rvMemSetHandler(RvMemHandler h) {
	RvMemHandler old = rvMemHandler;
	rvMemHandler = h;
	return old;
}

⌨️ 快捷键说明

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