b. Ben's second attempt uses two global semaphores. One, sem_t qlock, is initialized to 1 and enforces mutual exclusion while the linked list is being updated. The other, sem_t waitchan is initialized to 0, and is used to signal blocked threads when the queue transitions from empty to nonempty. Now Ben's code for pq_next() does this: P(qlock); // begin critical section while (list_head==NULL) { V(qlock); // release lock P(waitchan); // block if queue is empty P(qlock); } // re-acquire lock ... // remove first item from list V(qlock); // end critical section and pq_insert() does P(qlock); // enter critical section ... // insert item into queue, possibly making list_head non-NULL V (waitchan); // increment size count, awaken one sleeping thread V(qlock); // leave critical section Is this version correct? If you say no, indicate precisely what can go wrong, and show the interleaving of steps that leads to it. If you say yes, how does this code avoid the problem that requires that the lock be released and the thread be suspended simultaneously and atomically in pthread_cond_wait-that is, the danger of the notification arriving in between the thread releasing the lock and suspending, so that it blocks forever?

Computer Networking: A Top-Down Approach (7th Edition)
7th Edition
ISBN:9780133594140
Author:James Kurose, Keith Ross
Publisher:James Kurose, Keith Ross
Chapter1: Computer Networks And The Internet
Section: Chapter Questions
Problem R1RQ: What is the difference between a host and an end system? List several different types of end...
icon
Related questions
Question
b. Ben's second attempt uses two global semaphores. One, sem_t qlock, is initialized to 1 and
enforces mutual exclusion while the linked list is being updated. The other, sem_t waitchan
is initialized to 0, and is used to signal blocked threads when the queue transitions from empty
to nonempty. Now Ben's code for pq_next() does this:
P(qlock); // begin critical section
while (list_head==NULL) {
V(qlock); // release lock
P(waitchan); // block if queue is empty
P(qlock);
}
// re-acquire lock
... // remove first item from list
V(qlock); // end critical section
and pq_insert() does
P(qlock); // enter critical section
... // insert item into queue, possibly making list_head non-NULL
V (waitchan); // increment size count, awaken one sleeping thread
V(qlock); // leave critical section
Is this version correct? If you say no, indicate precisely what can go wrong, and show the
interleaving of steps that leads to it. If you say yes, how does this code avoid the problem that
requires that the lock be released and the thread be suspended simultaneously and atomically
in pthread_cond_wait that is, the danger of the notification arriving in between the thread
releasing the lock and suspending, so that it blocks forever?
Transcribed Image Text:b. Ben's second attempt uses two global semaphores. One, sem_t qlock, is initialized to 1 and enforces mutual exclusion while the linked list is being updated. The other, sem_t waitchan is initialized to 0, and is used to signal blocked threads when the queue transitions from empty to nonempty. Now Ben's code for pq_next() does this: P(qlock); // begin critical section while (list_head==NULL) { V(qlock); // release lock P(waitchan); // block if queue is empty P(qlock); } // re-acquire lock ... // remove first item from list V(qlock); // end critical section and pq_insert() does P(qlock); // enter critical section ... // insert item into queue, possibly making list_head non-NULL V (waitchan); // increment size count, awaken one sleeping thread V(qlock); // leave critical section Is this version correct? If you say no, indicate precisely what can go wrong, and show the interleaving of steps that leads to it. If you say yes, how does this code avoid the problem that requires that the lock be released and the thread be suspended simultaneously and atomically in pthread_cond_wait that is, the danger of the notification arriving in between the thread releasing the lock and suspending, so that it blocks forever?
Problem 2. In Project 6 you are required to use pthreads condition variables and mutexes to
synchronize accesses to shared variables in your priority queue implementation. Ben Bitdiddle wants
to try (on his own) to do it using semaphores instead. As in Project 6, the “next" operation returns
the highest-priority item in the queue; if the queue is empty, it blocks until the queue becomes
non-empty. The “insert" operation places an item in the queue, and if the queue went from empty
to non-empty, it signals any waiting threads. Ben's implementation uses a (global) semaphore to
count the number of items in the queue, and uses the Bryant and O'Hallaron "P()" and "V()"
wrapper functions (see text) to decrement and increment it. He declares a global sem_t list_size
and initializes it with sem_init(&list_size,0,0). The global variable list_head points to the
first item in the list and is initially NULL.
a. In Ben's first attempt, the pq_next() function does this:
P(list_size); // block until list is nonempty, i.e., list_size > 0
// Update list: remove and return highest-prio item, update list
Meanwhile, the pq_insert() function does this:
// update list:
V(list_size);
insert item into the linked list
Ben's code is incorrect. What's wrong with it?
Transcribed Image Text:Problem 2. In Project 6 you are required to use pthreads condition variables and mutexes to synchronize accesses to shared variables in your priority queue implementation. Ben Bitdiddle wants to try (on his own) to do it using semaphores instead. As in Project 6, the “next" operation returns the highest-priority item in the queue; if the queue is empty, it blocks until the queue becomes non-empty. The “insert" operation places an item in the queue, and if the queue went from empty to non-empty, it signals any waiting threads. Ben's implementation uses a (global) semaphore to count the number of items in the queue, and uses the Bryant and O'Hallaron "P()" and "V()" wrapper functions (see text) to decrement and increment it. He declares a global sem_t list_size and initializes it with sem_init(&list_size,0,0). The global variable list_head points to the first item in the list and is initially NULL. a. In Ben's first attempt, the pq_next() function does this: P(list_size); // block until list is nonempty, i.e., list_size > 0 // Update list: remove and return highest-prio item, update list Meanwhile, the pq_insert() function does this: // update list: V(list_size); insert item into the linked list Ben's code is incorrect. What's wrong with it?
Expert Solution
steps

Step by step

Solved in 2 steps

Blurred answer
Recommended textbooks for you
Computer Networking: A Top-Down Approach (7th Edi…
Computer Networking: A Top-Down Approach (7th Edi…
Computer Engineering
ISBN:
9780133594140
Author:
James Kurose, Keith Ross
Publisher:
PEARSON
Computer Organization and Design MIPS Edition, Fi…
Computer Organization and Design MIPS Edition, Fi…
Computer Engineering
ISBN:
9780124077263
Author:
David A. Patterson, John L. Hennessy
Publisher:
Elsevier Science
Network+ Guide to Networks (MindTap Course List)
Network+ Guide to Networks (MindTap Course List)
Computer Engineering
ISBN:
9781337569330
Author:
Jill West, Tamara Dean, Jean Andrews
Publisher:
Cengage Learning
Concepts of Database Management
Concepts of Database Management
Computer Engineering
ISBN:
9781337093422
Author:
Joy L. Starks, Philip J. Pratt, Mary Z. Last
Publisher:
Cengage Learning
Prelude to Programming
Prelude to Programming
Computer Engineering
ISBN:
9780133750423
Author:
VENIT, Stewart
Publisher:
Pearson Education
Sc Business Data Communications and Networking, T…
Sc Business Data Communications and Networking, T…
Computer Engineering
ISBN:
9781119368830
Author:
FITZGERALD
Publisher:
WILEY