An atomic operation is an operation that will always be executed without any other process being able to read or change state that is read or changed during the operation. It is effectively executed as a single step, and is an important quality in a number of algorithms that deal with multiple indepent processes, both in synchronization and algorithms that update shared data without requiring synchronization.
Methods for ensuring an operation is atomic
Single processor-single core systems
On a single processor system, if an operation is implemented in a single CPU instruction, it is always atomic. Therefore it is safe to assume that operations like XCHG or INC are atomic on such systems.
If an operation requires multiple CPU instructions, then it may be interrupted in the middle of executing. If this results in a context switch (or if the interrupt handler refers to data that was being used) then atomicity could be compromised. It is possible to use any standard locking technique (e.g. a spinlock) to prevent this, but may be inefficient. If it is possible, disabling interrupts may be the most efficient method of ensuring atomicity (although note that this may increase the worst-case interrupt latency, which could be problematic if it becomes too long).
Multiprocessor or multicore systems
On multiprocessor systems, ensuring atomicity exists is a little harder. It is still possible to use a lock (e.g. a spinlock) the same as on single processor systems, but merely using a single instruction or disabling interrupts will not guarantee atomic access. You must also ensure that no other processor or core in the system attempts to access the data you are working with. The easiest way to achieve this is to ensure that the instructions you are using assert the 'LOCK' signal on the bus, which prevents any other processor in the system from accessing the memory at the same time. On x86 processors, some instructions automatically lock the bus (e.g. 'XCHG') while others require you to specify a 'LOCK' prefix to the instruction to achieve this (e.g. 'CMPXCHG', which you should write as 'LOCK CMPXCHG op1, op2').
A few of the Synchronization Primitives (sub)pages have implementations or examples of atomic operations. Besides that, GCC can make your life easier because it has built-in functions for them. You can take a look at the GCC Documentation.