[SSI] openssi/kernel/include/asm-x86_64 atomic.h, 1.1, 1.2 fcntl.h, 1.1, 1.2 mman.h, 1.1, 1.2 semaphore.h, 1.1, 1.2 uaccess.h, 1.1, 1.2
John Hughes <[email protected]> Mon, 15 Feb 2010 16:48:46 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv27464/include/asm-x86_64
Modified Files:
Tag: OPENSSI-DEBIAN
atomic.h fcntl.h mman.h semaphore.h uaccess.h
Log Message:
Back out incorrect x86_64 patch
Index: uaccess.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64/uaccess.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- uaccess.h 13 Jun 2003 14:51:38 -0000 1.1
+++ uaccess.h 15 Feb 2010 16:48:43 -0000 1.2
@@ -5,6 +5,7 @@
* User space memory access functions
*/
#include <linux/config.h>
+#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/prefetch.h>
@@ -23,31 +24,32 @@
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
-#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF)
+#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFFUL)
#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
#define get_ds() (KERNEL_DS)
-#define get_fs() (current->addr_limit)
-#define set_fs(x) (current->addr_limit = (x))
+#define get_fs() (current_thread_info()->addr_limit)
+#define set_fs(x) (current_thread_info()->addr_limit = (x))
#define segment_eq(a,b) ((a).seg == (b).seg)
-#define __addr_ok(addr) (!((unsigned long)(addr) & (current->addr_limit.seg)))
+#define __addr_ok(addr) (!((unsigned long)(addr) & (current_thread_info()->addr_limit.seg)))
/*
* Uhhuh, this needs 65-bit arithmetic. We have a carry..
*/
#define __range_not_ok(addr,size) ({ \
unsigned long flag,sum; \
+ __chk_user_ptr(addr); \
asm("# range_ok\n\r" \
"addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \
:"=&r" (flag), "=r" (sum) \
- :"1" (addr),"g" ((long)(size)),"g" (current->addr_limit.seg)); \
+ :"1" (addr),"g" ((long)(size)),"g" (current_thread_info()->addr_limit.seg)); \
flag; })
-#define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0)
+#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0)
-extern inline int verify_area(int type, const void * addr, unsigned long size)
+extern inline int verify_area(int type, const void __user * addr, unsigned long size)
{
return access_ok(type,addr,size) ? 0 : -EFAULT;
}
@@ -100,8 +102,9 @@
/* Careful: we have to cast the result to the type of the pointer for sign reasons */
#define get_user(x,ptr) \
-({ long __val_gu; \
+({ unsigned long __val_gu; \
int __ret_gu; \
+ __chk_user_ptr(ptr); \
switch(sizeof (*(ptr))) { \
case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \
case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \
@@ -134,6 +137,9 @@
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
#define __put_user_nocheck(x,ptr,size) \
({ \
int __pu_err; \
@@ -145,8 +151,8 @@
#define __put_user_check(x,ptr,size) \
({ \
int __pu_err = -EFAULT; \
- __typeof__(*(ptr)) *__pu_addr = (ptr); \
- if (access_ok(VERIFY_WRITE,__pu_addr,size)) \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ if (likely(access_ok(VERIFY_WRITE,__pu_addr,size))) \
__put_user_size((x),__pu_addr,(size),__pu_err); \
__pu_err; \
})
@@ -154,6 +160,7 @@
#define __put_user_size(x,ptr,size,retval) \
do { \
retval = 0; \
+ __chk_user_ptr(ptr); \
switch (size) { \
case 1: __put_user_asm(x,ptr,retval,"b","b","iq",-EFAULT); break;\
case 2: __put_user_asm(x,ptr,retval,"w","w","ir",-EFAULT); break;\
@@ -165,7 +172,7 @@
/* FIXME: this hack is definitely wrong -AK */
struct __large_struct { unsigned long buf[100]; };
-#define __m(x) (*(struct __large_struct *)(x))
+#define __m(x) (*(struct __large_struct __user *)(x))
/*
* Tell gcc we read from memory instead of writing: this is because
@@ -173,25 +180,25 @@
* aliasing issues.
*/
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errno) \
- __asm__ __volatile__( \
- "1: mov"itype" %"rtype"1,%2\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
+ __asm__ __volatile__( \
+ "1: mov"itype" %"rtype"1,%2\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
- " jmp 2b\n" \
+ " jmp 2b\n" \
".previous\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 8\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 8\n" \
" .quad 1b,3b\n" \
- ".previous" \
- : "=r"(err) \
+ ".previous" \
+ : "=r"(err) \
: ltype (x), "m"(__m(addr)), "i"(errno), "0"(err))
#define __get_user_nocheck(x,ptr,size) \
({ \
int __gu_err; \
- long __gu_val; \
+ unsigned long __gu_val; \
__get_user_size(__gu_val,(ptr),(size),__gu_err); \
(x) = (__typeof__(*(ptr)))__gu_val; \
__gu_err; \
@@ -202,6 +209,7 @@
#define __get_user_size(x,ptr,size,retval) \
do { \
retval = 0; \
+ __chk_user_ptr(ptr); \
switch (size) { \
case 1: __get_user_asm(x,ptr,retval,"b","b","=q",-EFAULT); break;\
case 2: __get_user_asm(x,ptr,retval,"w","w","=r",-EFAULT); break;\
@@ -234,76 +242,119 @@
/* Handles exceptions in both to and from, but doesn't do access_ok */
extern unsigned long copy_user_generic(void *to, const void *from, unsigned len);
-extern unsigned long copy_to_user(void *to, const void *from, unsigned len);
-extern unsigned long copy_from_user(void *to, const void *from, unsigned len);
+extern unsigned long copy_to_user(void __user *to, const void *from, unsigned len);
+extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len);
+extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len);
-static inline int __copy_from_user(void *dst, const void *src, unsigned size)
+static inline int __copy_from_user(void *dst, const void __user *src, unsigned size)
{
+ int ret = 0;
if (!__builtin_constant_p(size))
- return copy_user_generic(dst,src,size);
- int ret = 0;
+ return copy_user_generic(dst,(__force void *)src,size);
switch (size) {
- case 1:__get_user_asm(*(u8*)dst,(u8 *)src,ret,"b","b","=q",1);
+ case 1:__get_user_asm(*(u8*)dst,(u8 __user *)src,ret,"b","b","=q",1);
return ret;
- case 2:__get_user_asm(*(u16*)dst,(u16*)src,ret,"w","w","=r",2);
+ case 2:__get_user_asm(*(u16*)dst,(u16 __user *)src,ret,"w","w","=r",2);
return ret;
- case 4:__get_user_asm(*(u32*)dst,(u32*)src,ret,"l","k","=r",4);
+ case 4:__get_user_asm(*(u32*)dst,(u32 __user *)src,ret,"l","k","=r",4);
return ret;
- case 8:__get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",8);
+ case 8:__get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",8);
return ret;
case 10:
- __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
- if (ret) return ret;
- __get_user_asm(*(u16*)(8+dst),(u16*)(8+src),ret,"w","w","=r",2);
+ __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
+ if (unlikely(ret)) return ret;
+ __get_user_asm(*(u16*)(8+(char*)dst),(u16 __user *)(8+(char __user *)src),ret,"w","w","=r",2);
return ret;
case 16:
- __get_user_asm(*(u64*)dst,(u64*)src,ret,"q","","=r",16);
- if (ret) return ret;
- __get_user_asm(*(u64*)(8+dst),(u64*)(8+src),ret,"q","","=r",8);
+ __get_user_asm(*(u64*)dst,(u64 __user *)src,ret,"q","","=r",16);
+ if (unlikely(ret)) return ret;
+ __get_user_asm(*(u64*)(8+(char*)dst),(u64 __user *)(8+(char __user *)src),ret,"q","","=r",8);
return ret;
default:
- return copy_user_generic(dst,src,size);
+ return copy_user_generic(dst,(__force void *)src,size);
}
}
-static inline int __copy_to_user(void *dst, const void *src, unsigned size)
+static inline int __copy_to_user(void __user *dst, const void *src, unsigned size)
{
+ int ret = 0;
if (!__builtin_constant_p(size))
- return copy_user_generic(dst,src,size);
- int ret = 0;
+ return copy_user_generic((__force void *)dst,src,size);
switch (size) {
- case 1:__put_user_asm(*(u8*)src,(u8 *)dst,ret,"b","b","iq",1);
+ case 1:__put_user_asm(*(u8*)src,(u8 __user *)dst,ret,"b","b","iq",1);
return ret;
- case 2:__put_user_asm(*(u16*)src,(u16*)dst,ret,"w","w","ir",2);
+ case 2:__put_user_asm(*(u16*)src,(u16 __user *)dst,ret,"w","w","ir",2);
return ret;
- case 4:__put_user_asm(*(u32*)src,(u32*)dst,ret,"l","k","ir",4);
+ case 4:__put_user_asm(*(u32*)src,(u32 __user *)dst,ret,"l","k","ir",4);
return ret;
- case 8:__put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",8);
+ case 8:__put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",8);
return ret;
case 10:
- __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",10);
- if (ret) return ret;
+ __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",10);
+ if (unlikely(ret)) return ret;
asm("":::"memory");
- __put_user_asm(4[(u16*)src],4+(u16*)dst,ret,"w","w","ir",2);
+ __put_user_asm(4[(u16*)src],4+(u16 __user *)dst,ret,"w","w","ir",2);
return ret;
case 16:
- __put_user_asm(*(u64*)src,(u64*)dst,ret,"q","","ir",16);
- if (ret) return ret;
+ __put_user_asm(*(u64*)src,(u64 __user *)dst,ret,"q","","ir",16);
+ if (unlikely(ret)) return ret;
asm("":::"memory");
- __put_user_asm(1[(u64*)src],1+(u64*)dst,ret,"q","","ir",8);
+ __put_user_asm(1[(u64*)src],1+(u64 __user *)dst,ret,"q","","ir",8);
return ret;
default:
- return copy_user_generic(dst,src,size);
+ return copy_user_generic((__force void *)dst,src,size);
}
}
-long strncpy_from_user(char *dst, const char *src, long count);
-long __strncpy_from_user(char *dst, const char *src, long count);
-long strnlen_user(const char *str, long n);
-long strlen_user(const char *str);
-unsigned long clear_user(void *mem, unsigned long len);
-unsigned long __clear_user(void *mem, unsigned long len);
-extern unsigned long search_exception_table(unsigned long);
+static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
+{
+ int ret = 0;
+ if (!__builtin_constant_p(size))
+ return copy_user_generic((__force void *)dst,(__force void *)src,size);
+ switch (size) {
+ case 1: {
+ u8 tmp;
+ __get_user_asm(tmp,(u8 __user *)src,ret,"b","b","=q",1);
+ if (likely(!ret))
+ __put_user_asm(tmp,(u8 __user *)dst,ret,"b","b","iq",1);
+ return ret;
+ }
+ case 2: {
+ u16 tmp;
+ __get_user_asm(tmp,(u16 __user *)src,ret,"w","w","=r",2);
+ if (likely(!ret))
+ __put_user_asm(tmp,(u16 __user *)dst,ret,"w","w","ir",2);
+ return ret;
+ }
+
+ case 4: {
+ u32 tmp;
+ __get_user_asm(tmp,(u32 __user *)src,ret,"l","k","=r",4);
+ if (likely(!ret))
+ __put_user_asm(tmp,(u32 __user *)dst,ret,"l","k","ir",4);
+ return ret;
+ }
+ case 8: {
+ u64 tmp;
+ __get_user_asm(tmp,(u64 __user *)src,ret,"q","","=r",8);
+ if (likely(!ret))
+ __put_user_asm(tmp,(u64 __user *)dst,ret,"q","","ir",8);
+ return ret;
+ }
+ default:
+ return copy_user_generic((__force void *)dst,(__force void *)src,size);
+ }
+}
+
+long strncpy_from_user(char *dst, const char __user *src, long count);
+long __strncpy_from_user(char *dst, const char __user *src, long count);
+long strnlen_user(const char __user *str, long n);
+long strlen_user(const char __user *str);
+unsigned long clear_user(void __user *mem, unsigned long len);
+unsigned long __clear_user(void __user *mem, unsigned long len);
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
#endif /* __X86_64_UACCESS_H */
Index: mman.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64/mman.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- mman.h 28 Nov 2002 23:53:15 -0000 1.1
+++ mman.h 15 Feb 2010 16:48:43 -0000 1.2
@@ -5,6 +5,9 @@
#define PROT_WRITE 0x2 /* page can be written */
#define PROT_EXEC 0x4 /* page can be executed */
#define PROT_NONE 0x0 /* page can not be accessed */
+#define PROT_SEM 0x8
+#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
+#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
@@ -18,6 +21,8 @@
#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
#define MAP_LOCKED 0x2000 /* pages are locked */
#define MAP_NORESERVE 0x4000 /* don't check for reservations */
+#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x10000 /* do not block on IO */
#define MS_ASYNC 1 /* sync memory asynchronously */
#define MS_INVALIDATE 2 /* invalidate the caches */
Index: fcntl.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64/fcntl.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- fcntl.h 12 Apr 2005 22:34:55 -0000 1.1
+++ fcntl.h 15 Feb 2010 16:48:43 -0000 1.2
@@ -20,7 +20,7 @@
#define O_LARGEFILE 0100000
#define O_DIRECTORY 0200000 /* must be a directory */
#define O_NOFOLLOW 0400000 /* don't follow links */
-#define O_ATOMICLOOKUP 01000000 /* do atomic file lookup */
+#define O_NOATIME 01000000
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get close_on_exec */
@@ -73,8 +73,4 @@
#define F_LINUX_SPECIFIC_BASE 1024
-#ifdef __KERNEL__
-#define flock64 flock
-#endif
-
#endif /* !_X86_64_FCNTL_H */
Index: atomic.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64/atomic.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- atomic.h 12 Apr 2005 22:34:56 -0000 1.1
+++ atomic.h 15 Feb 2010 16:48:43 -0000 1.2
@@ -29,8 +29,7 @@
* atomic_read - read atomic variable
* @v: pointer of type atomic_t
*
- * Atomically reads the value of @v. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * Atomically reads the value of @v.
*/
#define atomic_read(v) ((v)->counter)
@@ -39,8 +38,7 @@
* @v: pointer of type atomic_t
* @i: required value
*
- * Atomically sets the value of @v to @i. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * Atomically sets the value of @v to @i.
*/
#define atomic_set(v,i) (((v)->counter) = (i))
@@ -49,8 +47,7 @@
* @i: integer value to add
* @v: pointer of type atomic_t
*
- * Atomically adds @i to @v. Note that the guaranteed useful range
- * of an atomic_t is only 24 bits.
+ * Atomically adds @i to @v.
*/
static __inline__ void atomic_add(int i, atomic_t *v)
{
@@ -65,8 +62,7 @@
* @i: integer value to subtract
* @v: pointer of type atomic_t
*
- * Atomically subtracts @i from @v. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * Atomically subtracts @i from @v.
*/
static __inline__ void atomic_sub(int i, atomic_t *v)
{
@@ -83,8 +79,7 @@
*
* Atomically subtracts @i from @v and returns
* true if the result is zero, or false for all
- * other cases. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * other cases.
*/
static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
{
@@ -97,30 +92,11 @@
return c;
}
-/* returns true if the inc succeeded */
-static inline int atomic_inc_if_nonzero(atomic_t *v)
-{
- int val = atomic_read(v);
-
- while (val) {
- unsigned char c;
- __asm__ __volatile__(
- LOCK "cmpxchgl %3,%1 ; setz %2"
- : "=a" (val), "=m" (v->counter), "=qm" (c)
- : "r" (val + 1), "0" (val), "m" (v->counter)
- : "memory");
- if (c != 0)
- return 1;
- }
- return 0;
-}
-
/**
* atomic_inc - increment atomic variable
* @v: pointer of type atomic_t
*
- * Atomically increments @v by 1. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * Atomically increments @v by 1.
*/
static __inline__ void atomic_inc(atomic_t *v)
{
@@ -134,8 +110,7 @@
* atomic_dec - decrement atomic variable
* @v: pointer of type atomic_t
*
- * Atomically decrements @v by 1. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * Atomically decrements @v by 1.
*/
static __inline__ void atomic_dec(atomic_t *v)
{
@@ -151,8 +126,7 @@
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
- * cases. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * cases.
*/
static __inline__ int atomic_dec_and_test(atomic_t *v)
{
@@ -171,8 +145,7 @@
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
- * other cases. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * other cases.
*/
static __inline__ int atomic_inc_and_test(atomic_t *v)
{
@@ -192,8 +165,7 @@
*
* Atomically adds @i to @v and returns true
* if the result is negative, or false when
- * result is greater than or equal to zero. Note that the guaranteed
- * useful range of an atomic_t is only 24 bits.
+ * result is greater than or equal to zero.
*/
static __inline__ int atomic_add_negative(int i, atomic_t *v)
{
@@ -206,6 +178,191 @@
return c;
}
+/* An 64bit atomic type */
+
+typedef struct { volatile long counter; } atomic64_t;
+
+#define ATOMIC64_INIT(i) { (i) }
+
+/**
+ * atomic64_read - read atomic64 variable
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically reads the value of @v.
+ * Doesn't imply a read memory barrier.
+ */
+#define atomic64_read(v) ((v)->counter)
+
+/**
+ * atomic64_set - set atomic64 variable
+ * @v: pointer to type atomic64_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ */
+#define atomic64_set(v,i) (((v)->counter) = (i))
+
+/**
+ * atomic64_add - add integer to atomic64 variable
+ * @i: integer value to add
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically adds @i to @v.
+ */
+static __inline__ void atomic64_add(long i, atomic64_t *v)
+{
+ __asm__ __volatile__(
+ LOCK "addq %1,%0"
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic64_sub - subtract the atomic64 variable
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+static __inline__ void atomic64_sub(long i, atomic64_t *v)
+{
+ __asm__ __volatile__(
+ LOCK "subq %1,%0"
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic64_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int atomic64_sub_and_test(long i, atomic64_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ LOCK "subq %2,%0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
+ return c;
+}
+
+/**
+ * atomic64_inc - increment atomic64 variable
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically increments @v by 1.
+ */
+static __inline__ void atomic64_inc(atomic64_t *v)
+{
+ __asm__ __volatile__(
+ LOCK "incq %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+/**
+ * atomic64_dec - decrement atomic64 variable
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically decrements @v by 1.
+ */
+static __inline__ void atomic64_dec(atomic64_t *v)
+{
+ __asm__ __volatile__(
+ LOCK "decq %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+/**
+ * atomic64_dec_and_test - decrement and test
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases.
+ */
+static __inline__ int atomic64_dec_and_test(atomic64_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ LOCK "decq %0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * atomic64_inc_and_test - increment and test
+ * @v: pointer to type atomic64_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+static __inline__ int atomic64_inc_and_test(atomic64_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ LOCK "incq %0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * atomic64_add_negative - add and test if negative
+ * @v: pointer to atomic64_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+static __inline__ long atomic64_add_negative(long i, atomic64_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ LOCK "addq %2,%0; sets %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
+ return c;
+}
+
+/**
+ * atomic_add_return - add and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static __inline__ int atomic_add_return(int i, atomic_t *v)
+{
+ int __i = i;
+ __asm__ __volatile__(
+ LOCK "xaddl %0, %1;"
+ :"=r"(i)
+ :"m"(v->counter), "0"(i));
+ return i + __i;
+}
+
+static __inline__ int atomic_sub_return(int i, atomic_t *v)
+{
+ return atomic_add_return(-i,v);
+}
+
+#define atomic_inc_return(v) (atomic_add_return(1,v))
+#define atomic_dec_return(v) (atomic_sub_return(1,v))
+
/* These are x86-specific, used by some header files */
#define atomic_clear_mask(mask, addr) \
__asm__ __volatile__(LOCK "andl %0,%1" \
@@ -213,7 +370,7 @@
#define atomic_set_mask(mask, addr) \
__asm__ __volatile__(LOCK "orl %0,%1" \
-: : "r" ((unsigned)mask),"m" (*addr) : "memory")
+: : "r" ((unsigned)mask),"m" (*(addr)) : "memory")
/* Atomic operations are already serializing on x86 */
#define smp_mb__before_atomic_dec() barrier()
Index: semaphore.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/include/asm-x86_64/semaphore.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- semaphore.h 12 Apr 2005 22:34:53 -0000 1.1
+++ semaphore.h 15 Feb 2010 16:48:43 -0000 1.2
@@ -47,21 +47,14 @@
atomic_t count;
int sleepers;
wait_queue_head_t wait;
-#if WAITQUEUE_DEBUG
- long __magic;
-#endif
};
-#if WAITQUEUE_DEBUG
-# define __SEM_DEBUG_INIT(name) \
- , (int)&(name).__magic
-#else
-# define __SEM_DEBUG_INIT(name)
-#endif
-
-#define __SEMAPHORE_INITIALIZER(name,count) \
-{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
- __SEM_DEBUG_INIT(name) }
+#define __SEMAPHORE_INITIALIZER(name, n) \
+{ \
+ .count = ATOMIC_INIT(n), \
+ .sleepers = 0, \
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
+}
#define __MUTEX_INITIALIZER(name) \
__SEMAPHORE_INITIALIZER(name,1)
@@ -78,14 +71,11 @@
* *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
*
* i'd rather use the more flexible initialization above, but sadly
- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.
+ * GCC 2.7.2.3 emits a bogus warning. EGCS doesn't. Oh well.
*/
atomic_set(&sem->count, val);
sem->sleepers = 0;
init_waitqueue_head(&sem->wait);
-#if WAITQUEUE_DEBUG
- sem->__magic = (int)&sem->__magic;
-#endif
}
static inline void init_MUTEX (struct semaphore *sem)
@@ -115,9 +105,7 @@
*/
static inline void down(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
+ might_sleep();
__asm__ __volatile__(
"# atomic down operation\n\t"
@@ -133,31 +121,6 @@
:"memory");
}
-/* Returns 0 if we acquired the semaphore, 1 if it was queued */
-struct worktodo;
-static inline int wtd_down(struct worktodo *wtd, struct semaphore * sem)
-{
- int ret = 0;
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
-
- __asm__ __volatile__(
- "# atomic down operation\n\t"
- LOCK "decl %0\n\t" /* --sem->count */
- "js 2f\n"
- "1:\n"
- LOCK_SECTION_START("")
- "2:\tcall __wtd_down_failed\n\t"
- "movl $1,%1\n\t"
- "jmp 1b\n"
- LOCK_SECTION_END
- :"=m" (sem->count), "=r" (ret)
- :"D" (sem), "1" (ret), "S" (wtd)
- :"memory");
- return ret;
-}
-
/*
* Interruptible try to acquire a semaphore. If we obtained
* it, return zero. If we were interrupted, returns -EINTR
@@ -166,9 +129,7 @@
{
int result;
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
+ might_sleep();
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
@@ -194,10 +155,6 @@
{
int result;
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
-
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
LOCK "decl %1\n\t" /* --sem->count */
@@ -222,9 +179,6 @@
*/
static inline void up(struct semaphore * sem)
{
-#if WAITQUEUE_DEBUG
- CHECK_MAGIC(sem->__magic);
-#endif
__asm__ __volatile__(
"# atomic up operation\n\t"
LOCK "incl %0\n\t" /* ++sem->count */
@@ -238,11 +192,5 @@
:"D" (sem)
:"memory");
}
-
-static inline int sem_getcount(struct semaphore *sem)
-{
- return atomic_read(&sem->count);
-}
-
#endif /* __KERNEL__ */
#endif
------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev