bitops.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:2k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * bitops.c: atomic operations which got too long to be inlined all over
  3.  *      the place.
  4.  * 
  5.  * Copyright 1999 Philipp Rumpf (prumpf@tux.org)
  6.  * Copyright 2000 Grant Grundler (grundler@cup.hp.com)
  7.  */
  8. #include <linux/config.h>
  9. #include <linux/kernel.h>
  10. #include <linux/spinlock.h>
  11. #include <asm/system.h>
  12. #include <asm/atomic.h>
  13. #ifdef CONFIG_SMP
  14. spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] = {
  15. [0 ... (ATOMIC_HASH_SIZE-1)]  = SPIN_LOCK_UNLOCKED
  16. };
  17. #endif
  18. spinlock_t __atomic_lock = SPIN_LOCK_UNLOCKED;
  19. #ifdef __LP64__
  20. unsigned long __xchg64(unsigned long x, unsigned long *ptr)
  21. {
  22. unsigned long temp, flags;
  23. SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
  24. temp = *ptr;
  25. *ptr = x;
  26. SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
  27. return temp;
  28. }
  29. #endif
  30. unsigned long __xchg32(int x, int *ptr)
  31. {
  32. unsigned long flags;
  33. unsigned long temp;
  34. SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
  35. (long) temp = (long) *ptr; /* XXX - sign extension wanted? */
  36. *ptr = x;
  37. SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
  38. return temp;
  39. }
  40. unsigned long __xchg8(char x, char *ptr)
  41. {
  42. unsigned long flags;
  43. unsigned long temp;
  44. SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
  45. (long) temp = (long) *ptr; /* XXX - sign extension wanted? */
  46. *ptr = x;
  47. SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
  48. return temp;
  49. }
  50. #ifdef __LP64__
  51. unsigned long __cmpxchg_u64(volatile unsigned long *ptr, unsigned long old, unsigned long new)
  52. {
  53. unsigned long flags;
  54. unsigned long prev;
  55. SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
  56. if ((prev = *ptr) == old)
  57. *ptr = new;
  58. SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
  59. return prev;
  60. }
  61. #endif
  62. unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
  63. {
  64. unsigned long flags;
  65. unsigned int prev;
  66. SPIN_LOCK_IRQSAVE(ATOMIC_HASH(ptr), flags);
  67. if ((prev = *ptr) == old)
  68. *ptr = new;
  69. SPIN_UNLOCK_IRQRESTORE(ATOMIC_HASH(ptr), flags);
  70. return (unsigned long)prev;
  71. }