cmpxchg.h 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /*
  2. * Atomics xchg/cmpxchg for PKUnity SoC and UniCore ISA
  3. *
  4. * Copyright (C) 2001-2012 GUAN Xue-tao
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #ifndef __UNICORE_CMPXCHG_H__
  11. #define __UNICORE_CMPXCHG_H__
  12. /*
  13. * Generate a link failure on undefined symbol if the pointer points to a value
  14. * of unsupported size.
  15. */
  16. extern void __xchg_bad_pointer(void);
  17. static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
  18. int size)
  19. {
  20. unsigned long ret;
  21. switch (size) {
  22. case 1:
  23. asm volatile("swapb %0, %1, [%2]"
  24. : "=&r" (ret)
  25. : "r" (x), "r" (ptr)
  26. : "memory", "cc");
  27. break;
  28. case 4:
  29. asm volatile("swapw %0, %1, [%2]"
  30. : "=&r" (ret)
  31. : "r" (x), "r" (ptr)
  32. : "memory", "cc");
  33. break;
  34. default:
  35. __xchg_bad_pointer();
  36. }
  37. return ret;
  38. }
  39. #define xchg(ptr, x) \
  40. ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
  41. #include <asm-generic/cmpxchg-local.h>
  42. /*
  43. * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
  44. * them available.
  45. */
  46. #define cmpxchg_local(ptr, o, n) \
  47. ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
  48. (unsigned long)(o), (unsigned long)(n), sizeof(*(ptr))))
  49. #define cmpxchg64_local(ptr, o, n) \
  50. __cmpxchg64_local_generic((ptr), (o), (n))
  51. #include <asm-generic/cmpxchg.h>
  52. #endif /* __UNICORE_CMPXCHG_H__ */