📄 osapi_linux.cpp
字号:
/**
* OS Message Queue Remove function.
*
* @param mqId - message queue identifier
* @param *strMsg - message pointer, the location of where the removed message is to be placed after it has been removed
* @param uiSize - message size (not used)
*
* @retval
* OS_OK if successful
* OS_FAILURE if not successful
* OS_TIMEOUT if msg queue is empty
*/
#if defined(NDEBUG)
OS_STATUS OS_MsgQRemove(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize)
#else
OS_STATUS OS_MsgQRemoveDbg(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize, char *srcFile, int srcLine)
#endif
{
/* Check the validity of message queue */
if (mqId == 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);
}
/* Receive message from the head by default */
return (OS_MsgQReceiveOption(mqId, strMsg, ulSize, OS_NO_WAIT, OS_MSG_Q_TAIL) );
}
/**
* OS Message Queue Receive Option function. Same as OS_MsgQReceive, but allow message to received
* from either the head or the tail of the message queue.
*
* @param mqId - message queue identifier
* @param *strMsg - message pointer, the location of where the received message is to be placed after it has been received
* @param uiSize - message size (not used)
* @param iTimeout - send timeout value, in ticks. (-1 = wait forever, 0 = no wait, > 1 = wait)
* @param iOption - head or tail of message queue (OS_MSG_Q_HEAD or OS_MSG_Q_TAIL)
*
* @retval
* OS_OK if successful
* OS_FAILURE if not successful
* OS_TIMEOUT if a timeout occurred
*/
static OS_STATUS OS_MsgQReceiveOption(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize, int iTimeout, int iOption)
{
OS_STATUS iRet = OS_OK;
OS_MBOX *pmsg = (OS_MBOX *)mqId;
struct timeval tv;
struct timespec abstime;
/* Check the validity of message queue */
if (mqId == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: INVALID mqId!\n", __FUNCTION__));
goto error_handler;
}
/* Check the validity of message */
if (strMsg == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: BAD POINTER!\n", __FUNCTION__));
goto error_handler;
}
if (ulSize != pmsg->ulSize)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: INVALID SIZE!\n", __FUNCTION__));
goto error_handler;
}
/* Get Mutex */
if (pthread_mutex_lock(&pmsg->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(&pmsg->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;
}
}
/* If empty queue, wait */
while (pmsg->ulHead == pmsg->ulTail)
{
if (OS_WAIT_FOREVER == iTimeout)
{
if (pthread_cond_wait(&pmsg->condWaitEmpty, &pmsg->mutex) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_wait ERROR!\n"));
iRet = OS_FAILURE;
break;
}
}
else if (OS_NO_WAIT == iTimeout)
{
iRet = OS_TIMEOUT;
break;
}
else
{
iRet = pthread_cond_timedwait(&pmsg->condWaitEmpty, &pmsg->mutex, &abstime);
if (iRet != 0)
{
if (iRet == ETIMEDOUT)
{
iRet = OS_TIMEOUT;
break;
}
else
{
switch ( iRet )
{
case EINVAL: DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = EINVAL\n")); break;
case EFAULT: DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = EFAULT\n")); break;
case ETIMEDOUT: DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = ETIMEDOUT\n")); break;
default: DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = unknown\n")); break;
}
iRet = OS_FAILURE;
break;
}
}
}
}
/* if we didn't time out, receive it from the queue */
if (OS_OK == iRet)
{
/* Receive it from the queue */
if (iOption == OS_MSG_Q_TAIL)
{
/* Receive from tail of queue */
pmsg->ulTail = ( (pmsg->ulTail + pmsg->ulDepth) % (pmsg->ulDepth + 1) );
memcpy(strMsg, pmsg->pbBuffers + (pmsg->ulTail * pmsg->ulSize), pmsg->ulSize);
}
else
{
/* Receive from head of queue */
memcpy(strMsg, pmsg->pbBuffers + (pmsg->ulHead * pmsg->ulSize), pmsg->ulSize);
pmsg->ulHead = ( (pmsg->ulHead + 1) % (pmsg->ulDepth + 1) );
}
/* Signal any waiters */
if (pthread_cond_signal(&pmsg->condWaitFull))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
}
}
/* Release mutex */
if (pthread_mutex_unlock(&pmsg->mutex))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
goto error_handler;
}
/* Return success */
return (iRet);
error_handler:
/* Return failure */
return (OS_FAILURE);
}
/**
* Removes all messages from the queue.
*
* @param mqId - message queue identifier
*
* @retval OS_OK if successful, else an osapi error code.
*/
OS_STATUS OS_MsgQReset(OS_MSG_Q_ID mqId)
{
OS_MBOX *pmsg = (OS_MBOX *)mqId;
/* Check the validity of message queue */
if (mqId == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: BAD POINTER!\n", __FUNCTION__));
goto error_handler;
}
/* Get Mutex */
if (pthread_mutex_lock(&pmsg->mutex) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
goto error_handler;
}
/* reset queue */
pmsg->ulHead = pmsg->ulTail;
/* Signal any waiters */
if (pthread_cond_broadcast(&pmsg->condWaitEmpty))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
}
if (pthread_cond_broadcast(&pmsg->condWaitFull))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
}
/* Release mutex */
if (pthread_mutex_unlock(&pmsg->mutex))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
goto error_handler;
}
/* Return success */
return (OS_OK);
error_handler:
/* Return failure */
return (OS_FAILURE);
}
/**
* OS Message Queue Number of Messages function.
*
* @param
* OS_MSG_Q_ID mqId - message queue identifier
*
* @retval
* Returns the number of messages in the given message queue.
*/
int OS_MsgQNumMsgs(OS_MSG_Q_ID mqId)
{
OS_MBOX *pmsg = (OS_MBOX *)mqId;
int num_messages = 0;
/* Check the validity of message queue */
if (mqId == 0)
{
DbgPrint(("%s: BAD POINTER!\n", __FUNCTION__));
return (OS_FAILURE);
}
/* Get Mutex */
if (pthread_mutex_lock(&pmsg->mutex) == 0)
{
if (pmsg->ulHead > pmsg->ulTail)
{
num_messages = pmsg->ulTail + pmsg->ulDepth + 1 - pmsg->ulHead;
}
else
{
num_messages = pmsg->ulTail - pmsg->ulHead;
}
/* Release mutex */
pthread_mutex_unlock(&pmsg->mutex);
}
else
{
num_messages = OS_FAILURE;
}
return (num_messages);
}
/******************************************************************************
*******************************************************************************
** **
** Semaphore function definitions **
** **
*******************************************************************************
******************************************************************************/
/**
* OS Semaphore Binary Create function.
*
* @param
* int iOSOptions - operating system options (not used)
*
* @param
* OS_SEM_B_STATE semsInitialState - initial semaphore state
*
* @retval
* OS_SEM_ID semId - semaphore identifier, if successful
* 0 - if not successful
*/
OS_SEM_ID OS_SemBCreate(int iOSOptions, OS_SEM_B_STATE semsInitialState)
{
OS_SEMAPHORE *psemRecord = NULL;
/* Check the validity of the initial semaphore state */
if ( (semsInitialState != OS_SEM_EMPTY) && (semsInitialState != OS_SEM_FULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Invalid initial state (%d)!\n", semsInitialState));
goto error;
}
/* Allocate a record for the semaphore */
psemRecord = (OS_SEMAPHORE *)OS_MemAlloc(sizeof(OS_SEMAPHORE));
if (psemRecord == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not allocate semaphore record!\n"));
goto error;
}
/* Set the semaphore type as binary */
psemRecord->ulSemType = OS_SEM_BINARY;
/* Set maximum to 1 */
psemRecord->ulMaxCount = 0;
/* Set count to the parameter */
psemRecord->ulCount = semsInitialState;
/* No name was specified for the semaphore */
strncpy(psemRecord->strName, "\0", MAX_NAME_SIZE);
/* Create the binary semaphore */
if (pthread_cond_init(&psemRecord->condWait, NULL) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not init condWait"));
goto error;
}
if (pthread_mutex_init(&psemRecord->mutex, NULL) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not init mutex"));
goto error;
}
/* Return a handle to the binary semaphore */
return (OS_SEM_ID)psemRecord;
error:
if (NULL != psemRecord)
{
OS_MemFree(psemRecord);
}
return (0);
}
/**
* OS Semaphore Binary Create function.
*
* @param iOSOptions - operating system options (not used)
* @param semsInitialState - initial semaphore state
* @param strName - Null terminated string.
*
* @retval
* OS_SEM_ID semId - semaphore identifier, if successful
* 0 - if not successful
*/
OS_SEM_ID OS_SemBCreateNamed(int iOSOptions, OS_SEM_B_STATE semsInitialState, char *strName)
{
OS_SEM_ID semId = 0;
OS_SEMAPHORE *psemRecord;
/*
* Create a counting semaphore
*/
semId = OS_SemBCreate(iOSOptions, semsInitialState);
if (semId == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreateNamed: Could not create named semaphore!\n"));
return 0;
}
/*
* Name the 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 Count Create function.
*
* @param
* int iOSOptions - operating system options
*
* @param
* int iInitialCount - initial reference count
*
* @retval
* OS_SEM_ID semId - semaphore identifier, if successful
* 0 - if not successful
*/
OS_SEM_ID OS_SemCCreate(int iOSOptions, int iInitialCount)
{
OS_SEMAPHORE *psemRecord = NULL;
/* Check the validity of the given initial count */
if (iInitialCount < 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Invalid initial count (%d)!\n", iInitialCount));
goto error;
}
/* Allocate a record for the semaphore */
psemRecord = (OS_SEMAPHORE *)OS_MemAlloc(sizeof(OS_SEMAPHORE));
if (psemRecord == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not allocate semaphore record!\n"));
goto error;
}
/* Set the semaphore type as counting */
psemRecord->ulSemType = OS_SEM_COUNTING;
/* No name was specified for the semaphore */
strncpy(psemRecord->strName, "\0", MAX_NAME_SIZE);
/* Set maximum count to some large number... */
psemRecord->ulMaxCount = 32678;
/* Set count to the parameter */
psemRecord->ulCount = iInitialCount;
/* Create the binary semaphore */
if (pthread_cond_init(&psemRecord->condWait, NULL) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not init condWait"));
goto error;
}
if (pthread_mutex_init(&psemRecord->mutex, NULL) != 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not init mutex"));
goto error;
}
/* Return a handle to the counting semaphore */
return (OS_SEM_ID)psemRecord;
error:
if (NULL != psemRecord)
{
OS_MemFree(psemRecord);
}
return (0);
}
/**
* OS Semaphore Count Create (Named) function.
*
* @param
* int iOSOptions - operating system options
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -