From: "Chen, Kenneth W" <kenneth.w.chen@intel.com>
To: linux-ia64@vger.kernel.org
Subject: RE: [Linux-ia64] RE: ia64 rwsem using atomic primitive
Date: Wed, 19 Feb 2003 20:09:31 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590709805880@msgid-missing> (raw)
In-Reply-To: <marc-linux-ia64-105590709805873@msgid-missing>
[-- Attachment #1: Type: text/plain, Size: 701 bytes --]
Hi David,
Here it is again with the CR-LF removed. Sorry.
- Ken
-----Original Message-----
From: David Mosberger [mailto:davidm@napali.hpl.hp.com]
Sent: Wednesday, February 19, 2003 11:53 AM
To: Chen, Kenneth W
Cc: linux-ia64@linuxia64.org
Subject: Re: [Linux-ia64] RE: ia64 rwsem using atomic primitive
>>>>> On Wed, 19 Feb 2003 10:31:33 -0800, "Chen, Kenneth W" <kenneth.w.chen@intel.com> said:
Ken> Here is a patch against 2.5.60. It has one new function added
Ken> __downgrade_write() for 2.5. - Ken
I glanced over the patch and it looks fine, except that it has CR-LF
for end-of-line. Could you resend with the carriage-returns removed?
Thanks,
--david
[-- Attachment #2: rwsem.2.5.60.patch --]
[-- Type: application/octet-stream, Size: 5225 bytes --]
diff -Nur linux-2.5.60/arch/ia64/Kconfig linux-2.5.60.rwsem/arch/ia64/Kconfig
--- linux-2.5.60/arch/ia64/Kconfig Mon Feb 10 10:38:54 2003
+++ linux-2.5.60.rwsem/arch/ia64/Kconfig Wed Feb 19 00:32:37 2003
@@ -26,7 +26,7 @@
bool
default y
-config RWSEM_GENERIC_SPINLOCK
+config RWSEM_XCHGADD_ALGORITHM
bool
default y
diff -Nur linux-2.5.60/include/asm-ia64/rwsem.h linux-2.5.60.rwsem/include/asm-ia64/rwsem.h
--- linux-2.5.60/include/asm-ia64/rwsem.h Wed Dec 31 16:00:00 1969
+++ linux-2.5.60.rwsem/include/asm-ia64/rwsem.h Wed Feb 19 10:21:12 2003
@@ -0,0 +1,188 @@
+/*
+ * asm-ia64/rwsem.h: R/W semaphores for ia64
+ *
+ * Copyright (C) 2003 Ken Chen <kenneth.w.chen@intel.com>
+ * Copyright (C) 2003 Asit Mallick <asit.k.mallick@intel.com>
+ *
+ * Based on asm-i386/rwsem.h and other architecture implementation.
+ *
+ * The MSW of the count is the negated number of active writers and
+ * waiting lockers, and the LSW is the total number of active locks.
+ *
+ * The lock count is initialized to 0 (no active and no waiting lockers).
+ *
+ * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case
+ * of an uncontended lock. Readers increment by 1 and see a positive value
+ * when uncontended, negative if there are writers (and maybe) readers
+ * waiting (in which case it goes to sleep).
+ */
+
+#ifndef _IA64_RWSEM_H
+#define _IA64_RWSEM_H
+
+#ifdef __KERNEL__
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+/*
+ * the semaphore definition
+ */
+struct rw_semaphore {
+ signed int count;
+ spinlock_t wait_lock;
+ struct list_head wait_list;
+#if RWSEM_DEBUG
+ int debug;
+#endif
+};
+
+#define RWSEM_UNLOCKED_VALUE 0x00000000
+#define RWSEM_ACTIVE_BIAS 0x00000001
+#define RWSEM_ACTIVE_MASK 0x0000ffff
+#define RWSEM_WAITING_BIAS (-0x00010000)
+#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+
+/*
+ * initialization
+ */
+#if RWSEM_DEBUG
+#define __RWSEM_DEBUG_INIT , 0
+#else
+#define __RWSEM_DEBUG_INIT /* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+ { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
+ LIST_HEAD_INIT((name).wait_list) \
+ __RWSEM_DEBUG_INIT }
+
+#define DECLARE_RWSEM(name) \
+ struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+
+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 *sem);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+
+static inline void init_rwsem(struct rw_semaphore *sem)
+{
+ sem->count = RWSEM_UNLOCKED_VALUE;
+ spin_lock_init(&sem->wait_lock);
+ INIT_LIST_HEAD(&sem->wait_list);
+#if RWSEM_DEBUG
+ sem->debug = 0;
+#endif
+}
+
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+ int result;
+ __asm__ __volatile__ ("fetchadd4.acq %0=[%1],1" :
+ "=r"(result) : "r"(&sem->count) : "memory");
+ if (result < 0)
+ rwsem_down_read_failed(sem);
+}
+
+/*
+ * lock for writing
+ */
+static inline void __down_write(struct rw_semaphore *sem)
+{
+ int old, new;
+
+ do {
+ old = sem->count;
+ new = old + RWSEM_ACTIVE_WRITE_BIAS;
+ } while (cmpxchg_acq(&sem->count, old, new) != old);
+
+ if (old != 0)
+ rwsem_down_write_failed(sem);
+}
+
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+ int result;
+ __asm__ __volatile__ ("fetchadd4.rel %0=[%1],-1" :
+ "=r"(result) : "r"(&sem->count) : "memory");
+ if (result < 0 && (--result & RWSEM_ACTIVE_MASK) == 0)
+ rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+ int old, new;
+
+ do {
+ old = sem->count;
+ new = old - RWSEM_ACTIVE_WRITE_BIAS;
+ } while (cmpxchg_rel(&sem->count, old, new) != old);
+
+ if (new < 0 && (new & RWSEM_ACTIVE_MASK) == 0)
+ rwsem_wake(sem);
+}
+
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+ int tmp;
+ while ((tmp = sem->count) >= 0) {
+ if (tmp == cmpxchg_acq(&sem->count, tmp, tmp+1)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+ int tmp = cmpxchg_acq(&sem->count, RWSEM_UNLOCKED_VALUE,
+ RWSEM_ACTIVE_WRITE_BIAS);
+ return tmp == RWSEM_UNLOCKED_VALUE;
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+ int old, new;
+
+ do {
+ old = sem->count;
+ new = old - RWSEM_WAITING_BIAS;
+ } while (cmpxchg_rel(&sem->count, old, new) != old);
+
+ if (old < 0)
+ rwsem_downgrade_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+{
+ atomic_add(delta, (atomic_t *)(&sem->count));
+}
+
+static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+{
+ return atomic_add_return(delta, (atomic_t *)(&sem->count));
+}
+
+#endif /* __KERNEL__ */
+#endif /* _IA64_RWSEM_H */
prev parent reply other threads:[~2003-02-19 20:09 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-02-19 18:31 [Linux-ia64] RE: ia64 rwsem using atomic primitive Chen, Kenneth W
2003-02-19 19:52 ` David Mosberger
2003-02-19 20:09 ` Chen, Kenneth W [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-105590709805880@msgid-missing \
--to=kenneth.w.chen@intel.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.