wolf@grasp1.univ-lyon1.fr (Christophe Wolfhugel) (03/10/91)
Is there any mechanisme similar to Unixes' semaphores, ie I'd like to get a semaphore with units: - one thread increments it (so never blocking) - another thread uses units and gets blocked only when the counter is 0. (it's for managing a packet layer window in a comm package). -- Christophe Wolfhugel (on irc: Zolf) | Email: wolf@grasp1.univ-lyon1.fr Listserv admin at fifi.univ-lyon1.fr | Fax: (+33) 72 44 08 00
wbonner@eecs.wsu.edu (Wim Bonner) (03/12/91)
In article <18131@milton.u.washington.edu> wolf@grasp1.univ-lyon1.fr (Christophe Wolfhugel) writes: >Is there any mechanisme similar to Unixes' semaphores, ie I'd like to get >a semaphore with units: > - one thread increments it (so never blocking) > - another thread uses units and gets blocked only when the counter is 0. >(it's for managing a packet layer window in a comm package). I know that when you use semaphores in OS/2, they are not really sspecified as to the way they are impleneted internally, but a DosSemWait will wait for the semaphore to be completely cleared. (Multple DosSemSet()'s seem to increment the counter, and you must use the same number of DosSemClear()'s to get the semaphore back to the original state.) A DosSemRequest will wait till the sem has been cleared, and then set it. Hope this helps... -- | wbonner@yoda.eecs.wsu.edu | | 27313853@wsuvm1.csc.wsu.edu | | 72561.3135@CompuServe.com |
duncanb@ibmpcug.co.uk (D G Booth) (03/12/91)
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
kushner@ux1.lbl.gov (Gary Kushner) (04/08/91)
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); }