# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile # README # semCnt.c # semCnt.n # semCntLib.h # This archive created: Wed May 31 09:38:59 1989 sed 's/^X//' << \SHAR_EOF > Makefile X# Makefile for semCnt.o XVXLIB = /vx/h XCOPTS = -O X XsemCnt.o: semCnt.c XsemCnt.o: /vx/h/vxWorks.h XsemCnt.o: /vx/h/semLib.h XsemCnt.o: /vx/h/lstLib.h XsemCnt.o: /vx/h/local/semCntLib.h XsemCnt.o: /vx/h/local/lock.h X XsemCnt.o: X cc $(COPTS) -c -I$(VXLIB) semCnt.c SHAR_EOF sed 's/^X//' << \SHAR_EOF > README XThis is a set of routines that implement counting semaphores. The Xfiles are: X X semCnt.c - source code X semCntLib.h - Needed header file X lock.h - Another needed header file X semCnt.n - man page X Makefile - guess X XTo build modify the location of header files for your system in XMakefile and semCnt.c. X XRichard Neitzel XNational Center for Atmospheric Research XBox 3000 XBoulder, CO 80307 Xthor@thor.ucar.eduSHAR_EOF sed 's/^X//' << \SHAR_EOF > semCnt.c X/* X module: semCnt.c X Author: Richard E. K. Neitzel X Date: 13 Oct. 1988 X Xrevision history X---------------- X1.0,4oct88,rekn written X X This is a set of routines that implement counting semaphores. All X operations legal on binary semaphores are legal on these with the X addition of a function that allows the current count to be returned. X X The counting semaphores are implemented by coupling a binary semaphore X to a use count and a maximum count. When the counting semaphore is X taken, the use count is decremented. Once it reaches zero, futher X takes cause the caller to pend on the binary semaphore. Gives increment X the use count and if the use count is zero when the give routine is X entered, the binary semaphore is also given, so pending tasks awake. X The maximum count is checked to make sure that the use count never X exceeds the user's limit. X X The number of remaining counts can be determined by calling the X inspection routine. Note that this is a macro (defined in semCntLib.h) X and not a function. X X*/ X X X#include "vxWorks.h" X#include "semLib.h" X#include "local/semCntLib.h" X#include "local/lock.h" X X/* X semCntCreate - create a counting semaphore X*/ XCNT_SEM semCntCreate(count) Xint count; /* Number of takes allowed */ X{ X CNT_SEM cntPtr; /* The created semaphore */ X X X /* Allocate the needed space */ X X if ((cntPtr = (CNT_SEM)malloc(sizeof(struct cnt_sem))) == (CNT_SEM)NULL) X return((CNT_SEM)NULL); X X cntPtr->maxCount = cntPtr->count = count; X X if ((cntPtr->sem = semCreate()) == (SEM_ID)ERROR) X { X free((char *)cntPtr); /* If can't make sem. release space */ X return((CNT_SEM)NULL); X } X X return(cntPtr); X} X X/* X semCntTake - request semaphore X*/ Xvoid semCntTake(cntPtr) XCNT_SEM cntPtr; /* User's semaphore */ X{ X LOCK; /* Block other tasks */ X if (cntPtr->count > 0) X { X semClear(cntPtr->sem); /* Make sure that the semaphore is zero X or a later take will not block X correctly */ X --cntPtr->count; /* Take a count */ X UNLOCK; /* Resume contension */ X } X else X { X UNLOCK; /* Can't block others and wait */ X semTake(cntPtr->sem); /* Wait for a count to be released */ X LOCK; /* Block others during update */ X --cntPtr->count; /* Take it */ X UNLOCK; X } X} X X/* X semCntGive - signal a semaphore X*/ Xvoid semCntGive(cntPtr) XCNT_SEM cntPtr; /* User's semaphore */ X{ X LOCK; /* Block others during update */ X if (cntPtr->count == 0) X semGive(cntPtr->sem); /* Signal that we are releasing */ X X cntPtr->count++; /* Now fix count */ X X if (cntPtr->count > cntPtr->maxCount) /* But it might be too big */ X cntPtr->count = cntPtr->maxCount; X X UNLOCK; /* Now let others have access */ X} X X/* X semCntDelete - remove a semaphore X*/ Xvoid semCntDelete(cntPtr) XCNT_SEM cntPtr; /* User's semaphore */ X{ X semDelete(cntPtr->sem); /* Trash binary semaphore */ X X free((char *)cntPtr); /* Release memory */ X} SHAR_EOF sed 's/^X//' << \SHAR_EOF > semCnt.n X.TH semCnt l "13 October 1988" "" X.SH NAME XsemCntCreate, semCntTake, semCntGive, semCntInspect, semCntDelete - counting semphores X.SH SYNOPSIS X.nf XCNT_SEM semCntCreate(count); X Xvoid semCntTake(sem); X Xvoid semCntGive(sem); X XsemCntInspect(sem); X Xvoid semCntDelete(sem); X XCNT_SEM sem; Xint count; X.fi X.SH DESCRIPTION XThese routines allow the user access to counting semaphores. A counting Xsemaphore is created by calling X.I semCntCreate Xwith the number of counts in X.I count. XEach call to X.I semCntTake Xdecrements the count until zero is reached. Further attempts to take the Xsemaphore cause the caller to pend. Calls to X.I semCntGive Xincrement the count and if it was zero on entry, signal any pending tasks. X XIf the user wishes to know the number of counts (say prior to deleting the Xsemaphore), X.I semCntInspect Xis called. This is a macro that returns the current count. Deletion of Xthe semaphore is accomplished by X.I semCntDelete. XThe internal data structures are released back to the system. X.SH RETURN X.I semCntCreate Xreturns a CNT_SEM semaphore or NULL if it fails. X.I semCntInspect Xreturns the number of counts. X.SH FILES XInclude local/semCntLib.h. X.SH BUGS XBe forewarned that X.I semCntDelete Xdoes not zero out the CMT_SEM you pass to it. The pointer is still there, but Xpoints to invalid data. Also, tasks pending on a deleted semaphore pend Xforever. X.SH AUTHOR Xsend barbs, flames and other info to: X.nf XRichard Neitzel XNational Center for Atmospheric Research XBox 3000 XBoulder, CO 80307 Xthor@thor.ucar.eduSHAR_EOF sed 's/^X//' << \SHAR_EOF > semCntLib.h X/* X module - semCntLib.h X Author: Richard E. K. Neitzel X Date: 13 Oct. 88 X Xrevision history X---------------- X1.0,13oct88,rekn written X X The following is the internal structure used to make a counting X semaphore. X*/ X X#include "semLib.h" X#include "local/lock.h" X X#ifndef INCsemcntlibh X#define INCsemcntlibh X X/* HIDDEN */ Xstruct cnt_sem { X SEM_ID sem; X int count; X int maxCount; X}; X/* END HIDDEN */ X Xtypedef struct cnt_sem *CNT_SEM; X XCNT_SEM semCntCreate(); Xvoid semCntTake(); Xvoid semCntGive(); Xvoid semCntDelete(); X X#define semCntInspect(x) ((x)->count) X X#endif SHAR_EOF # End of shell archive exit 0