patch-2.1.44 linux/include/asm-mips/semaphore.h

Next file: linux/include/asm-mips/sgi.h
Previous file: linux/include/asm-mips/segment.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.43/linux/include/asm-mips/semaphore.h linux/include/asm-mips/semaphore.h
@@ -0,0 +1,84 @@
+/*
+ * SMP- and interrupt-safe semaphores..
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * (C) Copyright 1996  Linus Torvalds, Ralf Baechle
+ */
+#ifndef __ASM_MIPS_SEMAPHORE_H
+#define __ASM_MIPS_SEMAPHORE_H
+
+#include <asm/atomic.h>
+
+struct semaphore {
+	atomic_t count;
+	atomic_t waking;
+	struct wait_queue * wait;
+};
+
+#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL })
+#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL })
+
+extern void __down(struct semaphore * sem);
+extern int  __down_interruptible(struct semaphore * sem);
+extern void __up(struct semaphore * sem);
+
+#define sema_init(sem, val)	atomic_set(&((sem)->count), val)
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * which we have.  Let the rest of the losers suck eggs.
+ */
+
+static inline void wake_one_more(struct semaphore * sem)
+{
+	atomic_inc(&sem->waking);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+	int ret, tmp;
+
+	__asm__ __volatile__(
+	"1:\tll\t%1,%2\n"
+	"blez\t%1,2f\n\t"
+	"subu\t%0,%1,1\n\t"
+	"sc\t%0,%2\n\t"
+	"beqz\t%0,1b\n\t"
+	"2:"
+	".text"
+	: "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
+	: "0"(0));
+
+	return ret;
+}
+
+extern inline void down(struct semaphore * sem)
+{
+	if (atomic_dec_return(&sem->count) < 0)
+		__down(sem);
+}
+
+extern inline int down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	if (atomic_dec_return(&sem->count) < 0)
+		ret = __down_interruptible(sem);
+	return ret;
+}
+
+/*
+ * Note! This is subtle. We jump to wake people up only if
+ * the semaphore was negative (== somebody was waiting on it).
+ */
+extern inline void up(struct semaphore * sem)
+{
+	if (atomic_inc_return(&sem->count) <= 0)
+		__up(sem);
+}
+
+#endif /* __ASM_MIPS_SEMAPHORE_H */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov