Task: Atomic Assembly
No, this section is not about nukes, sadly :(. Instead, we aim to get accustomed to the way in which the x86 ISA provides atomic instructions.
This mechanism looks very simple. It is but one instruction prefix: lock. It is not an instruction with its own separate opcode, but a prefix that slightly modifies the opcode of the following instructions to make the CPU execute it atomically (i.e. with exclusive access to the data bus).
lock must only be place before an instruction that executes a read-modify-write action. For example, we cannot place it before a mov instruction, as the action of a mov is simply read or write. Instead, we can place it in front of an inc instruction if its operand is memory.
Go in labs/lab-08/tasks/atomic-assembly/ and run:
make skels
Look at the code in labs/lab-08/tasks/atomic-assembly/support/src/race_condition_lock.asm. It’s an Assembly equivalent of the code you’ve already seen many times so far (such as labs/lab-08/tasks/race-condition/support/c/race_condition.c). The 2 assembly functions (increment_var and decrement_var) are called by race_condition_lock_checker.c
Now add the lock prefix before dec. Go in the tests/ folder and run the checker:
cd ../tests/
./checker.sh
You should see something like this, if done correctly:
Building the project...
nasm -f elf64 -o race_condition_lock.o race_condition_lock.asm
gcc -no-pie -o race_condition_lock_checker race_condition_lock_checker.c race_condition_lock.o -lpthread
Checking if var == 0...
Test passed
And now we have synchronized the two threads by leveraging CPU support.