Subversion Repositories Kolibri OS

Rev

Rev 6099 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5602 serge 1
#ifndef __LBSYNC_H__
2
#define __LBSYNC_H__
3
 
6068 serge 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
 
5602 serge 16
typedef struct
17
{
18
    volatile int lock;
6068 serge 19
    int handle;
5602 serge 20
}mutex_t;
21
 
6068 serge 22
static inline int mutex_init(mutex_t *mutex)
23
{
24
    int handle;
5602 serge 25
 
6068 serge 26
    mutex->lock = 0;
27
 
6109 serge 28
    __asm__ volatile(
6068 serge 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
 
6109 serge 41
    __asm__ volatile(
6068 serge 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
    {
6109 serge 58
        __asm__ volatile(
6099 serge 59
        "int $0x40\t\n"
6068 serge 60
        :"=a"(tmp)
61
        :"a"(77),"b"(FUTEX_WAIT),
62
        "c"(mutex->handle),"d"(2),"S"(0));
63
   }
64
};
65
 
6099 serge 66
static inline int mutex_lock_timeout(mutex_t *mutex, int timeout)
6068 serge 67
{
6099 serge 68
    int tmp = 0;
6068 serge 69
 
70
    if( __sync_fetch_and_add(&mutex->lock, 1) == 0)
6099 serge 71
        return 1;
6068 serge 72
 
73
    while (exchange_acquire (&mutex->lock, 2) != 0)
74
    {
6109 serge 75
        __asm__ __volatile__(
6068 serge 76
        "int $0x40\t"
77
        :"=a"(tmp)
78
        :"a"(77),"b"(FUTEX_WAIT),
79
        "c"(mutex->handle),"d"(2),"S"(timeout));
6099 serge 80
 
81
        if(++tmp == 0)
82
            break;
83
    }
84
    return tmp ;
6068 serge 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
    {
6109 serge 102
        __asm__ volatile(
6068 serge 103
        "int $0x40\t"
104
        :"=a"(prev)
105
        :"a"(77),"b"(FUTEX_WAKE),
106
        "c"(mutex->handle),"d"(1));
107
    };
108
};
109
 
5602 serge 110
#endif