🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.os.os2.programmer
2 messages
2 total messages Started by D G Booth Tue, 12 Mar 1991 15:20
Re: Making a non exclusive semaphore (like on Unix)
#2453
Author: D G Booth
Date: Tue, 12 Mar 1991 15:20
104 lines
3390 bytes
Christophe Wolfhugel asks whether OS/2 had any mechanism similar to 
the classic counting semaphores. There is no such mechanism built-in
to OS/2, but I have used the code below quite successfully.
 
The code defines a new structure type COUNTSEM which is a counting
semaphore, and functions P and V that operate on it. P decrements the
counter, but blocks if the counter is 0 until it is non-zero. V
increments the counter (and unblocks any blocked threads).
 
The code can be in an application managing mutual exclusion between
threads. It may also be in a DLL to manage semaphores between
processes, but in this case the MutualExclusion semaphore, and the
COUNTSEM structures should all be put in shared memory.
 
Duncan Booth <duncanb@ibmpcug.co.uk>
 
======= File: SEM.H ============
 
typedef struct COUNTSEM {
   long countSem;
   USHORT count;
} COUNTSEM, far *PCOUNTSEM;
 
void P (PCOUNTSEM s);	/* Wait till non-zero then decrement. */
BOOL P_timeout (PCOUNTSEM s, LONG timeout);	/* as P - may time out. */
void V (PCOUNTSEM s);				/* Increment */
======== End of SEM.H ==========
======= File: SEM.C ============
/*
 * Useful code using semaphores.
 * 
 * Author: Duncan Booth
 */
#define INCL_DOSPROCESS
#include <os2.h>
#include "sem.h"
 
/*
 * This semaphore is local to this file. It is used to control requests
 * to the counting semaphore structures.
 */
static long MutualExclusion = 0L;
 
#define	GET_SEM() (DosSemRequest (&MutualExclusion, SEM_INDEFINITE_WAIT))
#define	RLS_SEM() (DosSemClear (&MutualExclusion))
 
void P (PCOUNTSEM s)
{
   int blocked=1;
 
   while (blocked)
   {
      DosSemWait (&s->countSem, SEM_INDEFINITE_WAIT); /* wait til maybe ok */
 
      GET_SEM();
      if (s->count == 0)		/* not ready yet */
	 DosSemSet (&s->countSem);	/* set up block */
      else
      {
	 s->count--;	/* decrement count */
	 blocked = 0;	/* set up loop exit */
      }
      RLS_SEM();
   }
}
 
BOOL P_timeout (PCOUNTSEM s, LONG timeout)
{
   int blocked=1;
 
   while (blocked == 1)
   {
      if (DosSemWait (&s->countSem, timeout) != 0)
	 return FALSE;		/* wait til maybe ok */
 
      if (GET_SEM() != 0) return FALSE;
      if (s->count == 0)		/* not ready yet */
	 DosSemSet (&s->countSem);	/* set up block */
      else
      {
	 s->count--;	/* decrement count */
	 blocked = 0;	/* set up loop exit */
      }
      RLS_SEM();
   }
   return TRUE;
}
 
void V (PCOUNTSEM s)
{
   GET_SEM();			/* mutual excl */
   s->count++;			/* increment count */
   DosSemClear (&s->countSem);	/* free waiters */
   RLS_SEM();			/* mutual excl */
}
 
======== End of SEM.C ==========
-- 
Automatic Disclaimer:
The views expressed above are those of the author alone and may not
represent the views of the IBM PC User Group.
-- 
Duncan Booth, RCP Ltd.                    Didcot, Oxon, UK
duncanb@ibmpcug.co.uk                     Bix: jrichards
Re: Making a non exclusive semaphore (like on Unix)
#2520
Author: Gary Kushner
Date: Mon, 08 Apr 1991 02:25
78 lines
1984 bytes
Your code uses polling which should be avoided if at all possible.  Here
is the code I use:
----------
pv.h:
----------

/*------------
  Type for PVsems
  ------------*/

typedef struct _pvsem {
	long count;
	long more;				// sem clear if count > 0
	long mutex;
	} _far PVSEM;


/*-----------
  Protos
  -----------*/
PVSEM _far *PVSemCreate(void);
void _far _fastcall P(PVSEM _far *s);
void _far _fastcall V(PVSEM _far *s);

--------
pv.c
---------

#define INCL_DOSSEMAPHORES

#include <os2.h>
#include <malloc.h>
#include "pv.h"


/**************
*          PVSEMCREATE - allocate sem
**************/
PVSEM _far *PVSemCreate(void)
{
	PVSEM *s;

	if ( (s=calloc(1, sizeof(PVSEM))) != NULL)
		s->count=0;

	return s;
}


/**************
*          P - 
**************/
void _far _fastcall P(PVSEM _far *s)
{
		// any V's pending?  if not then wait...
	DosSemRequest(&s->more, SEM_INDEFINITE_WAIT);
	DosSemRequest(&s->mutex, SEM_INDEFINITE_WAIT);

		// if there are still more V's, then leave more clear
	if (--(s->count) > 0)
		DosSemClear(&s->more);

	DosSemClear(&s->mutex);
}


/**************
*          V - count them up
**************/
void _far _fastcall V(PVSEM _far *s)
{
	DosSemRequest(&s->mutex, SEM_INDEFINITE_WAIT);

	s->count++;
	DosSemClear(&s->more);		// ok guys, come and get it

	DosSemClear(&s->mutex);
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads