(void)ing unreferenced parameters
Nathan Sidwell
nathan@acm.org
Wed Jun 30 23:07:00 GMT 1999
Martin Dorey wrote:
> > fields of that struct to strobe something I understand. I find it hard
> to
> > understand why you'd dink the *whole* struct in one go. But I'm not
> suggesting
> > gratuitously banning it.
>
> Scenario: you want to read several registers from a device in a loop,
> whose values all change each time you frob the device - once per loop
> iteration. You have to use volatile, to ensure the dereference doesn't
> get hoisted out of the loop. You can get the whole struct at once,
> because you know the device's registers won't change except when you
> frob it. You want to get the whole struct at once, because sequential
> memory accesses are more efficient, perhaps because of memory pipelining
> or because the compiler might then be able to read several byte-wide
> registers with a word-read.
You've changed the ground rules.
I said that given
struct dev {int reg1; int reg2};
volatile dev *device = someptr;
I found it hard to understand what you would expect
*device;
to do. The most you can expect it to do is read the locations and ignore the
result (You'd be wrong for C++, as the read should not happen.) Why would you
do this? The _only_ reason must be that a read had a side effect of changing
the device's state. In which case you need to be absolutely certain in which
order and with which atomicity the device's registers were accessed. There are
no guarentees in reading an entire struct in one go.
You give an example where you do
while(whenever) {
dev copy = *device; // doesn't change state
... do something
device->reg1 = somecommand; // change device's state
}
You'd like `copy = *device' to happen in one go for efficiency. You lose.
You can say to the compiler either a) this object behaves just like memory (not
volatile qualified), b) this object does not behave just like memory
(volatile).
What you wanted to say is c) reads can be combined and reordered wrt reads, but
writes cannot be reordered or combined.
Hardware cache control and memory interfaces generally give only a and b too.
not c.
If you want it read in one go you might try
memcpy(©, device, sizeof(dev));
and hope the compiler inlines it (egcs should do). or
copy = *(dev *)device;
but I'm not sure how legal that is and how it might interfere with type based
alias analysis. If `dev' and `volatile dev' are treated as different types,
you've now given the compiler license to reorder the reads with the write and
all bets are off.
> Scenario: you want to save the whole state of the device in one go.
> Again, you need to be sure that you're going to read a consistent state.
You've changed the ground rules *again*. In the example you gave, you wanted to
get the thing on one go for *efficiency*. Now you're saying you need to get it
in one go for *consistency*. If this is the case you've now reverted to a
device where a read changes its state. This is an even worse situation and
there's no way to tell the compiler both
1) don't rearrange reads because they do something strange (volatile)
2) you have to combine (i.e. rearrange) these reads
there might be *no* way to atomically read the locations.
nathan
--
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
I have seen the death of PhotoShop -- it is called GIMP
nathan@acm.org http://www.cs.bris.ac.uk/~nathan/ nathan@cs.bris.ac.uk
More information about the Gcc-bugs
mailing list