I'm coding something using direct control of GPIO, there are some good resources around for this, such as http://elinux.org/RPi_Low-level_peripherals#GPIO_hardware_hacking ; the process involves open("/dev/mem") and then a mmap operation effectively maps the desired physical address into your virtual address space. Then you read section 6 of this http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf to find out about how the I/O are controlled.
To change to the function of a pin (input, or output, or various special functions) you modify these 3-bit fields in the GPFSELx I/O registers (000=input, 001= output foe instance). These modification operations are compiled to operations with ordinary load and store (e.g. to change GPIO0 to input: *(regptr) &= ~7; which compiles to something like
ldr r2, [r3, #0] ; r = *ptr (load r2 from I/O register) bic r2, r2, #7 ; r2 &= ~7 str r2, [r3, #0] ; *ptr = r2 (store r2 to I/O register)
The problem is this: if an interrupt occurs between the load and store, and another process or ISR modifies the same I/O register, the store operation (based on a stale read into r2) will revert the effects of that other operation. So changing these I/O registers really needs to done with an atomic (locked) read/modify/write operation. The examples I've seen do not use a locked operation.
Since these I/O registers are generally changed only when setting something up, it's unlikely that problems will occur, but 'never' is always better than 'unlikely'. Also, if you have an application where you are bit-bashing to emulate an open-collector output, then (as far as I can tell) this involves programming the output to 0 and then switching it between output (for low) or input (for off/high). So in that case there would be frequent mods to these I/O registers, and unsafe modifications would be far more likely to cause a problem.
So, there's probably an ARM 'compare and set' or similar operation which can be used here to do this, can anyone point me to that, and how to make that happen from C code?
[Note, nothing special is needed when you have programmed an I/O as output and are just changing it from 0 to 1 or vice versa; since there is an I/O register you write to, to set selected bits to 1 and another to clear selected bits to 0. No read/write is needed for this operation, thus there is no hazard from interrupts].