1
/* Copyright 2013-2014 IBM Corp.
3
* Licensed under the Apache License, Version 2.0 (the "License");
4
* you may not use this file except in compliance with the License.
5
* You may obtain a copy of the License at
7
* http://www.apache.org/licenses/LICENSE-2.0
9
* Unless required by applicable law or agreed to in writing, software
10
* distributed under the License is distributed on an "AS IS" BASIS,
11
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
20
#include <processor.h>
24
/* Set to bust locks. Note, this is initialized to true because our
25
* lock debugging code is not going to work until we have the per
26
* CPU data initialized
28
bool bust_locks = true;
32
static void lock_error(struct lock *l, const char *reason, uint16_t err)
36
fprintf(stderr, "LOCK ERROR: %s @%p (state: 0x%016lx)\n",
37
reason, l, l->lock_val);
38
op_display(OP_FATAL, OP_MOD_LOCK, err);
43
static void lock_check(struct lock *l)
45
if ((l->lock_val & 1) && (l->lock_val >> 32) == this_cpu()->pir)
46
lock_error(l, "Invalid recursive lock", 0);
49
static void unlock_check(struct lock *l)
51
if (!(l->lock_val & 1))
52
lock_error(l, "Unlocking unlocked lock", 1);
54
if ((l->lock_val >> 32) != this_cpu()->pir)
55
lock_error(l, "Unlocked non-owned lock", 2);
57
if (l->in_con_path && this_cpu()->con_suspend == 0)
58
lock_error(l, "Unlock con lock with console not suspended", 3);
60
if (this_cpu()->lock_depth == 0)
61
lock_error(l, "Releasing lock with 0 depth", 4);
65
static inline void lock_check(struct lock *l) { };
66
static inline void unlock_check(struct lock *l) { };
67
#endif /* DEBUG_LOCKS */
69
bool lock_held_by_me(struct lock *l)
71
uint64_t pir64 = this_cpu()->pir;
73
return l->lock_val == ((pir64 << 32) | 1);
76
bool try_lock(struct lock *l)
80
this_cpu()->con_suspend++;
81
this_cpu()->lock_depth++;
87
void lock(struct lock *l)
100
void unlock(struct lock *l)
102
struct cpu_thread *cpu = this_cpu();
110
this_cpu()->lock_depth--;
113
if (l->in_con_path) {
115
if (cpu->con_suspend == 0 && cpu->con_need_flush)
120
bool lock_recursive(struct lock *l)
125
if (lock_held_by_me(l))
132
void init_locks(void)