aboutsummaryrefslogtreecommitdiff
path: root/include/lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lock.h')
-rw-r--r--include/lock.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/include/lock.h b/include/lock.h
new file mode 100644
index 0000000..f24e769
--- /dev/null
+++ b/include/lock.h
@@ -0,0 +1,83 @@
+/* Copyright 2013-2014 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LOCK_H
+#define __LOCK_H
+
+#include <stdbool.h>
+
+struct lock {
+ /* Lock value has bit 63 as lock bit and the PIR of the owner
+ * in the top 32-bit
+ */
+ unsigned long lock_val;
+
+ /*
+ * Set to true if lock is involved in the console flush path
+ * in which case taking it will suspend console flushing
+ */
+ bool in_con_path;
+};
+
+/* Initializer */
+#define LOCK_UNLOCKED { .lock_val = 0, .in_con_path = 0 }
+
+/* Note vs. libc and locking:
+ *
+ * The printf() family of
+ * functions use stack based t buffers and call into skiboot
+ * underlying read() and write() which use a console lock.
+ *
+ * The underlying FSP console code will thus operate within that
+ * console lock.
+ *
+ * The libc does *NOT* lock stream buffer operations, so don't
+ * try to scanf() from the same FILE from two different processors.
+ *
+ * FSP operations are locked using an FSP lock, so all processors
+ * can safely call the FSP API
+ *
+ * Note about ordering:
+ *
+ * lock() is a full memory barrier. unlock() is a lwsync
+ *
+ */
+
+extern bool bust_locks;
+
+static inline void init_lock(struct lock *l)
+{
+ l->lock_val = 0;
+ l->in_con_path = false;
+}
+
+extern bool __try_lock(struct lock *l);
+extern bool try_lock(struct lock *l);
+extern void lock(struct lock *l);
+extern void unlock(struct lock *l);
+
+/* The debug output can happen while the FSP lock, so we need some kind
+ * of recursive lock support here. I don't want all locks to be recursive
+ * though, thus the caller need to explicitly call lock_recursive which
+ * returns false if the lock was already held by this cpu. If it returns
+ * true, then the caller shall release it when done.
+ */
+extern bool lock_recursive(struct lock *l);
+
+/* Called after per-cpu data structures are available */
+extern void init_locks(void);
+
+#endif /* __LOCK_H */