aboutsummaryrefslogtreecommitdiff
path: root/core/lock.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-11-29 15:36:56 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-03 22:08:53 -0600
commit1486a08de557b8f237a066a57cc2c74961ba36e0 (patch)
tree493986a01191b9d5449fb43dc421a8ea7a1e1dc5 /core/lock.c
parent1e85912b921028bafa3a68fa286682a5d21a1223 (diff)
downloadskiboot-1486a08de557b8f237a066a57cc2c74961ba36e0.zip
skiboot-1486a08de557b8f237a066a57cc2c74961ba36e0.tar.gz
skiboot-1486a08de557b8f237a066a57cc2c74961ba36e0.tar.bz2
core/lock: Introduce atomic cmpxchg and implement try_lock with it
cmpxchg will be used in a subsequent change, and this reduces the amount of asm code. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> [stewart: fix some ifdef __TEST__ foo to ensure unittests work] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core/lock.c')
-rw-r--r--core/lock.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/core/lock.c b/core/lock.c
index 0868f2b..916a024 100644
--- a/core/lock.c
+++ b/core/lock.c
@@ -33,7 +33,7 @@ static void lock_error(struct lock *l, const char *reason, uint16_t err)
{
bust_locks = true;
- fprintf(stderr, "LOCK ERROR: %s @%p (state: 0x%016lx)\n",
+ fprintf(stderr, "LOCK ERROR: %s @%p (state: 0x%016llx)\n",
reason, l, l->lock_val);
op_display(OP_FATAL, OP_MOD_LOCK, err);
@@ -73,12 +73,30 @@ bool lock_held_by_me(struct lock *l)
return l->lock_val == ((pir64 << 32) | 1);
}
+static inline bool __try_lock(struct cpu_thread *cpu, struct lock *l)
+{
+ uint64_t val;
+
+ val = cpu->pir;
+ val <<= 32;
+ val |= 1;
+
+ barrier();
+ if (__cmpxchg64(&l->lock_val, 0, val) == 0) {
+ sync();
+ return true;
+ }
+ return false;
+}
+
bool try_lock(struct lock *l)
{
- if (__try_lock(l)) {
+ struct cpu_thread *cpu = this_cpu();
+
+ if (__try_lock(cpu, l)) {
if (l->in_con_path)
- this_cpu()->con_suspend++;
- this_cpu()->lock_depth++;
+ cpu->con_suspend++;
+ cpu->lock_depth++;
return true;
}
return false;