📄 osapi_linux.cpp
字号:
* @param
* int iInitialCount - initial reference count
*
* @param
* char *strName - semaphore name
*
* @retval
* OS_SEM_ID semId - semaphore identifier, if successful
* 0 - if not successful
*/
OS_SEM_ID OS_SemCCreateNamed(int iOSOptions, int iInitialCount, char *strName)
{
OS_SEM_ID semId = 0;
OS_SEMAPHORE *psemRecord;
/*
* Create a counting semaphore
*/
semId = OS_SemCCreate( iOSOptions, iInitialCount );
if (semId == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemNamedCCreate: Could not create named semaphore!\n"));
return 0;
}
/*
* Name the counting semaphore
*/
psemRecord = (OS_SEMAPHORE *)semId;
strncpy(psemRecord->strName, strName, MAX_NAME_SIZE);
psemRecord->strName[MAX_NAME_SIZE-1] = 0;
/*
* Return a handle to the counting semaphore
*/
return (OS_SEM_ID)psemRecord;
}
/**
* OS Semaphore Delete function.
*
* @param
* OS_SEM_ID semId - semaphore identifier
*
* @retval
* Returns OS_OK.
* This command is always successful.
*/
#if defined(NDEBUG)
OS_STATUS OS_SemDelete(OS_SEM_ID semId)
#else
OS_STATUS OS_SemDeleteDbg(OS_SEM_ID semId, char *srcFile, int srcLine)
#endif
{
/* Cast the given semaphore identifier to a semaphore record */
OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
if (semId == 0)
{
#if defined(NDEBUG)
DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
DbgPrint(("%s: BAD POINTER. Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
return (OS_FAILURE);
}
/* release all wait states */
OS_SemFlush(semId);
/* Destroy the semaphore */
if (pthread_cond_destroy(&psemRecord->condWait) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemDelete: Could not init condWait"));
}
if (pthread_mutex_destroy(&psemRecord->mutex) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemDelete: Could not init mutex"));
}
/* Delete the semaphore record */
OS_MemFree(psemRecord);
/* Return success */
return (OS_OK);
}
/**
* OS Semaphore Take function. Basically decrements the semaphore count, if
* possible.
*
* @param
* OS_SEM_ID semId - semaphore identifier
*
* @param
* int iTimeout - semaphore take timeout value
*
* @retval
* OS_OK if successful
* OS_TIMEOUT if timout
* OS_FAILURE if not successful
*/
#if defined(NDEBUG)
OS_STATUS OS_SemTake(OS_SEM_ID semId, int iTimeout)
#else
OS_STATUS OS_SemTakeDbg(OS_SEM_ID semId, int iTimeout, char *srcFile, int srcLine)
#endif
{
int iRet = OS_OK;
OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
struct timeval tv;
struct timespec abstime;
/* Check the validity of the semaphore */
if (semId == 0)
{
#if defined(NDEBUG)
DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
DbgPrint(("%s: BAD POINTER. Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
goto error_handler;
}
/* Check the validity of the given timeout value */
if (iTimeout < OS_WAIT_FOREVER)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Invalid timeout value (%d)!\n", __FUNCTION__, iTimeout));
goto error_handler;
}
if (pthread_mutex_lock(&psemRecord->mutex) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
goto error_handler;
}
if ( (OS_WAIT_FOREVER != iTimeout) && (OS_NO_WAIT != iTimeout) )
{
/* get the current time */
if (gettimeofday(&tv, NULL) != 0)
{
DbgPrint(("%s: gettimeofday Failed!\n",__FUNCTION__));
pthread_mutex_unlock(&psemRecord->mutex);
iRet = OS_FAILURE;
goto error_handler;
}
/* set our timeout */
abstime.tv_sec = tv.tv_sec + iTimeout/CLOCKS_PER_SEC;
abstime.tv_nsec = ( tv.tv_usec + (iTimeout%CLOCKS_PER_SEC) ) * 1000;
while ( abstime.tv_nsec > 1000000000 )
{
abstime.tv_sec += 1;
abstime.tv_nsec -= 1000000000;
}
}
while (psemRecord->ulCount == 0)
{
if (OS_WAIT_FOREVER == iTimeout)
{
iRet = pthread_cond_wait(&psemRecord->condWait, &psemRecord->mutex);
if (iRet != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemTake: pthread_cond_wait ERROR = %s!\n", strerror(errno)));
iRet = OS_FAILURE;
break;
}
}
else if (OS_NO_WAIT == iTimeout)
{
iRet = OS_TIMEOUT;
break;
}
else
{
iRet = pthread_cond_timedwait(&psemRecord->condWait, &psemRecord->mutex, &abstime);
if (iRet != 0)
{
if (iRet == ETIMEDOUT)
{
iRet = OS_TIMEOUT;
break;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemTake: pthread_cond_timedwait ERROR = %s!\n", strerror(errno)));
iRet = OS_FAILURE;
break;
}
}
}
}
if (psemRecord->ulCount != 0)
{
psemRecord->ulCount--;
iRet = OS_OK;
}
if (pthread_mutex_unlock(&psemRecord->mutex))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
goto error_handler;
}
/* Return status */
return iRet;
error_handler:
/* Return failure */
return (OS_FAILURE);
}
/**
* OS Semaphore Take function.
*
* @param
* semId - semaphore identifier
*
* @param
* ulMilliSeconds - semaphore take timeout value in milliseconds
*
* @retval
* OS_OK if successful
* OS_TIMEOUT if timout
* OS_FAILURE if not successful
*/
#if defined(NDEBUG)
OS_STATUS OS_SemTakeMsec(OS_SEM_ID semId, int milliseconds)
#else
OS_STATUS OS_SemTakeMsecDbg(OS_SEM_ID semId, int milliseconds, char* srcFile, int srcLine)
#endif
{
if ( (milliseconds == OS_WAIT_FOREVER) || (milliseconds == OS_NO_WAIT) )
{
return ( OS_SemTake(semId, milliseconds) );
}
else
{
return ( OS_SemTake(semId, milliseconds*(CLOCKS_PER_SEC/1000)) );
}
}
/**
* OS Semaphore Give function. Basically increments the semaphore count,
* if possible.
*
* @param
* OS_SEM_ID semId - semaphore identifier
*
* @retval
* OS_OK if successful
* OS_FAILURE if not successful
*/
#if defined(NDEBUG)
OS_STATUS OS_SemGive(OS_SEM_ID semId)
#else
OS_STATUS OS_SemGiveDbg(OS_SEM_ID semId, char *srcFile, int srcLine)
#endif
{
OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
/* Check the validity of the semaphore */
if (semId == 0)
{
#if defined(NDEBUG)
DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
DbgPrint(("%s: BAD POINTER. Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
goto error_handler;
}
if (pthread_mutex_lock(&psemRecord->mutex) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
goto error_handler;
}
/* If the semaphore is binary and the count is 1, return an error */
if (psemRecord->ulSemType == OS_SEM_BINARY)
{
if (psemRecord->ulCount == 1)
{
pthread_mutex_unlock(&psemRecord->mutex);
goto error_handler;
}
}
/* Increment the semaphore count */
psemRecord->ulCount++;
/* wake one waiting thread */
if (pthread_cond_signal(&psemRecord->condWait))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
}
if (pthread_mutex_unlock(&psemRecord->mutex))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
goto error_handler;
}
/* Return successfully */
return OS_OK;
error_handler:
/* Return failure */
return (OS_FAILURE);
}
/**
* OS Semaphore Flush function
*
* @param
* OS_SEM_ID semId - semaphore identifier
*
* @retval
* Returns OS_OK is successful, OS_FAILURE otherwise.
*/
OS_STATUS OS_SemFlush(OS_SEM_ID semId)
{
OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
OS_STATUS status = OS_OK;
/* Check the validity of the semaphore */
if (0 == semId)
{
DbgPrint(("OS_SemFlush: BAD POINTER\n"));
return (OS_FAILURE);
}
if (pthread_mutex_lock(&psemRecord->mutex) == 0)
{
if (pthread_cond_broadcast(&psemRecord->condWait) != 0)
{
DbgPrint(("OS_SemFlush: Broadcast Failed\n"));
status = OS_FAILURE;
}
pthread_mutex_unlock(&psemRecord->mutex);
}
else
{
status = OS_FAILURE;
}
return (status);
}
/**
* OS memory pool Information function. Prints out information about
* the specified memory pool. This information includes the number of
* pages in the memory pool, the page size, the address of each memory
* page, and if each page is allocated or not.
*
* @param pool - The memory pool ID
*
* @retval
* None.
*/
void OS_MemoryInfo(OS_MEMPOOL_ID pool)
{
if (pool == NULL)
{
#ifdef __CALC_PEAK_ALLOCATION
DBGPRINT(1, ("OS_MemoryInfo:\n"));
DBGPRINT(1, ("/tPeak Allocations = %d Bytes\n", ulPeakAllocations));
DBGPRINT(1, ("/tCurrent Allocations = %d Bytes\n", ulCurrentAllocations));
#endif
}
else
{
OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool; /* Pointer to memory pool */
CHAR cUsed; /* Indicates if page allocated */
LONG lAtt; /* Indicates # pages attached */
DbgPrint( ("\n----- Memory Pool Information -----\n") );
DbgPrint( ("Number of Pages: %d\n", tmpPool->ulNumPages) );
DbgPrint( ("Page Size: %d\n", tmpPool->ulPgSize) );
DbgPrint( ("Memory Pages:\n") );
DbgPrint( ("\tPage\tAddress\t\tAllocated?\n") );
for (ULONG i = 0; i < tmpPool->ulNumPages; i++)
{
if (tmpPool->memPage[i].lAttached < 0)
{
lAtt = -1 * tmpPool->memPage[i].lAttached;
cUsed = 'Y';
}
else
{
lAtt = tmpPool->memPage[i].lAttached;
cUsed = 'N';
}
DbgPrint( ("\t%d:\t%x\t\t%c\n", i + 1, (ULONG)tmpPool->memPage[i].pvPgAddr, cUsed) );
}
}
return;
}
/**
* Creates a memory pool with the specified page size. This function does not
* allocate the memory for the pool. The memory address is provided as an input.
*
* @param pAddr - pointer to allocated memory buffer
* @param ulSize - Size of the memory pool
* @param ulPageSize - Page size of allocations from the pool. All allocations
* will be a multiple of this size.
*
* @retval non-negative memPoolID if success, NULL otherwise.
*
* @remark
* If ulSize is not a multiple of ulPageSize, then the memory pool
* will only contain the number of whole pages that fit in the size
* ulSize.
*/
OS_MEMPOOL_ID OS_CreateMemPool(PVOID pvAddr, ULONG ulSize, ULONG ulPageSize)
{
PVOID pvTmpAddr; /* Address of a page in memory pool */
OS_MEMPOOL *tmpPool = NULL; /* Pointer to memory pool */
ULONG ulArraySize; /* Size of array to hold memory pool */
/*
* If any of the parameters are invalid, return.
*/
if ( (pvAddr == NULL) || (ulPageSize == 0) )
{
return (NULL);
}
/*
* Allocate memory for the memory pool.
*/
tmpPool = (OS_MEMPOOL *)OS_MemAlloc(sizeof(OS_MEMPOOL) );
if (tmpPool == NULL)
{
return (NULL);
}
/*
* Set value for memory pool page size and the number of pages.
*/
tmpPool->ulPgSize = ulPageSize;
tmpPool->ulNumPages = ulSize / ulPageSize;
/*
* Allocate an array large enough to hold the memory pool.
*/
ulArraySize = sizeof(OS_MEMPOOL::Page) * tmpPool->ulNumPages;
tmpPool->memPage = (OS_MEMPOOL::Page *)OS_MemAlloc(ulArraySize);
if (tmpPool->memPage == NULL)
{
(void)OS_MemFree(tmpPool);
return (NULL);
}
/*
* Give a memory address to each page in the memory pool. Also,
* each page is given a value of the number of pages attached to
* it, including itself.
*/
pvTmpAddr = pvAddr;
for (ULONG i = 0; i < tmpPool->ulNumPages; i++)
{
tmpPool->memPage[i].pvPgAddr = pvTmpAddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -