mutex.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * Pull in the generic implementation for the mutex fastpath.
  3. *
  4. * TODO: implement optimized primitives instead, or leave the generic
  5. * implementation in place, or pick the atomic_xchg() based generic
  6. * implementation. (see asm-generic/mutex-xchg.h for details)
  7. */
  8. #ifndef _ASM_MUTEX_H
  9. #define _ASM_MUTEX_H
  10. #ifndef CONFIG_SMP
  11. #include <asm-generic/mutex-dec.h>
  12. #else
  13. static inline void
  14. __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
  15. {
  16. if (unlikely(atomic_dec_return(count) < 0))
  17. fail_fn(count);
  18. else
  19. smp_mb();
  20. }
  21. static inline int
  22. __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
  23. {
  24. if (unlikely(atomic_dec_return(count) < 0))
  25. return fail_fn(count);
  26. else {
  27. smp_mb();
  28. return 0;
  29. }
  30. }
  31. static inline void
  32. __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
  33. {
  34. smp_mb();
  35. if (unlikely(atomic_inc_return(count) <= 0))
  36. fail_fn(count);
  37. }
  38. #define __mutex_slowpath_needs_to_unlock() 1
  39. static inline int
  40. __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
  41. {
  42. /*
  43. * We have two variants here. The cmpxchg based one is the best one
  44. * because it never induce a false contention state. It is included
  45. * here because architectures using the inc/dec algorithms over the
  46. * xchg ones are much more likely to support cmpxchg natively.
  47. *
  48. * If not we fall back to the spinlock based variant - that is
  49. * just as efficient (and simpler) as a 'destructive' probing of
  50. * the mutex state would be.
  51. */
  52. #ifdef __HAVE_ARCH_CMPXCHG
  53. if (likely(atomic_cmpxchg(count, 1, 0) == 1)) {
  54. smp_mb();
  55. return 1;
  56. }
  57. return 0;
  58. #else
  59. return fail_fn(count);
  60. #endif
  61. }
  62. #endif
  63. #endif