Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership | k5 store

[P]
Programming Challenge (Diaries)

By llimllib
Mon Feb 16th, 2004 at 12:36:19 PM EST

llimllib's Diary

Think you know about mutexes and semaphores? Read on!


Semaphores are pretty simple, right? Atomically decrement and test an integer to see if it's locked, atomically increment it to unlock. The P() operation should do the decrementing, and the V() the incrementing. (Dijkstra, the crazy Dutch, defined these operation names to bee Pass and Release, or something like that).

The following implementations of P() and V() are given as the correct ones in my OS textbook. My classmates and I have all discovered that they are not; indeed, P() and V() as given here deadlock. Your task is to help me figure out why. The C code:

pthread_mutex_t mutex_s = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t delay_s = PTHREAD_COND_INITIALIZER;

void P(int &s) {
  pthread_mutex_lock(&mutex_s);
  if(--s<0) pthread_cond_wait(&delay_s, &mutex_s);
  pthread_mutex_unlock(&mutex_s);
}

void V(int &s) {
  pthread_mutex_lock(&mutex_s);
  ++s <= 0 ? pthread_cond_signal(&delay_s) : pthread_mutex_unlock(&mutex_s);
}

The code I'm using that creates the deadlock simply creates two threads which attempt to use P() and V() as a binary lock around the update of a global variable. I will post it upon request.

Sponsors
Voxel dot net
o Managed Servers
o Managed Clusters
o Virtual Hosting


Collocated Linux/FreeBSD Server
As low as $45/month
o Root on your own FreeBSD or Linux server
o Very fast, triple-homed network
o NO hardware or setup fees, unlimited support
Testimonials from K5 Users

Login
Make a new account
Username:
Password:

Note: You must accept a cookie to log in.

Related Links
o llimllib's Diary


View: Display: Sort:
Programming Challenge | 17 comments (17 topical, 0 editorial, 0 hidden)
P and V (none / 1) (#15)
by sesquiped on Mon Feb 16th, 2004 at 03:05:22 PM EST

His P and V don't stand for any English words, but instead for a made-up quasi-Dutch word, "prolagen" (which might mean something like "try to decrease") and a real Dutch word "verhogen" ("increase").

Additionally, (none / 3) (#17)
by it certainly is on Mon Feb 16th, 2004 at 03:17:55 PM EST
http://www.kyz.uklinux.net/

it's proberen, not prolagen.

kur0shin.org -- it certainly is

Godwin's law [...] is impossible to violate except with an infinitely long thread that doesn't mention nazis.
[ Parent ]

Procure and Vacate (none / 2) (#16)
by it certainly is on Mon Feb 16th, 2004 at 03:13:20 PM EST
http://www.kyz.uklinux.net/

are very well known names for obtaining and releasing semaphores or mutexes.

kur0shin.org -- it certainly is

Godwin's law [...] is impossible to violate except with an infinitely long thread that doesn't mention nazis.
[ Parent ]

How 'bout this: (none / 1) (#11)
by Mr.Surly on Mon Feb 16th, 2004 at 01:45:06 PM EST


// wait
void P(int &s) {
  pthread_mutex_lock(&mutex_s);
  while(s == 0)
   pthread_cond_wait(&delay_s, mutex_s);
  s--;
  pthread_mutex_unlock(&mutex_s);
}

//post
void V(int &s) {
  pthread_mutex_lock(&mutex_s);
  if (++s > 0)
   pthread_cond_signal(&delay_s);
  pthread_mutex_unlock(&mutex_s);
}

yup, you implemented awgsilari's changes (none / 0) (#14)
by llimllib on Mon Feb 16th, 2004 at 01:55:55 PM EST
(llimllib at f2o .. org)

basically, i had else unlock; instead of unlock;. I thought that P() would release the lock on mutex_s after the wait, but it block until mutex_s is released, which is a problem.

Peace.
[ Parent ]
HA HA THATS C++! (none / 1) (#8)
by noogie on Mon Feb 16th, 2004 at 01:38:40 PM EST
(noogie.brownATgmail.com)




I'm smarter than the average bear.
oh yeah (none / 0) (#9)
by llimllib on Mon Feb 16th, 2004 at 01:41:13 PM EST
(llimllib at f2o .. org)

I forgot to remove the passes by reference. I translated from the C++, which I coded in, to C for simplicity's sake, but I missed that.

Thanks for pointing it out.

Peace.
[ Parent ]

Dunno, (none / 1) (#3)
by gabban on Mon Feb 16th, 2004 at 01:03:12 PM EST

never did any posix programming, but...
The pthread_cond_wait() function blocks on the specified condition variable, which atomically releases the specified mutex and causes the calling thread to block on the condition variable

Wouldn't this make your P() to release the lock twice if it has to wait on s?
And would the mutex be released in V() if the predicate is true?

No. (none / 1) (#4)
by awgsilyari on Mon Feb 16th, 2004 at 01:05:54 PM EST
(moc.wnlaruen@ttocs)

Wouldn't this make your P() to release the lock twice if it has to wait on s?

No. pthread_cond_wait() reacquires the mutex before it returns.

And would the mutex be released in V() if the predicate is true?

No. And that's the bug. P() is okay, though.

--------
Please direct SPAM to john@neuralnw.com
[ Parent ]

The bug is in V() (none / 3) (#2)
by awgsilyari on Mon Feb 16th, 2004 at 12:58:36 PM EST
(moc.wnlaruen@ttocs)

The code doesn't unlock the mutex after signalling the condition.

--------
Please direct SPAM to john@neuralnw.com
damn, that does work (none / 0) (#6)
by llimllib on Mon Feb 16th, 2004 at 01:31:31 PM EST
(llimllib at f2o .. org)

thanks. I still don't understand why it doesn't get unlocked in P() after the signal, though.

Peace.
[ Parent ]
Conditional operator (none / 1) (#10)
by CwazyWabbit on Mon Feb 16th, 2004 at 01:44:30 PM EST

That line is (expr) ? (foo) : (bar) so if the expression is true, the mutex unlock will never be called.

It would be clearer if written as an explicit "if" statement.
--
"But here's the thing: if people hand me ammunition, what kind of misanthrope would I be if I didn't use it?" - Sarah-Katherine
[ Parent ]

I changed it for compactness (none / 0) (#12)
by llimllib on Mon Feb 16th, 2004 at 01:53:32 PM EST
(llimllib at f2o .. org)

it's an if() in my original code, but formatting code for K5 is a pain.

I knew that the unlock wasn't getting called, but I thought that it got called in the P() function after the wait got unblocked. I didn't know that the wait needed to reacquire the lock on the mutex to unblock.

Peace.
[ Parent ]

Because (none / 1) (#7)
by awgsilyari on Mon Feb 16th, 2004 at 01:38:07 PM EST
(moc.wnlaruen@ttocs)

In P, after getting woken up, pthread_cond_wait() has to regain in the mutex before returning. What is happening is that V() is waking up the waiter, which immediately blocks waiting for the mutex. This is deadlock, because the V() routine never released it.

Remember, to wait, you: LOCK; while(!cond) WAIT; UNLOCK;

To wake, you: LOCK; SIGNAL; UNLOCK;

You can get away with an if(--s<0) instead of a while in P(), because you aren't using pthread_cond_broadcast in V(). However it's good practice to always use a while() instead of an if(), to guard a wakeup.

--------
Please direct SPAM to john@neuralnw.com
[ Parent ]

thanks a lot (none / 0) (#13)
by llimllib on Mon Feb 16th, 2004 at 01:54:37 PM EST
(llimllib at f2o .. org)

I get it now. Enlightenment has ensued.

Peace.
[ Parent ]
but that's the next statement in P() (none / 0) (#5)
by llimllib on Mon Feb 16th, 2004 at 01:25:30 PM EST
(llimllib at f2o .. org)

when the condition variable gets signalled, doesn't it hit the unlock_mutex at the end of p()?

Peace.
[ Parent ]
Strip all unnecessary code.. (none / 0) (#1)
by dublet on Mon Feb 16th, 2004 at 12:52:01 PM EST
(dDuUbBlLeEtT aATt DdUuBbLlEeTt DdOoTt OorRgG) http://dublet.org:8083/

to create the simplest example where it still exists, and the used platform, including thread library.

Badger. Badger. ←
Programming Challenge | 17 comments (17 topical, 0 editorial, 0 hidden)
View: Display: Sort:

kuro5hin.org

[XML]
All trademarks and copyrights on this page are owned by their respective companies. The Rest © 2000 - 2003 Kuro5hin.org Inc.
See our legalese page for copyright policies. Please also read our Privacy Policy.
Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
Need some help? Email help@kuro5hin.org.
Erik Benson is a deadbeat.

Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories! K5 Store by Jinx Hackwear Syndication Supported by NewsIsFree