Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6554 serge 1
#include 
2
#include 
3
#include 
4
 
5
void __mutex_lock(volatile int *val);
6
 
7
static inline int tls_get(int key)
8
{
9
    int val;
10
    __asm__ __volatile__(
11
    "movl %%fs:(%1), %0"
12
    :"=r"(val)
13
    :"r"(key));
14
 
15
  return val;
16
};
17
 
18
typedef struct {
19
  int done;
20
  long started;
21
} __gthread_once_t;
22
 
23
typedef struct {
24
  int counter;
25
  void *sema;
26
} __gthread_mutex_t;
27
 
28
typedef struct {
29
  int counter;
30
  int depth;
31
  unsigned long owner;
32
  int sema;
33
} __gthread_recursive_mutex_t;
34
 
35
 
36
int
37
__gthr_win32_once (__gthread_once_t *once, void (*func) (void))
38
{
39
    if (once == NULL || func == NULL)
40
        return EINVAL;
41
 
42
    if (! once->done)
43
    {
44
        if (__sync_add_and_fetch (&(once->started), 1) == 0)
45
        {
46
            (*func) ();
47
            once->done = 1;
48
        }
49
        else
50
        {
51
	  /* Another thread is currently executing the code, so wait for it
52
	     to finish; yield the CPU in the meantime.  If performance
53
	     does become an issue, the solution is to use an Event that
54
	     we wait on here (and set above), but that implies a place to
55
	     create the event before this routine is called.  */
56
            while (! once->done)
57
                delay(1);
58
        }
59
    }
60
    return 0;
61
}
62
 
63
void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
64
{
65
  mutex->counter = 0;
66
  mutex->sema = 0;
67
}
68
 
69
int __gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
70
{
71
    __mutex_lock(&mutex->counter);
72
    return 0;
73
}
74
 
75
int
76
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
77
{
78
  mutex->counter = 0;
79
  return 0;
80
}
81
 
82
void
83
__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
84
{
85
  mutex->counter = -1;
86
  mutex->depth = 0;
87
  mutex->owner = 0;
88
  mutex->sema = 0;
89
}
90
 
91
void
92
__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex)
93
{ }
94
 
95
int
96
__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
97
{
98
    int me = tls_get(0);
99
    if ( __sync_add_and_fetch(&mutex->counter, 1) == 0)
100
    {
101
        mutex->depth = 1;
102
        mutex->owner = me;
103
        mutex->sema  = 1;
104
    }
105
    else if (mutex->owner == me)
106
    {
107
        __sync_sub_and_fetch(&mutex->counter, 1);
108
        ++(mutex->depth);
109
    }
110
    else
111
    {
112
        __mutex_lock(&mutex->sema);
113
        mutex->depth = 1;
114
        mutex->owner = me;
115
    }
116
    return 0;
117
}
118
 
119
int
120
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
121
{
122
    int me = tls_get(0);
123
    if (__sync_val_compare_and_swap (&mutex->counter, -1, 0) < 0)
124
    {
125
        mutex->depth = 1;
126
        mutex->owner = me;
127
        mutex->sema  = 1;
128
    }
129
    else if (mutex->owner == me)
130
        ++(mutex->depth);
131
    else
132
        return 1;
133
 
134
  return 0;
135
}
136
 
137
int
138
__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
139
{
140
    --(mutex->depth);
141
    if (mutex->depth == 0)
142
    {
143
        mutex->owner = 0;
144
 
145
        if (__sync_sub_and_fetch (&mutex->counter, 1) >= 0)
146
            mutex->sema = 0;
147
    }
148
 
149
    return 0;
150
}