Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atomic instruction emulation #10

Open
misterjdrg opened this issue Dec 7, 2022 · 6 comments
Open

Atomic instruction emulation #10

misterjdrg opened this issue Dec 7, 2022 · 6 comments

Comments

@misterjdrg
Copy link

misterjdrg commented Dec 7, 2022

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)
@cnlohr
Copy link
Owner

cnlohr commented Dec 8, 2022

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
Copy link
Owner

cnlohr commented Dec 13, 2022

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?

@misterjdrg
Copy link
Author

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.

@cnlohr
Copy link
Owner

cnlohr commented Dec 16, 2022

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

@cnlohr
Copy link
Owner

cnlohr commented Dec 16, 2022

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
Copy link
Owner

cnlohr commented May 4, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants