Xref: utzoo comp.lang.c:10277 comp.arch:4930 Path: utzoo!attcan!uunet!mcvax!ukc!cam-cl!scc From: scc@cl.cam.ac.uk (Stephen Crawley) Newsgroups: comp.lang.c,comp.arch Subject: Re: volatile (in comp.lang.c) Summary: it isn't just memory mapped I/O that needs volatile Message-ID: <199@gannet.cl.cam.ac.uk> Date: 20 May 88 01:45:06 GMT References: <20345@pyramid.pyramid.com> <833@mcdsun.UUCP> <9916@tekecs.TEK.COM> <2642@geac.UUCP> <2082@winchester.mips.COM> <1011@ima.ISC.COM> <166@iaoobelix.UUCP> Sender: news@cl.cam.ac.uk Reply-To: scc@cl.cam.ac.uk (Stephen Crawley) Organization: U of Cambridge Comp Lab, UK Lines: 47 Posted: Fri May 20 02:45:06 1988 In article <166@iaoobelix.UUCP> woerz@iaoobelix.UUCP (Dieter Woerz) writes: >In article <1011@ima.ISC.COM> johnl@ima.UUCP (John R. Levine) writes: >> .... I have never seen any suggestion that a program containing >>"volatile" would be portable except perhaps to other processors which happen >>to have similar memory, I/O, and hardware architectures. >> ... > >I don't see, what "volatile" has todo with the hardware architecture. >In my understanding, "volatile" simply says that the compiler has to >access the variable in the memory every time the variable is access- >ed. There seems to be nothing dependent on the hardware, exept that >you can't get access to I/O ports on architectures, which don't have >memory mapped I/O. So "volatile" has nothing todo with portability, >because every compiler can be made to access a variable in memory >every time it is read or writtten. > The "volatile" construct is also necessary to write portable multi-process applications that use shared memory. Consider two processes A and B with a shared variable v, and the following code int x = v /* A1 */ | v = 2 /* B1 */ int y = v /* A2 */ | Assume that v starts with the value 1, and that the statements are actually executed in the order A1,B1,A2. If the C compiler generates a memory fetch for each access to v, A's variables x and y will contain 1 and 2 respectively. If the compiler does not generate a memory fetch for each access, x and y will both contain 1. To get behaviour that is the same for all compilers, the variable v must be declared volatile. [It might be argued that if processes A and B ought were using some synchronisation mechanism (e.g. a Unix semaphore call after A1) and that an optimizing compiler would notice this and realise that statement A2 needed to have a fetch. I claim that such an argument is invalid. In some tightly coupled multiprocessor systems, shared memory cells are the basis for ALL synchronisation. If the compiler won't let me declare volatile variables, I can't implement synchronisation primitives. Even in a uniprocessor UNIX system, there are situations where it is better to use a shared variable for synchronising 2 processes rather than frittering away a couple of milli-seconds on semaphore system calls] -- Steve