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

Why RISC-V up_testset use lr/sc and not amoswap? #6569

Closed
pkarashchenko opened this issue Jul 4, 2022 · 5 comments · Fixed by #12232
Closed

Why RISC-V up_testset use lr/sc and not amoswap? #6569

pkarashchenko opened this issue Jul 4, 2022 · 5 comments · Fixed by #12232

Comments

@pkarashchenko
Copy link
Contributor

pkarashchenko commented Jul 4, 2022

The RISC-V supports "Atomic Memory Operations" instructions. Seems like up_testset can be implemented with the less number of instruction using amoswap.w.aq/amoswap.w.rl than current implementation that use lr/sc instructions.

@xiaoxiang781216
Copy link
Contributor

@pkarashchenko
Copy link
Contributor Author

pkarashchenko commented Jul 4, 2022

@xiaoxiang781216 the issue is that currently it is implemented as you pointed, but it use lr/sc, but I posted an issue that we can rework it to use amoswap.
Current code:

  .globl up_testset
  .type  up_testset, %function

up_testset:

  li       a1, SP_LOCKED

  /* Test if the spinlock is locked or not */

retry:
  LR_INST  a2, (a0)       /* Test if spinlock is locked or not */
  beq      a2, a1, locked /* Already locked? Go to locked: */

  /* Not locked ... attempt to lock it */

  SC_INST  a2, a1, (a0)   /* Attempt to set the locked state (a1) to (a0) */
  bnez     a2, retry      /* a2 will not be zero, if sc.b failed, try again */

  /* Lock acquired -- return SP_UNLOCKED */

  fence                   /* Required before accessing protected resource */
  li        a0, SP_UNLOCKED
  jr        ra

  /* Lock not acquired -- return SP_LOCKED */

locked:
  li        a0, SP_LOCKED
  jr        ra
  .size	up_testset, . - up_testset
  .end

But can be something like

  .globl up_testset
  .type  up_testset, %function

up_testset:

  li       a1, SP_LOCKED
  amoswap.w a2, a1, (a0)  /* Attempt to acquire spinlock atomically */
  beq      a2, a1, locked /* Already locked? Go to locked: */

  /* Lock acquired -- return SP_UNLOCKED */

  fence                   /* Required before accessing protected resource */
  li        a0, SP_UNLOCKED
  jr        ra

  /* Lock not acquired -- return SP_LOCKED */

locked:
  li        a0, SP_LOCKED
  jr        ra
  .size	up_testset, . - up_testset
  .end

@xiaoxiang781216
Copy link
Contributor

Sorry, I misunderstand your meaning.

@pkarashchenko
Copy link
Contributor Author

Maybe my suggestion has some drawbacks compared to current implementation so I'm posting this as an issue so people some discussion may happen

@masayuki2009
Copy link
Contributor

@pkarashchenko
I remember I did the initial implementation for K210 SMP.
Actually, I referred to the armv7-a implementation that's why lr/sc are used for it.
However, I think amoswap instruction should work for up_testset.

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

Successfully merging a pull request may close this issue.

3 participants