/* enqdeq.h */ /* Data structures for condition variable based solution to the */ /* readers and writers problem... */ #include #define READ 1 #define WRITE 2 /* These Queue Elements are used to represent threads that are */ /* waiting upon the resource.. They should be dynamically created */ /* using malloc() ONLY IF a thread must wait and should be */ /* released using free() AT THE TIME the request is granted. */ struct qeltype { int tid; /* For debugging */ int action; /* Read or write */ struct qeltype *qnext; /* Next element in list (or NULL) */ }; /* This Queue Control block is used to serialize access of a number */ /* of reading or writing threads to a serially reusable resource */ /* It should reside in the calling program and be properly */ /* initialized by the calling program. */ struct qcbtype { int state; /* 1 => Read and 2 => write and 0 free */ int numusing; /* Number of threads using the resource */ int numwaiting; /* Number of waiting threads */ pthread_mutex_t mtx; /* Mutex */ pthread_cond_t cv; /* Condition var. */ struct qeltype *qhead; /* Head of wait queue */ struct qeltype *qtail; /* Tail of wait queue. */ }; /* Function prototypes */ int enqueue( struct qcbtype *q, /* Pointer to QCB */ int action, /* READ or WRITE */ int tid); /* Thread id */ /* Function prototypes */ int dequeue( struct qcbtype *q, /* Pointer to QCB */ int tid); /* Thread id */