Logo AND Algorithmique Numérique Distribuée

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