static inline void set_bit(int nr, volatile unsigned long * addr) {

_asm__volatile_( LOCK_PREFIX

"btsl %1,%0" :"+m" (ADDR) :"Ir" (nr));

bts stands for the assembler statement ''bit test and set,'' which queries the value of a given bit in a long value, stores the value in the CF flag of the processor, and then sets the bit to one. Because long values comprise 32 bits, the bit position can be specified by means of a constant in the range 0..31, which is why the constraint type I is used. The position must also be specified in a register as required by the architecture — in this case, the r constraint is used.

Because the processed data resides in memory and is modified by a write access, the constraint +m must be used for the long value.

The pre-processor constant lock_prefix is used to make the operation atomic. On single-processor systems, this constant is empty because a single assembly statement that cannot be interrupted is used to set the bit. On SMP systems, the constant expands to lock. This is a separate assembler statement, known as a lock prefix, which prevents all other processors of the system from interfering with the following statement, and thus makes it atomic.

Naturally, not only individual assembler statements are used in inline code. For example, atomic incrementing of an integer variable is a complex operation on Alpha CPUs as shown here:

Continue reading here: Includeasmalphaatomich

Was this article helpful?

0 0