Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Oct 2000 18:02:25 -0400 (EDT)
From:      Bosko Milekic <bmilekic@dsuper.net>
To:        Terry Lambert <tlambert@primenet.com>
Cc:        arch@FreeBSD.ORG
Subject:   Re: Mutexes and semaphores
Message-ID:  <Pine.BSF.4.21.0010101727590.8297-100000@jehovah.technokratis.com>
In-Reply-To: <20001010181621.M87663@wantadilla.lemis.com>

next in thread | previous in thread | raw e-mail | index | archive | help

  This is not aimed at anyone in particular;
  Appologies to those trimmed in the To: and Cc: fields.

On Tue, 10 Oct 2000, Greg Lehey wrote:

> >>> The most obvious argument is still that a mutex is intended to
> >>> protect data, not code.  Recursion is only required if the mutex
> >>> is actually protecting reentrancy of code, not access to data.

	I don't recall who originally stated this, but this is not exactly
  correct. Well, I suppose it is exactly correct in an exactly perfect
  world. While I do agree that recursion is typical when the mutex is
  protecting reentrancy of code (although, I gotta tell you, I find this to
  be more of a "feature" in some cases -- more below), recursion also
  happens even if the mutex is not only serving to protect reentrancy. This
  probably sounds twisted, so here (I hope this turns out looking alright):

  (execution path is counter-clockwise, starting from [Subsystem A])
  (when I mention "lock" or "mutex" it is in reference to a mutex
  protecting some data which lives in [Subsystem A code])

  [Subsystem A] -------------- [Subsystem A code]--------------
       |                                                      |
 [routine (a) that makes                     [ routine (b) that makes use
   use of Subsystem B code]                     of Subsystem A code ]
       |                                              |
	 -----[Subsystem B] ----- [some generic routine (c) that is an
	                           integral part of Subsystem B]

  1) [Subsystem A] makes use of a local routine, which acquires a lock, and
     ends up having to call routine (a); it cannot release the lock because
     then there would be a potential race condition.

  2) routine (a) does some neat stuff (the mutex is still held here) and
  then calls one of its own routines, call it routine (c), residing in the
  "integral part of Subsystem B" code.

  3) routine (c) is a general routine, in the sense that it can have points
  of entry from several different parts of [Subsystem B], at least. Routine
  (c) happens to call routine (b) (see schematic above to understand) which
  accesses the same data as [Subsystem A] was touching. So it acquires the
  lock recursively. Does its stuff, and returns.

  Okay, so the issues are clear, and you may be thinking:

  * (c) in point 3) is WRONG, it should be calling a lower-level routine
  (b) which doesn't acquire the lock. The problem with this "solution,"
  though, is also mentionned in point 3): Routine (c) is a "general"
  routine, in some cases, it HAS to aquire the lock. So you can't just have
  it not aquire the lock at all, because then those cases would be flawed.
  Splitting all these instances on a case by case basis is a recipe for
  disaster.

  * "Again, code reentry, not data, is being protected here." This argument
  unfortunately touches on a very sensitive issue; the difference here is a
  fine line. See, if you want to argue that locks should serve to protect
  "data" across subsystems, you're going to have a hard time doing it,
  mainly because in most cross-subsystem cases, the "data" will be
  manipulated by routines (code) and so you may draw the inference that if
  the lock needs to be aquired that it is the "code" that is being
  protected, but this is just an abstraction, and you _are_ in fact
  protecting the data.

	To just quickly touch on the issue I raised in the first paragraph
  above; about how I find the fact that sometimes the mutex can be used to
  protect code reentrancy as well as data a "feature." Basically, I find
  this neat only when the lock needs to be acquired to protect data as well,
  but the code surrounding it, which is the only code manipulating this
  data, also has one or two calls that need not be re-entrant; then,
  aquiring the same mutex just one statement above is neat, because things
  are much less "bloated" this way (as opposed to using an entirely
  separate mechanism to prevent reentrancy).

> I suppose I should have left this last paragraph of the quote out.
> The intention of mutexes is left to the programmer.  While I agree
> that I'd rather use them to protect data than code, there's nothing in
> the nature of a mutex that requires that.

	I agree with both points raised above.

[...]

> Greg
> --
> Finger grog@lemis.com for PGP public key
> See complete headers for address and phone numbers

  Cheers,
  Bosko Milekic
  bmilekic@technokratis.com




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0010101727590.8297-100000>