187 lines
3.9 KiB
C
187 lines
3.9 KiB
C
/* dsiUtilLib.c - utilities for the DSI stack */
|
|
|
|
/*
|
|
* Copyright (c) 2004-2005, 2007, 2011, 2013 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute, modify or otherwise make use
|
|
* of this software may be licensed only pursuant to the terms
|
|
* of an applicable Wind River license agreement.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01h,16sep13,f_f fix static overrun (WIND00435182)
|
|
01g,07jun11,shi LP64 conversion
|
|
01f,04jul07,ebh changes to allow DSI to run in SMP systems
|
|
01e,04may07,ebh modify dsiTsleep to return EINTR (Defect #91328)
|
|
01d,21feb05,ebh update manually (zippy merge was not running)
|
|
01c,28jan05,dlk Fix compiler warning.
|
|
01c,04jan05,bwa doc fix (SPR #103021).
|
|
01b,11oct04,p_r fixed pathname for dsi header (SPR #102446)
|
|
01a,17aug04,dlk written.
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This is an internal library that provides general utilities for the DSI
|
|
stack.
|
|
|
|
In particular, it provides the mutual exclusion routines dsiLock() and
|
|
dsiUnlock(), which replace splnet() and splx() for the DSI/AF_LOCAL/COMP
|
|
stack. It also provides the dsiTsleep() routine, which replaces tsleep()
|
|
and ksleep().
|
|
|
|
NOMANUAL
|
|
*/
|
|
|
|
/* VxWorks system includes */
|
|
|
|
#include <vxWorks.h>
|
|
#include <taskLib.h>
|
|
#include <semLib.h>
|
|
#include <private/semLibP.h>
|
|
#include <errno.h>
|
|
|
|
#include <dsi/backend/dsiUtilLib.h>
|
|
|
|
typedef struct _DSI_LOCK_INFO
|
|
{
|
|
TASK_ID lockTask;
|
|
SEMAPHORE sem;
|
|
BOOL initialized;
|
|
} DSI_LOCK_INFO;
|
|
|
|
/* globals */
|
|
|
|
int dsiLockMutexOptions = (SEM_Q_PRIORITY |
|
|
SEM_DELETE_SAFE |
|
|
SEM_INVERSION_SAFE);
|
|
|
|
/* locals */
|
|
|
|
LOCAL DSI_LOCK_INFO dsiLockInfo;
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* dsiLockInit - initialize AF_LOCAL/COMP/DSI mutual exclusion.
|
|
*
|
|
* This routine must be called as part of DSI initialization.
|
|
*
|
|
* RETURNS: OK or ERROR.
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
|
|
STATUS dsiLockInit (void)
|
|
{
|
|
STATUS status;
|
|
|
|
if (dsiLockInfo.initialized)
|
|
return OK;
|
|
|
|
dsiLockInfo.lockTask = 0;
|
|
|
|
status = semMInit (&dsiLockInfo.sem, dsiLockMutexOptions);
|
|
|
|
if (status == OK)
|
|
dsiLockInfo.initialized = TRUE;
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
*
|
|
* dsiLock - obtain AF_LOCAL/COMP/DSI mutual exclusion.
|
|
*
|
|
* This routine is the equivalent of splnet() for the DSI stack.
|
|
*
|
|
* RETURNS: 1 if the caller owned the DSI lock before the call; 0 if the
|
|
* caller did not.
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
|
|
int dsiLock (void)
|
|
{
|
|
if (dsiLockInfo.lockTask == (TASK_ID)taskIdCurrent)
|
|
return 1;
|
|
|
|
(void)semTake (&dsiLockInfo.sem, WAIT_FOREVER);
|
|
dsiLockInfo.lockTask = (TASK_ID)taskIdCurrent;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************
|
|
*
|
|
* dsiUnlock - release AF_LOCAL/COMP/DSI mutual exclusion.
|
|
*
|
|
* This routine is the equivalent of splx() for the DSI stack.
|
|
* It gets passed the return value from the corresponding call to
|
|
* dsiLock(); it releases mutual exlusion when the argument <key> is zero.
|
|
*
|
|
* RETURNS: N/A
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
|
|
void dsiUnlock
|
|
(
|
|
int key
|
|
)
|
|
{
|
|
if (key == 0)
|
|
{
|
|
dsiLockInfo.lockTask = 0;
|
|
semGive (&dsiLockInfo.sem);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************
|
|
*
|
|
* dsiTsleep - sleep with a timeout
|
|
*
|
|
* This routine is the equivalent of tsleep() for DSI.
|
|
* It should only be called when holding DSI lock.
|
|
*
|
|
* NOMANUAL
|
|
*/
|
|
|
|
STATUS dsiTsleep
|
|
(
|
|
SEM_ID semId,
|
|
int timeo_val
|
|
)
|
|
{
|
|
STATUS status;
|
|
|
|
/* Note, we must be holding the DSI lock */
|
|
|
|
if (timeo_val != NO_WAIT)
|
|
{
|
|
/* give up DSI big lock */
|
|
dsiLockInfo.lockTask = 0;
|
|
semGive (&dsiLockInfo.sem);
|
|
|
|
/* wait for event */
|
|
status = semTake (semId, timeo_val);
|
|
|
|
/* get DSI big lock */
|
|
(void)semTake (&dsiLockInfo.sem, WAIT_FOREVER);
|
|
dsiLockInfo.lockTask = (TASK_ID) taskIdCurrent;
|
|
}
|
|
else
|
|
{
|
|
/* Do not wait, so don't give up DSI big lock */
|
|
status = semTake (semId, timeo_val);
|
|
}
|
|
|
|
/* assume timeout or interruption rather than corruption ! */
|
|
|
|
return(status == OK ? OK : (errno == EINTR) ? EINTR : EWOULDBLOCK);
|
|
}
|
|
|