home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / MAILBOX.ZIP / MPSEM.H < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-27  |  5.7 KB  |  120 lines

  1. /****************************************************************************/
  2. /* mpsem.h  -- SEMAPHORE CLUSTER (INTERFACE)                    */
  3. /* Created:  11/22/87        Release:  0.7        Version:  12/03/87  */
  4. /****************************************************************************
  5. (c) Copyright 1987 by Michael Benjamin Parker           (USA SS# 557-49-4130)
  6.  
  7. All Rights Reserved unless specified in the following include files: */
  8. #include "mptsk.cpy" /*
  9.  
  10. DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
  11. ****************************************************************************/
  12. /* OVERVIEW:
  13. The semaphore cluster implements semaphores needed for
  14. multi-processor exection control (inter-proprocessor syncronization).
  15. The semaphores can be used as gates so to only allow a certain number
  16. of processors (usually one) to access data the semaphore protects, so
  17. that changes to the data are autonomous.
  18.  
  19. To control access to a particular data structure, include MPSEM datatype
  20. as one of its fields.  When the data structure is created, initialize
  21. the semaphore to the number of simultaneous accessors you intend to allow.
  22. Then, to access the data structure, always enter a critical section
  23. (see below).
  24.  
  25. The semaphores implemented here are "machine-level".  When waiting for a
  26. semaphore to be released, the processor just spins in a loop rather than
  27. doing something else productive.  And if there are other processors waiting,
  28. there is no implicit ordering of which gets the semaphore first.  Finally,
  29. when the semaphore is claimed, all signals are blocked and if the processor
  30. doesn't release the semaphore quickly, interrupts will be lost (possibly
  31. preventing other tasks from being run and losing I/O to the computer).
  32.  
  33. Thus, these semaphores are designed for low-level system programming
  34. to synchronize *processors*.  If *task* syncronization is desired,
  35. higher-level constructs built on this system programming should be used.
  36. ****************************************************************************/
  37. /****************************************************************************/
  38. #ifndef    MPSEM_H
  39. #define    MPSEM_H
  40. /****************************************************************************/
  41. /****************************************************************************/
  42. /* DATA INTERFACE:                                */
  43. #ifdef    ANSI_C
  44.     typedef volatile int    MPSEM, *MPSEMID;
  45. #else
  46.     typedef     int    MPSEM, *MPSEMID;
  47. #endif
  48. /****************************************************************************/
  49. /****************************************************************************/
  50. /* CODE INTERFACE:                                */
  51. /****************************************************************************/
  52. /* int    mpsem_val(MPSEMID mpsem)    int
  53.  
  54. (A MACRO)  RETURNS OR ASSIGNS THE CURRENT VALUE OF THE SEMAPHORE IN ONE
  55. INDIVISABLE OPERATION.  (USUALLY ASSIGNED TO THE NUMBER OF CLAIMS WHICH
  56. CAN BE ACTIVE AT ONCE) */
  57. /****************************************************************************/
  58. /* void    mpsem_inc(MPSEMID mpsem);
  59.  
  60. INCREMENTS THE SEMAPHORE IN ONE INDIVISABLE OPERATION. */
  61. /****************************************************************************/
  62. /* void    mpsem_dec(MPSEMID mpsem);
  63.  
  64. DECREMENTS THE SEMAPHORE IN ONE INDIVISABLE OPERATION. */
  65. /****************************************************************************/
  66. /* void    mpsem_critsect(MPSEMID mpsem, CODEBLOCK);     */
  67. /*
  68. A MACRO WHICH TEMPORARILY CLAIMS mpsem AND BLOCKS ALL SIGNALS FOR THE
  69. EVALUATION OF CODEBLOCK.  SPECIFICALLY, IT
  70.     WAITS UNTIL SEMAPHORE mpsem CAN BE CLAIMED, THEN...
  71.     BLOCKS ALL SIGNALS,
  72.     CLAIMS THE SEMAPHORE,
  73.     EVALUATES CODEBLOCK,
  74.     RELEASES THE SEMAPHORE, AND
  75.     RESTORES THE SIGNALS TO THEIR ORIGINAL VALUE.    */
  76. /****************************************************************************/
  77. /* void    mpsem_take(MPSEMID mpsem);    */
  78. /*
  79. WAITS UNTIL THE SEMAPHORE IS POSITIVE, THEN DECREMENTS (CLAIMS) IT.  IF THERE
  80. ARE SEVERAL WAITERS, THE OPERATION MAY TAKE AN UNDETERMINED AMOUT OF TIME.
  81. HAS NO EFFECT ON SIGNALS.  mpsem_critsect SHOULD BE USED IF POSSIBLE. */
  82. /****************************************************************************/
  83. /* void    mpsem_give(MPSEMID mpsem);
  84.  
  85. INCREMENTS (RELEASES) THE SEMAPHORE IMMEDIATELY.
  86. (ASSUMES THE SEMAPHORE HAD BEEN CLAIMED BEFORE)
  87. HAS NO EFFECT ON SIGNALS.  mpsem_critsect SHOULD BE USED IF POSSIBLE. */
  88. /****************************************************************************/
  89. /****************************************************************************/
  90. /****************************************************************************/
  91. /* STRUCTURE, EXTERNAL-VARIBLE, AND MACRO DEFINITION:                */
  92. /****************************************************************************/
  93. #include "mpsig.h"
  94. #define    mpsem_init(mpsem)    \
  95.             (mpsem_val((MPSEMID)(mpsem))= 1, (MPSEMID)(mpsem))
  96. #define    mpsem_dinit(mpsem)    ((void PTR)(mpsem))
  97. #define    mpsem_val(mpsem)    (*(mpsem))
  98. #define    mpsem_inc(mpsem)    (mpsem_val(mpsem)++)
  99. #define    mpsem_dec(mpsem)    (--mpsem_val(mpsem))    
  100. #define mpsem_give(mpsem)    mpsem_inc(mpsem)
  101. #define    mpsem_take(mpsem)    while (mpsem_dec(mpsem), mpsem_val(mpsem)<0) \
  102.                     mpsem_inc(mpsem)
  103. #define    mpsem_critsect(mpsem,CODEBLOCK)                    \
  104. {                                    \
  105.     BOOL    semclaimed=    BOOL_FALSE;                \
  106.     do {                                \
  107.         mpsig_critsect({                    \
  108.             mpsem_dec(mpsem);                \
  109.             semclaimed= bool_create(mpsem_val(mpsem) >= 0);    \
  110.             if (semclaimed)    {CODEBLOCK};            \
  111.             mpsem_inc(mpsem);                \
  112.         });                            \
  113.     } while (!semclaimed);                        \
  114. }
  115. /****************************************************************************/
  116. /****************************************************************************/
  117. /****************************************************************************/
  118. #endif /* MPSEM_H */
  119.  
  120.