diff options
| author | Rusty Russell <rusty@rustcorp.com.au> | 2002-03-09 19:50:14 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-03-09 19:50:14 -0800 |
| commit | 882ad449046cec136c484dd2b3659fb4c683e0a3 (patch) | |
| tree | 363f84f0dc65135b84accd91a32e82e8f4810e68 /include | |
| parent | ee7ae3cac7e27634267cde1159e84b069d3c7d6f (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.h | 1 | ||||
| -rw-r--r-- | include/asm-i386/unistd.h | 1 | ||||
| -rw-r--r-- | include/asm-ppc/mman.h | 1 | ||||
| -rw-r--r-- | include/asm-ppc/unistd.h | 1 | ||||
| -rw-r--r-- | include/linux/futex.h | 8 | ||||
| -rw-r--r-- | include/linux/hash.h | 58 | ||||
| -rw-r--r-- | include/linux/mmzone.h | 5 |
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. |
