⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* semLib.c - general semaphore library *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02j,09nov01,dee  add CPU_FAMILY != COLDFIRE in portable test02i,26oct01,bwa  Added semEvLib and eventLib to the list of 'SEE ALSO'                 modules.02h,12oct01,cjj  Added documentation regarding S_eventLib_EVENTSEND_FAILED                 error02g,06sep01,bwa  Added VxWorks events support.02f,16nov98,cdp  make ARM CPUs with ARM_THUMB==TRUE use portable routines.02f,03mar00,zl   merged SH support into T202e,05oct98,jmp  doc: cleanup.02d,17feb98,cdp  undo 02c: put ARM back in list of optimised CPUs.02c,21oct97,kkk  undo 02d, take out ARM from list of optimized CPUs.02d,19may97,jpd  added ARM to list of optimised CPUs.02c,17oct96,dgp  doc: add errnos for user-visible routines per SPR 689302b,13jun96,ms   conditionally compiled the windview instrumentation 02a,22oct95,jdi  doc: added bit values for semTake() timeout param (SPR 4276).01z,19mar95,dvs  removed tron references.01y,03feb95,rhp  edit SEMAPHORE DELETION manpage text, duplicate under semDelete()01x,18jan95,rhp  Doc errno value on semTake() return due to timeout (SPR#1930)01w,09jun93,hdn  added a support for I80X8601z,14apr94,smb  fixed class dereferencing for instrumentation macros01y,15mar94,smb  modified instrumentation macros01x,24jan94,smb  added instrumentation macros01w,10dec93,smb  added instrumentation01v,29jan93,pme  added little endian support for shared sempahores.01u,20jan93,jdi  documentation cleanup for 5.1.01t,13nov92,dnw  added include of smObjLib.h01s,02oct92,pme  added reference to shared semaphores documentation.01r,22jul92,pme  made semDestroy return S_smObjLib_NO_OBJECT_DESTROY when		 trying to destroy a shared semaphore.01q,19jul92,pme  added shared memory semaphores support.01p,04jul92,jcf  tables now initialized to null to reduce coupling.01o,26may92,rrr  the tree shuffle01n,15sep91,ajm  added MIPS to list of optimized CPU's01m,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed includes to have absolute path from h/		  -fixed #else and #endif		  -changed VOID to void		  -changed copyright notice01l,26sep91,hdn  added conditional flag for TRON optimized code.01k,15aug91,del  changed interface to qInit to pass all "optional" args.01j,05apr91,jdi	 documentation -- removed header parens and x-ref numbers;		 doc review by jcf.01i,24mar91,jdi  documentation cleanup.01h,05oct90,dnw  made semTerminate() be NOMANUAL.01g,28aug90,jcf  documentation.01f,10aug90,dnw  corrected forward declaration of semQFlushDefer().01e,03aug90,jcf  documentation.01d,05jul90,jcf  optimized version now available.01c,26jun90,jcf  merged into one semaphore class.		 added semFlush ()01b,11may90,jcf  fixed up PORTABLE definition.01a,20oct89,jcf  written based on v1g of semLib.*//*DESCRIPTIONSemaphores are the basis for synchronization and mutual exclusion inVxWorks.  They are powerful in their simplicity and form the foundationfor numerous VxWorks facilities.Different semaphore types serve different needs, and while the behaviorof the types differs, their basic interface is the same.  This libraryprovides semaphore routines common to all VxWorks semaphore types.  Forall types, the two basic operations are semTake() and semGive(), theacquisition or relinquishing of a semaphore.Semaphore creation and initialization is handled by other libraries,depending on the type of semaphore used.  These libraries containfull functional descriptions of the semaphore types:    semBLib  - binary semaphores    semCLib  - counting semaphores    semMLib  - mutual exclusion semaphores    semSmLib - shared memory semaphoresBinary semaphores offer the greatest speed and the broadest applicability.The semLib library provides all other semaphore operations, includingroutines for semaphore control, deletion, and information.  Semaphoresmust be validated before any semaphore operation can be undertaken.  Aninvalid semaphore ID results in ERROR, and an appropriate `errno' is set.SEMAPHORE CONTROLThe semTake() call acquires a specified semaphore, blocking the callingtask or making the semaphore unavailable.  All semaphore types support atimeout on the semTake() operation.  The timeout is specified as thenumber of ticks to remain blocked on the semaphore.  Timeouts ofWAIT_FOREVER and NO_WAIT codify common timeouts.  If a semTake() timesout, it returns ERROR.  Refer to the library of the specific semaphore type for the exact behavior of this operation.The semGive() call relinquishes a specified semaphore, unblocking a pendedtask or making the semaphore available.  Refer to the library of thespecific semaphore type for the exact behavior of this operation.The semFlush() call may be used to atomically unblock all tasks pended ona semaphore queue, i.e., all tasks will be unblocked before any are allowedto run.  It may be thought of as a broadcast operation insynchronization applications.  The state of the semaphore is unchanged bythe use of semFlush(); it is not analogous to semGive().SEMAPHORE DELETIONThe semDelete() call terminates a semaphore and deallocates anyassociated memory.  The deletion of a semaphore unblocks tasks pendedon that semaphore; the routines which were pended return ERROR.  Takecare when deleting semaphores, particularly those used for mutualexclusion, to avoid deleting a semaphore out from under a task thatalready has taken (owns) that semaphore.  Applications should adoptthe protocol of only deleting semaphores that the deleting task hassuccessfully taken.SEMAPHORE INFORMATIONThe semInfo() call is a useful debugging aid, reporting all tasksblocked on a specified semaphore.  It provides a snapshot of the queue atthe time of the call, but because semaphores are dynamic, the informationmay be out of date by the time it is available.  As with the current state ofthe semaphore, use of the queue of pended tasks should be restricted todebugging uses only.VXWORKS EVENTSIf a task has registered for receiving events with a semaphore, events will besent when that semaphore becomes available. By becoming available, it isimplied that there is a change of state. For a binary semaphore, there is only a change of state when a semGive() is done on a semaphore that was taken. For a counting semaphore, there is always a change of state when the semaphore is available, since the count is incremented each time. For a mutex, a semGive() can only be performed if the current task is the owner, implying that the semaphore has been taken; thus, there is always a change of state.INTERNAL:	WINDVIEW INSTRUMENTATIONLevel 1:	semGive() causes EVENT_SEMGIVE		(portable only)	semTake() causes EVENT_SEMTAKE		(portable only)	semFlush() causes EVENT_SEMFLUSH	semDestroy() causes EVENT_SEMDELETELevel 2:	semGive() causes EVENT_OBJ_SEMGIVE	(portable only)	semTake() causes EVENT_OBJ_SEMTAKE	(portable only)	semFlush() causes EVENT_OBJ_SEMFLUSH	Level 3:	N/AINCLUDE FILES: semLib.hSEE ALSO: taskLib, semBLib, semCLib, semMLib, semSmLib, semEvLib, eventLib,.pG "Basic OS"*/#include "vxWorks.h"#include "taskLib.h"#include "qLib.h"#include "intLib.h"#include "errno.h"#include "smObjLib.h"#include "private/eventLibP.h"#include "private/classLibP.h"#include "private/eventP.h"#include "private/objLibP.h"#include "private/semLibP.h"#include "private/windLibP.h"#include "private/workQLibP.h"#include "private/semSmLibP.h"/* optimized version available for 680X0, MIPS, i86, SH, *//* COLDFIRE and ARM (excluding Thumb) */#if (defined(PORTABLE) || \     ((CPU_FAMILY != MC680X0) && \      (CPU_FAMILY != MIPS) && \      (CPU_FAMILY != I80X86) && \      (CPU_FAMILY != SH) && \      (CPU_FAMILY != COLDFIRE) && \      (CPU_FAMILY != ARM)) || \     ((CPU_FAMILY == ARM) && ARM_THUMB))#define semLib_PORTABLE#endif/* locals */LOCAL BOOL	semLibInstalled;		/* protect from muliple inits *//* globals */OBJ_CLASS semClass;				/* semaphore object class */CLASS_ID  semClassId = &semClass;		/* semaphore class ID */#ifdef	WV_INSTRUMENTATIONOBJ_CLASS semInstClass;				/* semaphore object class */CLASS_ID  semInstClassId = &semInstClass;	/* semaphore class ID */#endifFUNCPTR semGiveTbl [MAX_SEM_TYPE] =		/* semGive() methods by type */    {    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid    };FUNCPTR semTakeTbl [MAX_SEM_TYPE] =		/* semTake() methods by type */    {    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid    };FUNCPTR semFlushTbl [MAX_SEM_TYPE] =		/* semFlush() methods by type */    {    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid, (FUNCPTR) semInvalid,    (FUNCPTR) semInvalid, (FUNCPTR) semInvalid    };FUNCPTR semGiveDeferTbl [MAX_SEM_TYPE] =	/* semGiveDefer() methods */    {    (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL,    (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL    };FUNCPTR semFlushDeferTbl [MAX_SEM_TYPE] =	/* semFlushDefer() methods */    {    (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL,    (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) NULL    };/********************************************************************************* semLibInit - initialize the semaphore management package** This routine initializes the semaphore object class.  No semaphore* operation will work until this is called.  This routine is called during* system configuration within kernelInit().  This routine should only be* called once.** SEE ALSO: classLib* NOMANUAL*/STATUS semLibInit (void)    {    if ((!semLibInstalled) &&	(classInit (semClassId, sizeof(SEMAPHORE), OFFSET(SEMAPHORE,objCore),         (FUNCPTR) NULL, (FUNCPTR) NULL, (FUNCPTR) semDestroy) == OK))	{#ifdef	WV_INSTRUMENTATION	/* initialise instrumented class for semaphores */	semClassId->initRtn = semInstClassId;        classInstrument (semClassId, semInstClassId);#endif	semEvLibInit (); /* pull semaphore-related events lib in kernel */	semLibInstalled = TRUE;	}    return ((semLibInstalled) ? OK : ERROR);    }#ifdef semLib_PORTABLE/********************************************************************************* semGive - give a semaphore** This routine performs the give operation on a specified semaphore.* Depending on the type of semaphore, the state of the semaphore and of the* pending tasks may be affected.  If no tasks are pending on the sempahore and* a task has previously registered to receive events from the semaphore, these* events are sent in the context of this call.  This may result in the* unpending of the task waiting for the events.  If the semaphore fails to* send events and if it was created using the SEM_EVENTSEND_ERR_NOTIFY * option, ERROR is returned even though the give operation was successful.* The behavior of semGive() is discussed fully in the library description * of the specific semaphore type being used.** RETURNS: OK on success or ERROR otherwise** ERRNO:* .iP "S_intLib_NOT_ISR_CALLABLE"* Routine was called from an ISR for a mutex semaphore.* .iP "S_objLib_OBJ_ID_ERROR"* Semaphore ID is invalid.* .iP "S_semLib_INVALID_OPERATION"* Current task not owner of mutex semaphore.* .iP "S_eventLib_EVENTSEND_FAILED"* Semaphore failed to send events to the registered task.  This errno * value can only exist if the semaphore was created with the * SEM_EVENTSEND_ERR_NOTIFY option.* .LP** SEE ALSO: semBLib, semCLib, semMLib, semSmLib, semEvStart*/STATUS semGive    (    SEM_ID semId        /* semaphore ID to give */    )    {    SM_SEM_ID  smObjSemId;	/* shared semaphore ID */    /* check if semaphore is shared */    if (ID_IS_SHARED (semId))  	{	smObjSemId = (SM_SEM_ID) SM_OBJ_ID_TO_ADRS(semId);	return ((*semGiveTbl[ntohl (smObjSemId->objType) & SEM_TYPE_MASK])		(smObjSemId));	}    /* otherwise the semaphore is local */#ifdef	WV_INSTRUMENTATION    /* windview - level 1 event logging */    EVT_OBJ_3 (OBJ, semId, semClassId, EVENT_SEMGIVE, semId, 		semId->state, semId->recurse);#endif    if (kernelState)	return (semGiveDefer (semId));      /* defer semaphore give */    else	return((* semGiveTbl[semId->semType & SEM_TYPE_MASK]) (semId));    }/********************************************************************************* semTake - take a semaphore** This routine performs the take operation on a specified semaphore.* Depending on the type of semaphore, the state of the semaphore and* the calling task may be affected.  The behavior of semTake() is* discussed fully in the library description of the specific semaphore * type being used.** A timeout in ticks may be specified.  If a task times out, semTake() will* return ERROR.  Timeouts of WAIT_FOREVER (-1) and NO_WAIT (0) indicate to wait* indefinitely or not to wait at all.** When semTake() returns due to timeout, it sets the errno to* S_objLib_OBJ_TIMEOUT (defined in objLib.h).* * The semTake() routine is not callable from interrupt service routines.** RETURNS: OK, or ERROR if the semaphore ID is invalid or the task timed out.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_ID_ERROR,*        S_objLib_OBJ_UNAVAILABLE** SEE ALSO: semBLib, semCLib, semMLib, semSmLib*/STATUS semTake    (    SEM_ID semId,       /* semaphore ID to take */    int timeout         /* timeout in ticks */    )    {    SM_SEM_ID  smObjSemId;      /* shared semaphore ID */    /* check if semaphore is global (shared) */    if (ID_IS_SHARED (semId))	{	smObjSemId = (SM_SEM_ID) SM_OBJ_ID_TO_ADRS(semId);        return ((* semTakeTbl[ntohl (smObjSemId->objType) & SEM_TYPE_MASK ]) 		 (smObjSemId, timeout));	}    /* otherwise sempahore is local */#ifdef	WV_INSTRUMENTATION    /* windview - level 1 event logging */    EVT_OBJ_3 (OBJ, semId, semClassId, EVENT_SEMTAKE, semId, 		semId->state, semId->recurse);#endif    return ((* (semTakeTbl[semId->semType & SEM_TYPE_MASK])) (semId, timeout));    }#endif	/* semLib_PORTABLE *//********************************************************************************* semFlush - unblock every task pended on a semaphore** This routine atomically unblocks all tasks pended on a specified* semaphore, i.e., all tasks will be unblocked before any is allowed

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -