patch-2.4.20 linux-2.4.20/arch/parisc/lib/bitops.c

Next file: linux-2.4.20/arch/parisc/lib/io.c
Previous file: linux-2.4.20/arch/parisc/lib/Makefile
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/arch/parisc/lib/bitops.c linux-2.4.20/arch/parisc/lib/bitops.c
@@ -1,7 +1,10 @@
-/* atomic.c: atomic operations which got too long to be inlined all over
- * the place.
+/*
+ * bitops.c: atomic operations which got too long to be inlined all over
+ *      the place.
  * 
- * Copyright 1999 Philipp Rumpf (prumpf@tux.org */
+ * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
+ * Copyright 2000 Grant Grundler (grundler@cup.hp.com)
+ */
 
 #include <linux/config.h>
 #include <linux/kernel.h>
@@ -17,44 +20,67 @@
 
 spinlock_t __atomic_lock = SPIN_LOCK_UNLOCKED;
 
-#ifndef __LP64__
-unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
+#ifdef __LP64__
+unsigned long __xchg64(unsigned long x, unsigned long *ptr)
 {
 	unsigned long temp, flags;
 
-	if (size != sizeof x) {
-		printk("__xchg called with bad pointer\n");
-	}
-	spin_lock_irqsave(&__atomic_lock, flags);
+	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
 	temp = *ptr;
 	*ptr = x;
-	spin_unlock_irqrestore(&__atomic_lock, flags);
+	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
 	return temp;
 }
-#else
-unsigned long __xchg(unsigned long x, unsigned long *ptr, int size)
+#endif
+
+unsigned long __xchg32(int x, int *ptr)
 {
-	unsigned long temp, flags;
-	unsigned int *ptr32;
+	unsigned long flags;
+	unsigned long temp;
+
+	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
+	(long) temp = (long) *ptr;	/* XXX - sign extension wanted? */
+	*ptr = x;
+	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
+	return temp;
+}
+
+
+unsigned long __xchg8(char x, char *ptr)
+{
+	unsigned long flags;
+	unsigned long temp;
 
-	if (size == 8) {
-try_long:
-		spin_lock_irqsave(&__atomic_lock, flags);
-		temp = *ptr;
-		*ptr = x;
-		spin_unlock_irqrestore(&__atomic_lock, flags);
-		return temp;
-	}
-	if (size == 4) {
-		ptr32 = (unsigned int *)ptr;
-		spin_lock_irqsave(&__atomic_lock, flags);
-		temp = (unsigned long)*ptr32;
-		*ptr32 = (unsigned int)x;
-		spin_unlock_irqrestore(&__atomic_lock, flags);
-		return temp;
-	}
+	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
+	(long) temp = (long) *ptr;	/* XXX - sign extension wanted? */
+	*ptr = x;
+	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
+	return temp;
+}
+
+
+#ifdef __LP64__
+unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new)
+{
+	unsigned long flags;
+	unsigned long prev;
 
-	printk("__xchg called with bad pointer\n");
-	goto try_long;
+	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
+	if ((prev = *ptr) == old)
+		*ptr = new;
+	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
+	return prev;
 }
 #endif
+
+unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
+{
+	unsigned long flags;
+	unsigned int prev;
+
+	SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
+	if ((prev = *ptr) == old)
+		*ptr = new;
+	SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
+	return (unsigned long)prev;
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)