Skip to content

Commit

Permalink
Merge pull request #182 from sifive/metal-lock-exp-backoff-1908
Browse files Browse the repository at this point in the history
Add an exponential backoff to lock acquisition
  • Loading branch information
nategraff-sifive authored Sep 10, 2019
2 parents 9c7955c + 51b69e0 commit a88919f
Showing 1 changed file with 20 additions and 1 deletion.
21 changes: 20 additions & 1 deletion metal/lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef METAL__LOCK_H
#define METAL__LOCK_H

#include <metal/machine.h>
#include <metal/memory.h>
#include <metal/compiler.h>

Expand All @@ -15,6 +16,9 @@
/* TODO: How can we make the exception code platform-independant? */
#define _METAL_STORE_AMO_ACCESS_FAULT 7

#define METAL_LOCK_BACKOFF_CYCLES 32
#define METAL_LOCK_BACKOFF_EXPONENT 2

/*!
* @def METAL_LOCK_DECLARE
* @brief Declare a lock
Expand Down Expand Up @@ -75,11 +79,26 @@ __inline__ int metal_lock_take(struct metal_lock *lock) {
int old = 1;
int new = 1;

while(old != 0) {
int backoff = 1;
const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES;

while(1) {
__asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])"
: [old] "=r" (old)
: [new] "r" (new), [state] "r" (&(lock->_state))
: "memory");

if (old == 0) {
break;
}

for (int i = 0; i < backoff; i++) {
__asm__ volatile("");
}

if (backoff < max_backoff) {
backoff *= METAL_LOCK_BACKOFF_EXPONENT;
}
}

return 0;
Expand Down

0 comments on commit a88919f

Please sign in to comment.