summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2002-03-09 19:50:14 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2002-03-09 19:50:14 -0800
commit882ad449046cec136c484dd2b3659fb4c683e0a3 (patch)
tree363f84f0dc65135b84accd91a32e82e8f4810e68 /include
parentee7ae3cac7e27634267cde1159e84b069d3c7d6f (diff)
[PATCH] Futexes IV (Fast Lightweight Userspace Semaphores)
Fast user-space mutex implementation, allowing user space to do all of the normal handling, with a minimal fallback to kernel space for when there is lock contention. The kernel space implementation does not keep any per-lock data structures, but instead does a fast hash on the physical page and offset of the user-space lock when contended. Thus no build/teardown costs, or any scalability costs wrt metadata. Updated syscall numbers for 2.5.6, and changed FUTEX_UP/DOWN definitions to be more logical for future expansions (eg. r/w).
Diffstat (limited to 'include')
-rw-r--r--include/asm-i386/mman.h1
-rw-r--r--include/asm-i386/unistd.h1
-rw-r--r--include/asm-ppc/mman.h1
-rw-r--r--include/asm-ppc/unistd.h1
-rw-r--r--include/linux/futex.h8
-rw-r--r--include/linux/hash.h58
-rw-r--r--include/linux/mmzone.h5
7 files changed, 72 insertions, 3 deletions
diff --git a/include/asm-i386/mman.h b/include/asm-i386/mman.h
index f953c436ce51..85566a0029ca 100644
--- a/include/asm-i386/mman.h
+++ b/include/asm-i386/mman.h
@@ -4,6 +4,7 @@
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index d87ebc3ceff6..84af0bcfdfe3 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -244,6 +244,7 @@
#define __NR_fremovexattr 237
#define __NR_tkill 238
#define __NR_sendfile64 239
+#define __NR_futex 240
/* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
diff --git a/include/asm-ppc/mman.h b/include/asm-ppc/mman.h
index 04206f671b85..eb7aba2be87a 100644
--- a/include/asm-ppc/mman.h
+++ b/include/asm-ppc/mman.h
@@ -7,6 +7,7 @@
#define PROT_READ 0x1 /* page can be read */
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
+#define PROT_SEM 0x8 /* page may be used for atomic ops */
#define PROT_NONE 0x0 /* page can not be accessed */
#define MAP_SHARED 0x01 /* Share changes */
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
index 3e1bd01ed08f..d881d0ed64c7 100644
--- a/include/asm-ppc/unistd.h
+++ b/include/asm-ppc/unistd.h
@@ -228,6 +228,7 @@
#define __NR_removexattr 218
#define __NR_lremovexattr 219
#define __NR_fremovexattr 220
+#define __NR_futex 221
#define __NR(n) #n
diff --git a/include/linux/futex.h b/include/linux/futex.h
new file mode 100644
index 000000000000..5ebcc879b4c0
--- /dev/null
+++ b/include/linux/futex.h
@@ -0,0 +1,8 @@
+#ifndef _LINUX_FUTEX_H
+#define _LINUX_FUTEX_H
+
+/* Second argument to futex syscall */
+#define FUTEX_UP (0)
+#define FUTEX_DOWN (1)
+
+#endif
diff --git a/include/linux/hash.h b/include/linux/hash.h
new file mode 100644
index 000000000000..acf17bb8e7f9
--- /dev/null
+++ b/include/linux/hash.h
@@ -0,0 +1,58 @@
+#ifndef _LINUX_HASH_H
+#define _LINUX_HASH_H
+/* Fast hashing routine for a long.
+ (C) 2002 William Lee Irwin III, IBM */
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ *
+ * These primes are chosen to be bit-sparse, that is operations on
+ * them can use shifts and additions instead of multiplications for
+ * machines where multiplications are slow.
+ */
+#if BITS_PER_LONG == 32
+/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e370001UL
+#elif BITS_PER_LONG == 64
+/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
+#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
+#else
+#error Define GOLDEN_RATIO_PRIME for your wordsize.
+#endif
+
+static inline unsigned long hash_long(unsigned long val, unsigned int bits)
+{
+ unsigned long hash = val;
+
+#if BITS_PER_LONG == 64
+ /* Sigh, gcc can't optimise this alone like it does for 32 bits. */
+ unsigned long n = hash;
+ n <<= 18;
+ hash -= n;
+ n <<= 33;
+ hash -= n;
+ n <<= 3;
+ hash += n;
+ n <<= 3;
+ hash -= n;
+ n <<= 4;
+ hash += n;
+ n <<= 2;
+ hash += n;
+#else
+ /* On some cpus multiply is faster, on others gcc will do shifts */
+ hash *= GOLDEN_RATIO_PRIME;
+#endif
+
+ /* High bits are more random, so use them. */
+ return hash >> (BITS_PER_LONG - bits);
+}
+
+static inline unsigned long hash_ptr(void *ptr, unsigned int bits)
+{
+ return hash_long((unsigned long)ptr, bits);
+}
+#endif /* _LINUX_HASH_H */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ff810df6c8ee..bfe502d98f2a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -51,8 +51,7 @@ typedef struct zone_struct {
/*
* wait_table -- the array holding the hash table
* wait_table_size -- the size of the hash table array
- * wait_table_shift -- wait_table_size
- * == BITS_PER_LONG (1 << wait_table_bits)
+ * wait_table_bits -- wait_table_size == (1 << wait_table_bits)
*
* The purpose of all these is to keep track of the people
* waiting for a page to become available and make them
@@ -75,7 +74,7 @@ typedef struct zone_struct {
*/
wait_queue_head_t * wait_table;
unsigned long wait_table_size;
- unsigned long wait_table_shift;
+ unsigned long wait_table_bits;
/*
* Discontig memory support fields.