bitops.h

Go to the documentation of this file.
00001 #ifndef _ASM_BITOPS_H
00002 #define _ASM_BITOPS_H
00003 /**
00004 *
00005 
00006  * Copyright 1992, Linus Torvalds.
00007 
00008 
00009 */
00010 
00011 #ifdef i386
00012 /**
00013 *
00014 
00015  * These have to be done with inline assembly: that way the bit-setting
00016  * is guaranteed to be atomic. All bitoperations return 0 if the bit
00017  * was cleared before the operation and != 0 if it was not.
00018  *
00019  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
00020 
00021 
00022 */
00023 
00024 /**
00025 *
00026 
00027  * Some hacks to defeat gcc over-optimizations..
00028 
00029 
00030 */
00031 struct __dummy { unsigned long a[100]; };
00032 #define ADDR (*(struct __dummy *) addr)
00033 
00034 extern __inline__ int set_bit(int nr, void * addr)
00035 {
00036         int oldbit;
00037 
00038         __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
00039                 :"=r" (oldbit),"=m" (ADDR)
00040                 :"r" (nr));
00041         return oldbit;
00042 }
00043 
00044 extern __inline__ int clear_bit(int nr, void * addr)
00045 {
00046         int oldbit;
00047 
00048         __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
00049                 :"=r" (oldbit),"=m" (ADDR)
00050                 :"r" (nr));
00051         return oldbit;
00052 }
00053 
00054 /**
00055 *
00056 
00057  * This routine doesn't need to be atomic, but it's faster to code it
00058  * this way.
00059 
00060 
00061 */
00062 extern __inline__ int test_bit(int nr, void * addr)
00063 {
00064         int oldbit;
00065 
00066         __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
00067                 :"=r" (oldbit)
00068                 :"m" (ADDR),"r" (nr));
00069         return oldbit;
00070 }
00071 
00072 #else
00073 /**
00074 *
00075 
00076  * For the benefit of those who are trying to port Linux to another
00077  * architecture, here are some C-language equivalents.  You should
00078  * recode these in the native assmebly language, if at all possible.
00079  * To guarantee atomicity, these routines call cli() and sti() to
00080  * disable interrupts while they operate.  (You have to provide inline
00081  * routines to cli() and sti().)
00082  *
00083  * Also note, these routines assume that you have 32 bit integers.
00084  * You will have to change this if you are trying to port Linux to the
00085  * Alpha architecture or to a Cray.  :-)
00086  * 
00087  * C language equivalents written by Theodore Ts'o, 9/26/92
00088 
00089 
00090 */
00091 
00092 extern __inline__ int set_bit(int nr,int * addr)
00093 {
00094         int     mask, retval;
00095 
00096         addr += nr >> 5;
00097         mask = 1 << (nr & 0x1f);
00098         cli();
00099         retval = (mask & *addr) != 0;
00100         *addr |= mask;
00101         sti();
00102         return retval;
00103 }
00104 
00105 extern __inline__ int clear_bit(int nr, int * addr)
00106 {
00107         int     mask, retval;
00108 
00109         addr += nr >> 5;
00110         mask = 1 << (nr & 0x1f);
00111         cli();
00112         retval = (mask & *addr) != 0;
00113         *addr &= ~mask;
00114         sti();
00115         return retval;
00116 }
00117 
00118 extern __inline__ int test_bit(int nr, int * addr)
00119 {
00120         int     mask;
00121 
00122         addr += nr >> 5;
00123         mask = 1 << (nr & 0x1f);
00124         return ((mask & *addr) != 0);
00125 }
00126 #endif  // i386 
00127 #endif // _ASM_BITOPS_H 

Generated on Mon May 1 21:46:59 2006 for KernelAPI by  doxygen 1.4.6-5