1: /* mutex.h -- include file for reflective memory mutex implementation. */
  2: /* rjbrown1@rockwellcollins & rj@elilabs.com Tue Feb  1 17:12:01 CST 2011 */
  3: 
  4: #ifndef __mutex_h__
  5: #define __mutex_h__
  6: 
  7: 
  8: /* This file specifies the task names and the mutex names for the mutex implementation defined in mutex.c,
  9:    which is a C language implementation of Boleslaw Szymanski's "Four-Bit Robust First-Come First-Served
 10:    Algorithm" for mutual exclusion (mutex) for shared memory and distributed assynchronous processors, as
 11:    described in Figure 5 in the paper "Mutual Exclusion Revisited", published in "Proceedings of the Fifth
 12:    Jerusalem Conference on Information Technology", Jerusalem, Israel, October 1990, IEEE Computer Society
 13:    Press, Los Alamitos, CA, pp. 110-117.
 14: 
 15:    This file is intended to be edited by the user to specify the task names and mutex names that are needed
 16:    for his particular application.  After this file has been edited, it is necessary to re-compile the file
 17:    mutex.c to get a version that makes use of the names defined in this file.
 18: 
 19:    See the mutex.c source file for additional documentation. */
 20: 
 21: 
 22: /* ---------------- BEGIN USER MODIFIABLE PART ---------------- */
 23: 
 24: 
 25: typedef int word;                        /* An integral type with the width of a memory word, ie what can be
 26:                                            stored and fetched with a single memory cycle.  On a 32 bit intel
 27:                                            x86 machine, this is int, but on a 64 bit machine, is is probably
 28:                                            long int, or long long int, depending on your compiler.  It will
 29:                                            not break the algorithm if this is declared to large, but all
 30:                                            guarantees are off if it is too small.  FIXME Is cache line width a
 31:                                            concern here? */
 32: 
 33: 
 34: typedef enum {                                /* A name for each task. */
 35:   t0,                                        /* Edit this to use meaningful task names! */
 36:   t1,
 37:   t2,
 38:   NUM_TASKS                                /* The total number of tasks. */
 39: } task_num;
 40:     
 41: 
 42: typedef enum {                                /* A name for each mutex. */
 43:   m0,                                        /* Edit this to use meaningful mutex names! */
 44:   m1,
 45:   m2,
 46:   m3,
 47:   NUM_MUTEXES                                /* The total number of mutexes. */
 48: } mutex_num;
 49: 
 50: 
 51: /* ---------------- END USER MODIFIABLE PART ---------------- */
 52: 
 53: 
 54: /* A name for each state bit, taken from Szymanski's paper. */
 55: 
 56: typedef enum {
 57:   a,                                        /* active */
 58:   w,                                        /* waiting */
 59:   s,                                        /* shutting the door */
 60:   p,                                        /* parity */
 61:   NUM_STATE_BITS                        /* The total number of state bits. */
 62: } state_bit;
 63: 
 64: 
 65: /* The type of the array of flag bits that exists in shared memory, accessible to all tasks.  Only task[i]
 66:    will write flag[i], but all tasks will read all flags. */
 67: 
 68: typedef word (flag_bits_t[NUM_MUTEXES][NUM_TASKS][NUM_STATE_BITS]);
 69: 
 70: 
 71: /* The function signatures for the mutex implementation. */
 72: 
 73: void initialize_mutex(task_num me, volatile flag_bits_t* shared_memory_ptr);
 74: 
 75: void acquire_mutex(task_num me, mutex_num mutex);
 76: 
 77: void release_mutex(task_num me, mutex_num mutex);
 78: 
 79: 
 80: #endif /* __mutex_h__ */
 81: