mini-rv32ima icon indicating copy to clipboard operation
mini-rv32ima copied to clipboard

Atomic instruction emulation

Open misterjdrg opened this issue 2 years ago • 6 comments

From riscv privileged spec:

3.1.8 Machine Trap Delegation Registers (medeleg and mideleg)

By default, all traps at any privilege level are handled in machine mode, though a machine-mode handler can redirect traps back to the appropriate level with the MRET instruction (Section 3.3.2).

Generally, linux runs in supervisor mode, and can't guarantee that machine mode interrupt doesn't happens in the middle of emulating atomic instruction

Proper implentation of atomic instructions would look something like this.

  1. Emulator encounters unknown instruction and emit Illegal instruction trap
  2. sbi implementation parses instruction and does emulation
   bool saved_mie = get_mie_from_mstatus();
   set_mie_in_mstatus(0);

   // atomic instruction emulation

   set_mie_in_mstatus(saved_mie);

Or you can embed same code directly into linux for better perf if:

  • linux runs in machine mode
  • system has one hart (core)

misterjdrg avatar Dec 07 '22 11:12 misterjdrg

Is this to be done on an individual instruction basis? I have to admit I don't fully understand the timing on when things are allowed to happen between loads and stores.

cnlohr avatar Dec 08 '22 18:12 cnlohr

Can this be done by just having a global flag of "I have a reservation!" and clearing it if there's an interrupt, and reporting failure to sc?

cnlohr avatar Dec 13 '22 01:12 cnlohr

Can this be done by just having a global flag of "I have a reservation!" and clearing it if there's an interrupt, and reporting failure to sc?

Yes, and them implement amo*_[w|d] instructions in terms of lr/sc loops. From spec:

We provided fetch-and-op style atomic primitives as they scale to highly parallel systems better
than LR/SC or CAS. A simple microarchitecture can implement AMOs using the LR/SC primi-
tives, provided the implementation can guarantee the AMO eventually completes.

misterjdrg avatar Dec 15 '22 07:12 misterjdrg

I don't need to do that. Because it's just one core (or we can control atomicity with an actual semaphore).

cnlohr avatar Dec 16 '22 01:12 cnlohr

Second question: No other memory accesses need to obey this, correct? So if I do have a global memory semaphore, it only needs to be used on RV32A?

cnlohr avatar Dec 16 '22 01:12 cnlohr

Just pasting this here:

i=1
while [ $i -le 10000 ]
do
  echo "Running 'ls' in the background, iteration $i"
  ls >/dev/null 2>&1 &
  i=$((i + 1))
done

cnlohr avatar May 04 '23 22:05 cnlohr