5 /* Requirements 4 & 5 for Homework 09 indicate that you should modify the add
6 * and pop methods for the queue to provide for thread safety. If you modify
7 * the producer and consumer methods instead you will not receive full credit
8 * for the solution. Additionally, the due date for the homework is now
9 * Thursday to provide for the necessary modifications to fulfill requirements
10 * 4 & 5. Please note that you should NOT be using a global mutex. Any
11 * structures you use to protect the queue should be associated with the
12 * particular queue that is being used (the one given to the add/pop methods).
17 static void clear_node(queue_node_t
* node
)
21 clear_node(node
->next
);
26 static queue_node_t
* create_node(int value
)
28 queue_node_t
* node
= malloc(sizeof(queue_node_t
));
36 void queue_init(queue_t
* queue
)
40 queue
->mx_pop
= (pthread_mutex_t
*) calloc(1, sizeof(pthread_mutex_t
));
41 queue
->mx_push
= (pthread_mutex_t
*) calloc(1, sizeof(pthread_mutex_t
));
42 queue
->mx_valid_root
= (pthread_mutex_t
*) calloc(1, sizeof(pthread_mutex_t
));
43 queue
->valid_root
= (pthread_cond_t
*) calloc(1, sizeof(pthread_cond_t
));
45 pthread_mutex_init(queue
->mx_pop
, NULL
);
46 pthread_mutex_init(queue
->mx_push
, NULL
);
47 pthread_mutex_init(queue
->mx_valid_root
, NULL
);
49 pthread_cond_init(queue
->valid_root
, NULL
);
54 void queue_clear(queue_t
* queue
)
56 clear_node(queue
->root
);
59 free(queue
->valid_root
);
64 void queue_add(queue_t
* queue
, int value
)
66 pthread_mutex_lock(queue
->mx_push
);
67 pthread_mutex_lock(queue
->mx_valid_root
);
69 if (queue
->root
== NULL
)
71 queue
->root
= create_node(value
);
72 pthread_cond_signal(queue
->valid_root
);
73 pthread_mutex_unlock(queue
->mx_valid_root
);
77 pthread_cond_signal(queue
->valid_root
);
78 pthread_mutex_unlock(queue
->mx_valid_root
);
80 queue_node_t
* last
= queue
->root
;
81 while (last
->next
!= NULL
)
85 last
->next
= create_node(value
);
87 pthread_mutex_unlock(queue
->mx_push
);
92 int queue_pop(queue_t
* queue
)
94 if(queue
->root
== NULL
) {
96 pthread_mutex_lock(queue
->mx_valid_root
);
97 pthread_cond_wait(queue
->valid_root
, queue
->mx_valid_root
);
98 pthread_mutex_unlock(queue
->mx_valid_root
);
100 pthread_mutex_lock(queue
->mx_pop
);
101 queue_node_t
* temp
= queue
->root
->next
;
102 int value
= queue
->root
->value
;
105 pthread_mutex_unlock(queue
->mx_pop
);