Subversion Repositories Kolibri OS

Rev

Rev 5602 | Rev 6099 | Go to most recent revision | 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
 
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
 
5602 serge 106
#endif