Files
m241Neelima/vxworks-6.9/target/src/dsi/backend/dsiUtilLib.c
T
2026-07-30 11:19:44 +05:30

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);
}