lkml.org 
[lkml]   [2004]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectQuestions about memory barriers
I have a couple of questions regarding memory barriers.

The first question concerns read_barrier_depends(). I'm not sure exactly
what it does.

The documentation in include/asm-i386/system.h says:

* No data-dependent reads from memory-like regions are ever reordered
* over this barrier. All reads preceding this primitive are guaranteed
* to access memory (but not necessarily other CPUs' caches) before any
* reads following this primitive that depend on the data return by
* any of the preceding reads.

Taken at face value, this implies that all reads preceding
read_barrier_depends are guaranteed to access memory before the barrier
finishes. Even reads whose data is not used by a subsequent read. Is
this right?

Furthermore, the text's distinction of reads "that depend on the data
return[ed] by any of the preceding reads" is nearly meaningless. Almost
any read from a non-constant location could fall into that category.
Consider this example:

q = p;
<... millions of instructions ...>
read_barrier_depends();
d = *q;

How is the processor supposed to remember whether or not the value of q
depends on the earlier read of p? Obviously it can't, so it must assume
that such a dependency exists. Only if q had very recently been assigned
a constant value would the processor know otherwise.

Putting these ideas together, they amount to saying that
read_barrier_depends is just like rmb except that reads from a constant
location following the barrier are allowed to be moved before the barrier.
Have I missed anything?

The first code example in system.h is not informative. It says that this
code sequence:

q = p;
read_barrier_depends();
d = *q;

enforces ordering. But that means nothing; the ordering is already forced
by the C language definition. After all, it's impossible for the
processor to load data from *q before it knows what value is stored in q.

The other code example says that

y = b;
read_barrier_depends();
x = a;

enforces nothing since there is no dependency between the read of "b" and
the read of "a". But the other documentation doesn't require such a
dependency to exist; it only requires that the read of "a" depends on data
from a previous read -- which is quite likely unless "a" is a statically
allocated variable. Was that the intention? It's not clear; the example
seems to imply that read_barrier_depends enforces ordering only in
situations where the C language already enforces it.


My second question concerns guarantees about barriers and synchronization
primitives. It doesn't seem to be documented anywhere, but I would assume
the following statements are all true:

Acquiring a semaphore or spinlock implicitly includes a read
barrier.

Releasing a semaphore or spinlock implicitly includes a write
barrier.

Reading the value of an atomic_t implicitly includes a read
barrier.

Setting or changing the value of an atomic_t implicitly includes
a write barrier.

test_bit(), test_and_set_bit(), etc. implicitly include read
barriers.

set_bit(), clear_bit(), test_and_set_bit(), etc. implicitly
include write barriers.

Without some guarantees like these, the synchronization primitives would
be a lot harder to use. Are these statements in fact correct?

Alan Stern

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:06    [W:1.094 / U:0.012 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site