diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2017-11-29 15:36:56 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-12-03 22:08:53 -0600 |
commit | 1486a08de557b8f237a066a57cc2c74961ba36e0 (patch) | |
tree | 493986a01191b9d5449fb43dc421a8ea7a1e1dc5 /core/lock.c | |
parent | 1e85912b921028bafa3a68fa286682a5d21a1223 (diff) | |
download | skiboot-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.c | 26 |
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; |