Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
update the double extern declaration bis
[simgrid.git] / src / xbt / win_thread.c
1 #include "win_thread.h"
2
3 #include <string.h>
4
5 int                       
6 win_thread_create(win_thread_t* thread,pfn_start_routine_t start_routine,void* param){
7
8         *thread = xbt_new0(s_win_thread_t,1);
9         
10         if(!*thread)
11                 return 1;
12                 
13         (*thread)->handle = CreateThread(NULL,NULL,start_routine,param,0,&((*thread)->id));
14         
15         if(!((*thread)->handle)){
16                 xbt_free(*thread);
17                 *thread = NULL;
18                 return 1;
19         }
20         
21         return 0;       
22 }
23
24 int
25 win_thread_exit(win_thread_t* thread,unsigned long exit_code)
26 {
27         
28     ExitThread(exit_code);
29     
30     free(*thread);
31     *thread = NULL;
32     
33     return 0;
34 }
35
36 unsigned long
37 win_thread_self(void){
38         return GetCurrentThreadId();
39 }
40
41 int
42 win_thread_mutex_init(win_thread_mutex_t* mutex)
43 {
44         *mutex = xbt_new0(s_win_thread_mutex_t,1);
45         
46         if(!*mutex)
47                 return 1;
48                 
49         /* initialize the critical section object */
50         InitializeCriticalSection(&((*mutex)->lock));
51                 
52         return 0;
53 }
54
55 int
56 win_thread_mutex_lock(win_thread_mutex_t* mutex){
57
58         EnterCriticalSection (&((*mutex)->lock));
59         return 0;
60 }
61
62 int
63 win_thread_mutex_unlock(win_thread_mutex_t* mutex){
64
65         LeaveCriticalSection (&(*mutex)->lock);
66         return 0;               
67 }
68
69 int
70 win_thread_mutex_destroy(win_thread_mutex_t* mutex){
71         
72         DeleteCriticalSection(&((*mutex)->lock));       
73                 
74         free(*mutex);
75         *mutex = NULL;
76         
77         return 0;
78 }
79
80 int
81 win_thread_cond_init(win_thread_cond_t* cond){
82         
83         *cond = xbt_new0(s_win_thread_cond_t,1);
84         
85         if(!*cond)
86                 return 1;
87                 
88         memset(&((*cond)->waiters_count_lock),0,sizeof(CRITICAL_SECTION));
89         
90         /* initialize the critical section object */
91         InitializeCriticalSection(&((*cond)->waiters_count_lock));
92         
93         (*cond)->waiters_count = 0;
94         
95         /* Create an auto-reset event */
96         (*cond)->events[SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL); 
97         
98         if(!(*cond)->events[SIGNAL]){
99                 DeleteCriticalSection(&((*cond)->waiters_count_lock));
100                 free(*cond);
101                 return 1;
102         }
103         
104         /* Create a manual-reset event. */
105         (*cond)->events[BROADCAST] = CreateEvent (NULL, TRUE, FALSE,NULL);
106         
107         if(!(*cond)->events[BROADCAST]){
108                 
109                 DeleteCriticalSection(&((*cond)->waiters_count_lock));
110                 
111                 if(!CloseHandle((*cond)->events[SIGNAL]))
112                         return 1;
113                 
114                 free(*cond);
115                 return 1;
116         }
117
118         
119         return 0;       
120 }
121
122 int
123 win_thread_cond_wait(win_thread_cond_t* cond,win_thread_mutex_t* mutex){
124         
125         unsigned long wait_result;
126         int is_last_waiter;
127         
128          /* lock the threads counter and increment it */
129         EnterCriticalSection (&((*cond)->waiters_count_lock));
130         (*cond)->waiters_count++;
131         LeaveCriticalSection (&((*cond)->waiters_count_lock));
132         
133         
134          /* unlock the mutex associate with the condition */
135         LeaveCriticalSection (&(*mutex)->lock);
136         
137         /* wait for a signal (broadcast or no) */
138         wait_result = WaitForMultipleObjects (2, (*cond)->events, FALSE, INFINITE);
139         
140         if(WAIT_FAILED == wait_result)
141                 return 1;
142         
143         /* we have a signal lock the condition */
144         EnterCriticalSection (&((*cond)->waiters_count_lock));
145         (*cond)->waiters_count--;
146         
147         /* it's the last waiter or it's a broadcast ? */
148         is_last_waiter = ((wait_result == WAIT_OBJECT_0 + BROADCAST - 1) && ((*cond)->waiters_count == 0));
149         
150         LeaveCriticalSection (&((*cond)->waiters_count_lock));
151         
152         /* yes it's the last waiter or it's a broadcast
153          * only reset the manual event (the automatic event is reset in the WaitForMultipleObjects() function
154          * by the système. 
155          */
156         if (is_last_waiter){
157                 
158                 if(!ResetEvent ((*cond)->events[BROADCAST]))
159                         return 1;
160         } 
161         
162         /* relock the mutex associated with the condition in accordance with the posix thread specification */
163         EnterCriticalSection (&(*mutex)->lock);
164
165         
166         return 0;
167 }
168
169 int
170 win_thread_cond_signal(win_thread_cond_t* cond)
171 {
172         int have_waiters;
173         
174         EnterCriticalSection (&((*cond)->waiters_count_lock));
175         have_waiters = (*cond)->waiters_count > 0;
176         LeaveCriticalSection (&((*cond)->waiters_count_lock));
177         
178         if (have_waiters){
179                 
180                 if(!SetEvent((*cond)->events[SIGNAL]))
181                         return 1;
182         }
183         
184         return 0;
185 }
186
187 int 
188 win_thread_cond_broadcast(win_thread_cond_t* cond)
189 {
190         int have_waiters;
191         
192         EnterCriticalSection (&((*cond)->waiters_count_lock));
193         have_waiters = (*cond)->waiters_count > 0;
194         LeaveCriticalSection (&((*cond)->waiters_count_lock));
195         
196         if (have_waiters)
197         SetEvent((*cond)->events[BROADCAST]);
198         
199         return 0;
200 }
201
202
203
204 int
205 win_thread_cond_destroy(win_thread_cond_t* cond)
206 {
207         int result = 0;
208         
209         if(!CloseHandle((*cond)->events[SIGNAL]))
210                 result= 1;
211         
212         if(!CloseHandle((*cond)->events[BROADCAST]))
213                 result = 1;
214         
215         DeleteCriticalSection(&((*cond)->waiters_count_lock));  
216         
217         xbt_free(*cond);
218         *cond = NULL;
219         
220         return result;
221 }
222
223