📄 osapi_linux.cpp
字号:
tmpPool->memPage[i].lAttached = tmpPool->ulNumPages - i;
pvTmpAddr = (BYTE *)pvTmpAddr + ulPageSize;
}
return ( (OS_MEMPOOL_ID)tmpPool);
}
/**
* Deletes a memory pool created by OS_CreateMemPool. This does not release the memory
* buffer used by the pool. This memory should be released by the application.
*
* @param pool - The memory pool ID
*
* @retval OS_OK if successful, an osapi error code otherwise.
*/
OS_STATUS OS_DeleteMemPool(OS_MEMPOOL_ID pool)
{
OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool; /* Pointer to memory pool */
/*
* If memory pool ID is NULL, then return.
*/
if (pool == NULL)
{
return (OS_INVALID_MEMPOOL);
}
/*
* Free any memory used by memory pool.
*/
OS_MemFree(tmpPool->memPage);
OS_MemFree(pool);
return (OS_OK);
}
/**
* Allocates a block of memory from the specified memory pool.
*
* @param pool - The memory pool ID
* @param ulSize - Size of memory block to allocate.
*
* @retval - pointer to allocated memory if successful, NULL if not successful
*/
PVOID OS_MemPoolAlloc(OS_MEMPOOL_ID pool, ULONG ulSize)
{
LONG lPgNeeded; /* Number of pages needed to allocate the *
* requested block of memory. */
OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool; /* Pointer to memory pool */
ULONG i; /* Loop iterator */
/*
* If invalid memory pool, return.
*/
if (pool == NULL)
{
return NULL;
}
/*
* Determine how many pages are needed for the requested amount
* of memory.
*/
lPgNeeded = (ulSize / tmpPool->ulPgSize);
if (ulSize % tmpPool->ulPgSize != 0)
{
++lPgNeeded;
}
/* Search for a block of pages that have at least the number
* of pages needed consecutively. Once a block is found, return
* the address of the first page of this block. If no blocks large
* enough are found, then return NULL.
*/
i = 0;
while (i < tmpPool->ulNumPages)
{
/*
* Look at the number of pages attached to the current page to
* determine if the block of pages is large enough to use. If
* the number of pages attached is a negative value, then move ahead
* that number of pages (positive value) because those pages are allocated.
* If the number of pages attached is less than the number of pages
* needed, then move ahead that number of pages because the block of
* pages is not large enough. Otherwise, the block is large enough,
* so allocate a block starting at current page.
*/
if (tmpPool->memPage[i].lAttached < 0)
{
i = i + (-1 * tmpPool->memPage[i].lAttached);
}
else if (tmpPool->memPage[i].lAttached < lPgNeeded)
{
i = i + tmpPool->memPage[i].lAttached;
}
else
{
/*
* Adjust the number of pages attached to the allocated pages.
* Simply change number to negative.
*/
LONG lPages = lPgNeeded;
for (ULONG j = i; j < (i + lPgNeeded); j++)
{
tmpPool->memPage[j].lAttached = -1 * lPages;
lPages = lPages - 1;
}
return (tmpPool->memPage[i].pvPgAddr);
}
}
return (NULL);
}
/**
* Frees the given memory block back to the specified memory pool
*
* @param pool - The memory pool ID
* @param pvMemory - The address
*
* @retval - OS_OK if sucessful, an osapi error code otherwise.
*/
OS_STATUS OS_MemPoolFree(OS_MEMPOOL_ID pool, PVOID pvMemory)
{
LONG lIndex, /* Page number in memory pool */
lNextIndex; /* Page number of next block */
OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool; /* Pointer to memory pool */
ULONG ulFront, /* Beginning and end address of */
ulEnd; /* memory pool. */
/*
* If null pointer was passed, return.
*/
if (pvMemory == NULL)
{
return (OS_NULL_POINTER);
}
/*
* Check that memory is in the specified memory pool. If it's not
* then do not free the memory.
*/
ulFront = (ULONG)tmpPool->memPage[0].pvPgAddr;
ulEnd = (ULONG)tmpPool->memPage[tmpPool->ulNumPages - 1].pvPgAddr +
tmpPool->ulPgSize;
if ( ( (ULONG)pvMemory < ulFront) || ( (ULONG)pvMemory >= ulEnd) ||
(pool == NULL) )
{
return (OS_INVALID_MEMPOOL);
}
/*
* Determine, from the address, which page(s) to free. If address
* is not a page address, then return.
*/
lIndex = (BYTE *)pvMemory - (BYTE *)tmpPool->memPage[0].pvPgAddr;
if (lIndex % tmpPool->ulPgSize != 0)
{
return (OS_FAILURE);
}
lIndex = lIndex / tmpPool->ulPgSize;
/*
* Make sure that the memory address given is not already free.
*/
if (tmpPool->memPage[lIndex].lAttached >= 0)
{
return (OS_FAILURE);
}
/*
* Adjust the number of pages attached to the freed page(s).
*/
lNextIndex = lIndex + (-1 * tmpPool->memPage[lIndex].lAttached);
LONG i;
if (tmpPool->memPage[lNextIndex].lAttached > 0)
{
/*
* Need to add the number of pages attached to the pages
* following the freed pages.
*/
for (i = lIndex; i < lNextIndex; i++)
{
tmpPool->memPage[i].lAttached =
(-1 * tmpPool->memPage[i].lAttached) +
tmpPool->memPage[lNextIndex].lAttached;
}
}
else
{
/*
* No non-allocated pages following the freed pages.
*/
for (i = lIndex; i < lNextIndex; i++)
{
tmpPool->memPage[i].lAttached =
(-1 * tmpPool->memPage[i].lAttached);
}
}
/*
* Adjust the number of pages attached to any pages preceding the
* freed pages.
*/
i = lIndex - 1;
while ( (tmpPool->memPage[i].lAttached >= 0) && (i >= 0) )
{
tmpPool->memPage[i].lAttached += tmpPool->memPage[lIndex].lAttached;
i = i - 1;
}
return (OS_OK);
}
/**
* Frees all memory blocks back to the specified memory pool
*
* @param pool - The memory pool ID
*
* @retval - OS_OK if sucessful, an osapi error code otherwise.
*/
OS_STATUS OS_MemPoolReset(OS_MEMPOOL_ID pool)
{
OS_MEMPOOL *pMemPool = (OS_MEMPOOL *)pool;
if (pool == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MemPoolReset: NULL pointer!\n"));
return (OS_NULL_POINTER);
}
/* Free all pages of mempool */
for (ULONG i = 0; i < pMemPool->ulNumPages; i++)
{
pMemPool->memPage[i].lAttached = pMemPool->ulNumPages - i;
}
return (OS_OK);
}
/**
* Allocates a block of memory from the OS memory pool.
*
* @param ulSize - memory size.
*
* @retval
* pvMemory - pointer to allocated memory, if successful
* NULL - if not successful
*/
#ifndef DMALLOC
PVOID OS_MemAlloc(ULONG ulSize)
{
PVOID pvMemory = NULL;
#ifdef __CALC_PEAK_ALLOCATION
if (fFirstAlloc == TRUE)
{
memset(test, 0, sizeof(mem_info) * 512);
fFirstAlloc = FALSE;
}
#endif
/*
* Check the validity of the given memory size
*/
if (ulSize == 0)
{
DbgPrint(("OS_MemAlloc: Memory size is 0!\n"));
return (NULL);
}
/*
* Allocate a block of the given size from the OS memory
*/
pvMemory = malloc(ulSize);
#ifdef __CALC_PEAK_ALLOCATION
if (pvMemory != NULL)
{
for (int i=0; i<512; i++)
{
if (test[i].pvAddr == NULL)
{
test[i].pvAddr = pvMemory;
test[i].size = ulSize;
break;
}
}
ulCurrentAllocations += ulSize;
if (ulPeakAllocations < ulCurrentAllocations)
{
ulPeakAllocations = ulCurrentAllocations;
}
}
#endif
DbgAssert(pvMemory != NULL);
/*
* Return a pointer to the allocated block
*/
return (pvMemory);
}
/**
* Frees the given memory block back to the OS memory pool.
*
* @param pvMemory - pointer to the memory to be freed
*
* @retval OS_OK if successful, otherwise an osapi error code
*/
OS_STATUS OS_MemFree(PVOID pvMemory)
{
/*
* Check the validity of the given memory pointer
*/
if (pvMemory == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MemFree: Memory pointer is NULL!\n"));
return (OS_NULL_POINTER);
}
#ifdef __CALC_PEAK_ALLOCATION
for (int i=0; i<512; i++)
{
if (test[i].pvAddr == pvMemory)
{
ulCurrentAllocations -= test[i].size;
test[i].pvAddr = NULL;
test[i].size = 0;
break;
}
}
#endif
/*
* Make sure the OS memory pool has been created
*/
/*
* Free the given block back to the OS memory
*/
free(pvMemory);
return (OS_OK);
}
#endif
/**
* OS Initialize DRAM Top function.
*
* @param
* None.
*
* @retval
* OS_MEMORY_BASE - offset to the top of DRAM, if successful
* NULL - if not successful
*/
OS_STATUS OS_InitDramTop(PVOID pStartAddr, ULONG ulMemSize)
{
return (OS_NOT_IMPLEMENTED);
}
/******************************************************************************
*******************************************************************************
** **
** Timer function prototypes **
** **
*******************************************************************************
******************************************************************************/
#ifdef VC_TIMERS
typedef struct tagThreadTimer
{
int iThreadID; /* the ID of the thread in charge of this timer */
timer_t timerid; /* the slot value and unique timer id */
struct sigevent evp; /* description of event, only callback type supported */
char strThreadName[17]; /* name of thread, this shall be VCTimerThreadXXX */
struct itimerspec itimer; /* this contains the timeout or repeat value */
OS_SEM_ID semTimerSet; /* used to block for timeout specified */
BOOLEAN fTimerSetPending; /* set when timer set is pending / cleared once timer starts counting */
BOOLEAN fTimerCounting; /* set while timer is counting */
BOOLEAN fTimerExitPending; /* set when timer exit is pending */
struct timespec abstime;
} ThreadTimer;
#define TOTAL_TIMERS 200
#define VC_TIMER_THREAD_STACK_SIZE 1024
/* @todo Track the timer list with a dynamic clist */
ThreadTimer *pttMasterList[TOTAL_TIMERS] = { NULL };
/**
* VCI Pthread-based, Posix-style Timer
*
* @param
* clockid_t clock_id
*
* @param
* struct sigevent *evp
*
* @param
* timer_t *timerid
* @retval
* 0 if successful
* -1 if not successful
*/
int vc_timer_create( clockid_t clockid, struct sigevent *evp, timer_t *timerid )
{
int iReturn = 0;
int i = 0;
char *strThreadName = "VCTimerThread";
ThreadTimer *pttThreadTimer = NULL;
BOOLEAN fFoundOpen = FALSE;
/* we only handle REALTIME at this time */
if( CLOCK_REALTIME != clockid )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s - clockid problem %08X\n", __FUNCTION__, clockid) );
iReturn = -1;
goto leave;
}
/* we only treat call-back signals */
if( NULL == evp )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s - NULL POINTER\n", __FUNCTION__) );
iReturn = -1;
goto leave;
}
/* malloc a structure to store all of the timer info including the threadid, timerid, and all of the private params */
if( NULL == ( pttThreadTimer = (ThreadTimer*)OS_MemAlloc(sizeof(ThreadTimer)) ) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s - OUT OF MEMORY\n", __FUNCTION__) );
iReturn = -1;
goto leave;
}
/* @todo - add new pThreadTimer to a list of some sort(possibly a clist) */
/* find a free slot in the global timer storage */
for (i = 0; i < TOTAL_TIMERS; i++)
{
if (pttMasterList[i] == NULL)
{
pttMasterList[i] = pttThreadTimer;
fFoundOpen = TRUE;
break;
}
}
if( FALSE == fFoundOpen )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s - can't find an open timer slot\n", __FUNCTION__) );
iReturn = -1;
goto leave;
}
/* Intially timer is waiting for a timer to be set and not counting */
pttThreadTimer->fTimerExitPending = FALSE;
pttThreadTimer->fTimerSetPending = FALSE;
pttThreadTimer->fTimerCounting = FALSE;
/* This is a semaphore that allows the thread to wait for the time that timer is set to */
pttThreadTimer->semTimerSet = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
/* The evp contains the function that gets called from the ti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -