[patch 2.5.30] alpha: rwsem update [10/10]

Ivan Kokshaysky (ink@jurassic.park.msu.ru)
Sat, 10 Aug 2002 19:35:28 +0400


- __down_[read,write]_trylock, __downgrade_write implemented;
- __builtin_expect replaced with unlikely().

Ivan.

--- 2.5.30/include/asm-alpha/rwsem.h Fri Aug 2 01:16:35 2002
+++ linux/include/asm-alpha/rwsem.h Thu Aug 8 19:28:02 2002
@@ -21,6 +21,7 @@ struct rwsem_waiter;
extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);

/*
* the semaphore definition
@@ -83,10 +84,26 @@ static inline void __down_read(struct rw
:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
:"Ir" (RWSEM_ACTIVE_READ_BIAS), "m" (sem->count) : "memory");
#endif
- if (__builtin_expect(oldcount < 0, 0))
+ if (unlikely(oldcount < 0))
rwsem_down_read_failed(sem);
}

+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+ long res, tmp;
+
+ res = sem->count;
+ do {
+ tmp = res + RWSEM_ACTIVE_READ_BIAS;
+ if (tmp <= 0)
+ break;
+ } while (cmpxchg(&sem->count, res, tmp) != res);
+ return res >= 0 ? 1 : 0;
+}
+
static inline void __down_write(struct rw_semaphore *sem)
{
long oldcount;
@@ -107,10 +124,22 @@ static inline void __down_write(struct r
:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
:"Ir" (RWSEM_ACTIVE_WRITE_BIAS), "m" (sem->count) : "memory");
#endif
- if (__builtin_expect(oldcount, 0))
+ if (unlikely(oldcount))
rwsem_down_write_failed(sem);
}

+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+ long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+ RWSEM_ACTIVE_WRITE_BIAS);
+ if (ret == RWSEM_UNLOCKED_VALUE)
+ return 1;
+ return 0;
+}
+
static inline void __up_read(struct rw_semaphore *sem)
{
long oldcount;
@@ -131,7 +160,7 @@ static inline void __up_read(struct rw_s
:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
:"Ir" (RWSEM_ACTIVE_READ_BIAS), "m" (sem->count) : "memory");
#endif
- if (__builtin_expect(oldcount < 0, 0))
+ if (unlikely(oldcount < 0))
if ((int)oldcount - RWSEM_ACTIVE_READ_BIAS == 0)
rwsem_wake(sem);
}
@@ -157,9 +186,36 @@ static inline void __up_write(struct rw_
:"=&r" (count), "=m" (sem->count), "=&r" (temp)
:"Ir" (RWSEM_ACTIVE_WRITE_BIAS), "m" (sem->count) : "memory");
#endif
- if (__builtin_expect(count, 0))
+ if (unlikely(count))
if ((int)count == 0)
rwsem_wake(sem);
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+ long oldcount;
+#ifndef CONFIG_SMP
+ oldcount = sem->count;
+ sem->count -= RWSEM_WAITING_BIAS;
+#else
+ long temp;
+ __asm__ __volatile__(
+ "1: ldq_l %0,%1\n"
+ " addq %0,%3,%2\n"
+ " stq_c %2,%1\n"
+ " beq %2,2f\n"
+ " mb\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
+ :"Ir" (-RWSEM_WAITING_BIAS), "m" (sem->count) : "memory");
+#endif
+ if (unlikely(oldcount < 0))
+ rwsem_downgrade_wake(sem);
}

static inline void rwsem_atomic_add(long val, struct rw_semaphore *sem)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/