Subversion Repositories Kolibri OS

Rev

Rev 6099 | 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\n"
  60.         :"=a"(tmp)
  61.         :"a"(77),"b"(FUTEX_WAIT),
  62.         "c"(mutex->handle),"d"(2),"S"(0));
  63.    }
  64. };
  65.  
  66. static inline int mutex_lock_timeout(mutex_t *mutex, int timeout)
  67. {
  68.     int tmp = 0;
  69.  
  70.     if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
  71.         return 1;
  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.         if(++tmp == 0)
  82.             break;
  83.     }
  84.     return tmp ;
  85. };
  86.  
  87. static inline int mutex_trylock (mutex_t *mutex)
  88. {
  89.     int zero = 0;
  90.  
  91.     return __atomic_compare_exchange_4(&mutex->lock, &zero, 1,0,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED);
  92. };
  93.  
  94. static inline void mutex_unlock(mutex_t *mutex)
  95. {
  96.     int prev;
  97.  
  98.     prev = exchange_release (&mutex->lock, 0);
  99.  
  100.     if (prev != 1)
  101.     {
  102.         __asm__ volatile(
  103.         "int $0x40\t"
  104.         :"=a"(prev)
  105.         :"a"(77),"b"(FUTEX_WAKE),
  106.         "c"(mutex->handle),"d"(1));
  107.     };
  108. };
  109.  
  110. #endif
  111.