Path: utzoo!mnetor!uunet!husc6!uwvax!oddjob!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: volatile Message-ID: <11049@mimsy.UUCP> Date: 13 Apr 88 16:42:56 GMT References: <4522@bloom-beacon.MIT.EDU> <1103@pur-phy> <49255@sun.uucp> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 85 >> extern volatile int user_interrupt; >> while (!user_interrupt) >> sleep(1); In article <49255@sun.uucp> limes@sun.uucp (Greg Limes) writes: >Please do not misunderstand me, I would like to see "volatile" >added -- but why would it be required above? If "user_interrupt" >is an external variable, then the compiler is not free to assume >that it will not change across a function call. The compiler *is* free to make that assumption if it examines the function and finds that it does not write into user_interrupt. For instance, if `sleep' is implemented as (say) typedef unsigned long u_long; sleep(unsigned n) { static volatile u_long *const timerp = (u_long *)0xfc000040; register u_long expect = *timerp + n; while (*timerp < expect) /*void*/; } and the code for sleep is stored in some format that the compiler can read, then the compiler can see that sleep cannot change user_interrupt. The main problem with volatile is that it does not have well- defined semantics. It *cannot* have well-defined semantics. Consider a load/store architecture versus a Vax-like architecture. If I write volatile char c; ... c++; the load/store machine must generate something like movbl _c,r212 addl #1,r212 movlb r212,_c which is one read and one write; the Vax-like machine just runs incb _c which is one read/modify/write. The reason volatile exists is because it is a machine-independent means of specifying something that is inherently machine-dependent but which affects every implementation that does what might be called `nonobvious optimisation'. Like the size of `pointer_t' (void *) or the length of `size_t', volatile is a machine- and compiler-dependent construct that can be used to give machine- and compiler-independent results: #include semaphore_t sem; ... SEM_LOCK(&sem); ... SEM_UNLOCK(&sem); where might say typedef volatile int semaphore_t; #define SEM_LOCK(semp) while ((*semp)++) --*(semp) #define SEM_UNLOCK(semp) --*(semp) or it might say instead typedef volatile short semaphore_t; #define SEM_LOCK(semp) \ while (_builtin_test_and_set(semp)) \ _builtin_atomic_clear(semp) #define SEM_UNLOCK(semp) _builtin_atomic_clear(semp) or any of a number of other possibilities. What `volatile' DOES is machine-dependent. What `volatile' EXPRESSES (`hands off! this is a weird object!') is not, or not entirely. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris