-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial.h
163 lines (143 loc) · 4.79 KB
/
serial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*******************************************************************************
* File: serial.h
* Serializer. CSE 511 Project
*
* All parallel code are summed up in these two words: sem_wait and sem_post!
*
* Copyright (C) Oct.2015 Haibo, Chen
*
* This program is not free software: you can not redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, neither version 3 of the License, nor
* (at your option) any later version.
*
* This program is not distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You will not receive a copy of the GNU General Public License
* along with this program.
*
* Contact Information:
* Haibo <[email protected]>
* 111 IST, University Park, PA, 16302
*
******************************************************************************/
//#ifndef __SERIAL_HH__
//#define __SERIAL_HH__
#include <semaphore.h>
pthread_mutex_t s_mutex; // what is this mutex for? I suppose it is for serializer(chen)
//pthread_mutex_t q_mutex;//enter Q mutex
pthread_mutex_t waiting_mutex;
struct serial_t ;
/*enum kSERIALIZERSTATUS
{
kNOPROCESS = -1,
kPARENTPID = 0,
kOTHERPID = 1
};
*/
enum kHASITEM
{
kEMPTY = 1,
kNOTEMPTY = 0
};
enum kNUM_WAITING_Q{
kWAITINGQ0 = 0,
kWAITINGQ1 = 1,
kWAITINGQ2 = 2,
kWAITINGQN = 99
};
enum kDIRECTION
{
kUP = 0,
kDOWN = 1
};
struct crowd_t {
int count;
pthread_mutex_t c_mutex;
pthread_mutex_t s_mutex;
int *fork;
//pthread_mutex_t cylinder_mutex;
//int cylinder;
int total_count;
};
struct qnode {
pid_t tid;
sem_t sem; /**if I am the head, sem is 1*/
int priority; // large number with higher priority
struct qnode *next;
int current_cylinder;
};
struct queue_t {
sem_t sem;
struct serial_t * s;
struct qnode *_head;
struct qnode *_tail;
struct queue_t * (*enqueue)(struct serial_t * s, struct queue_t * q, int priority);
struct qnode * (*dequeue)(struct queue_t * q);
struct qnode * (*head)(struct queue_t * q);
int count;
pthread_mutex_t q_mutex;
int isHeadChanged;
};
struct queues_t {
struct queue_t *enter_queue;
struct queue_t *leave_crowd_queue;
struct queue_t *waiting_queue;
// waiting_queue is a pointer,
// to the queue of the second parameter Serial_Enqueue
struct queue_t **waiting_queues;
};
/**
* Here, we create three sets of queus.
* enter_quene:
* Threads waiting in this queue to gain serializer,
* after gain the serializer, goto waiting Q.
* waiting_queues:
* Can be spilted into two or more queues, e.g. (Read Waiting Q,
* Write Waiting Queue, etc.). Threads waiting in this queues
* is to gain serializer, after gain the serializer, goto
* wthe resource, that is, crowd.
* leave_crowd_queue:
* After using the crowd, go to this queue, waiting for serializer
* , and call Exit().
*/
struct serial_t {
struct queues_t * queues;
struct crowd_t *rd_crowd;
struct crowd_t *wr_crowd;
sem_t sem; // shared by enter_queue and leave_crowd_queue
sem_t count_sem;
int direction; // 0/kUP: up direction, from small to large
// 1/kDOWN: down direction, from large to small
int cylinder;
struct queue_t ** waitqs;
int nwqs;
};
typedef struct serial_t serial_t;
typedef struct queues_t queues_t;
typedef struct queue_t queue_t;
typedef struct crowd_t crowd_t;
typedef struct qnode qnode_t;
typedef int cond_t;
serial_t * Create_Serial(); //done(haibo, chen)
void Serial_Enter(serial_t *); //done(haibo, chen)
void Serial_Exit(serial_t *);
queue_t * Create_Queue(serial_t *);
crowd_t * Create_Crowd(serial_t *);
int Queue_Empty(serial_t *, queue_t *);
int Crowd_Empty(serial_t *, crowd_t *);
void Serial_Enqueue(serial_t *, queue_t *, cond_t (*func)(), int priority);
void Serial_Join_Crowd(serial_t *, crowd_t *, void *(*func)());
queue_t * queue_t_enqueue(serial_t * s, queue_t *q, int priority);
qnode_t * queue_t_dequeue(queue_t * q);
qnode_t * queue_t_head(queue_t * q);
queues_t* create_queues(serial_t * serializer, const int waiting_queue_number);
queue_t* create_queue(serial_t * serializer, int initial_sem);
void leave_serializer(serial_t * s, queue_t * target_q);
void leave_crowd(serial_t * s, int priority);
serial_t* gs;
//#endif
//__SERIAL_HH__