Subversion Repositories Kolibri OS

Rev

Rev 5602 | Rev 6099 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #ifndef __LBSYNC_H__
  2. #define __LBSYNC_H__
  3.  
  4. #define FUTEX_INIT      0
  5. #define FUTEX_DESTROY   1
  6. #define FUTEX_WAIT      2
  7. #define FUTEX_WAKE      3
  8.  
  9. #define exchange_acquire(ptr, new) \
  10.   __atomic_exchange_4((ptr), (new), __ATOMIC_ACQUIRE)
  11.  
  12. #define exchange_release(ptr, new) \
  13.   __atomic_exchange_4((ptr), (new), __ATOMIC_RELEASE)
  14.  
  15.  
  16. typedef struct
  17. {
  18.     volatile int lock;
  19.     int handle;
  20. }mutex_t;
  21.  
  22. static inline int mutex_init(mutex_t *mutex)
  23. {
  24.     int handle;
  25.  
  26.     mutex->lock = 0;
  27.  
  28.     asm volatile(
  29.     "int $0x40\t"
  30.     :"=a"(handle)
  31.     :"a"(77),"b"(FUTEX_INIT),"c"(mutex));
  32.     mutex->handle = handle;
  33.  
  34.     return handle;
  35. };
  36.  
  37. static inline int mutex_destroy(mutex_t *mutex)
  38. {
  39.     int retval;
  40.  
  41.     asm volatile(
  42.     "int $0x40\t"
  43.     :"=a"(retval)
  44.     :"a"(77),"b"(FUTEX_DESTROY),"c"(mutex->handle));
  45.  
  46.     return retval;
  47. };
  48.  
  49. static inline void mutex_lock(mutex_t *mutex)
  50. {
  51.     int tmp;
  52.  
  53.     if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
  54.         return;
  55.  
  56.     while (exchange_acquire (&mutex->lock, 2) != 0)
  57.     {
  58.         asm volatile(
  59.         "int $0x40\t"
  60.         :"=a"(tmp)
  61.         :"a"(77),"b"(FUTEX_WAIT),
  62.         "c"(mutex->handle),"d"(2),"S"(0));
  63.    }
  64. };
  65.  
  66. static inline void mutex_lock_timeout(mutex_t *mutex, int timeout)
  67. {
  68.     int tmp;
  69.  
  70.     if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
  71.         return;
  72.  
  73.     while (exchange_acquire (&mutex->lock, 2) != 0)
  74.     {
  75.         asm volatile(
  76.         "int $0x40\t"
  77.         :"=a"(tmp)
  78.         :"a"(77),"b"(FUTEX_WAIT),
  79.         "c"(mutex->handle),"d"(2),"S"(timeout));
  80.    }
  81. };
  82.  
  83. static inline int mutex_trylock (mutex_t *mutex)
  84. {
  85.     int zero = 0;
  86.  
  87.     return __atomic_compare_exchange_4(&mutex->lock, &zero, 1,0,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED);
  88. };
  89.  
  90. static inline void mutex_unlock(mutex_t *mutex)
  91. {
  92.     int prev;
  93.  
  94.     prev = exchange_release (&mutex->lock, 0);
  95.  
  96.     if (prev != 1)
  97.     {
  98.         asm volatile(
  99.         "int $0x40\t"
  100.         :"=a"(prev)
  101.         :"a"(77),"b"(FUTEX_WAKE),
  102.         "c"(mutex->handle),"d"(1));
  103.     };
  104. };
  105.  
  106. #endif
  107.