Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
time function implementation
[simgrid.git] / win32_test_app / src / TThreadDynarray.c
1
2 #include <TThreadDynarray.h>
3
4 /*
5  * Constructs a ThreadDynarray with the specified capacity.
6  */
7 ThreadDynarray_t ThreadDynarray_new(unsigned long capacity)
8 {
9         ThreadDynarray_t ptr = calloc(1,sizeof(s_ThreadDynarray_t));
10
11         ptr->count = 0;
12         ptr->capacity = capacity;
13         
14         memset(&(ptr->cs),0,sizeof(CRITICAL_SECTION)) ;
15         InitializeCriticalSection(&(ptr->cs));
16         ptr->is_locked = false;
17
18         if(capacity)
19                 ptr->threads = (ThreadEntry_t)calloc(capacity,sizeof(s_ThreadEntry_t));
20     else
21                 ptr->threads = NULL;
22
23         return ptr;
24 }
25
26 /* 
27  * Destroy the ThreadDynarray 
28  */
29 void ThreadDynarray_destroy(ThreadDynarray_t ptr)
30 {
31         ThreadDynarray_clear(ptr);      
32         DeleteCriticalSection(&(ptr->cs));
33         free(ptr);
34         ptr = NULL;             
35 }
36
37 /*
38  * Returns an const pointer to entry pointed to by index.
39  */
40 ThreadEntry_t const ThreadDynarray_at(ThreadDynarray_t ptr, unsigned long index)
41 {
42         ThreadEntry_t __entry;
43         ThreadDynarray_lock(ptr);
44         __entry = &(ptr->threads)[index];
45         ThreadDynarray_unlock(ptr);
46         return __entry;
47 }
48
49 /*
50  * Fill the content of the entry addressed by __entry with the content
51  * of the entry pointed to by index.
52  */
53 void ThreadDynarray_get(ThreadDynarray_t ptr, unsigned long index, ThreadEntry_t const __entry)
54 {
55          ThreadDynarray_lock(ptr);
56     ::memcpy(__entry,ThreadDynarray_at(ptr,index),sizeof(s_ThreadEntry_t));
57      ThreadDynarray_unlock(ptr);
58 }
59
60 /* 
61  * Fill the content of the entry pointed to by index with the content of
62  * the entry addressed by __entry.
63  */
64 void ThreadDynarray_set(ThreadDynarray_t ptr, unsigned long index, ThreadEntry_t const __entry)
65 {
66
67          ThreadDynarray_lock(ptr);
68          memcpy(ThreadDynarray_at(ptr,index),__entry,sizeof(s_ThreadEntry_t));
69          ThreadDynarray_unlock(ptr);
70 }
71
72 /*
73  * Returns a const pointer to the first entry.
74  */
75 ThreadEntry_t const ThreadDynarray_getFront(ThreadDynarray_t ptr)
76 {
77         ThreadEntry_t __entry;
78         ThreadDynarray_lock(ptr);
79         __entry = ThreadDynarray_at(ptr,0);
80         ThreadDynarray_unlock(ptr);
81         return __entry;
82 }
83
84 /*
85  * Returns a const pointer to the last entry.
86  */
87 ThreadEntry_t const ThreadDynarray_getBack(ThreadDynarray_t ptr)
88 {
89         ThreadEntry_t __entry;
90         ThreadDynarray_lock(ptr);
91         __entry = ThreadDynarray_at(ptr,ptr->count - 1);;
92         ThreadDynarray_unlock(ptr);
93         return __entry;
94 }
95
96 /*
97  * Inserts a copy of __entry at the front
98  */
99 void ThreadDynarray_pushFront(ThreadDynarray_t ptr, ThreadEntry_t const __entry)
100 {
101         ThreadDynarray_lock(ptr);
102
103         if(!ThreadDynarray_getCapacityAvailable(ptr))
104                 ThreadDynarray_resize(ptr);
105         
106         ptr->count++;
107         ThreadDynarray_move(ptr,1,ThreadDynarray_getLowerBound(ptr),ThreadDynarray_getUpperBound(ptr));
108         ThreadDynarray_set(ptr,ThreadDynarray_getLowerBound(ptr),__entry);
109
110         ThreadDynarray_unlock(ptr);
111 }
112
113 /*
114  * Appends a copy of __entry to the end.
115  */
116 void ThreadDynarray_pushBack(ThreadDynarray_t ptr, ThreadEntry_t const __entry)
117 {
118         ThreadDynarray_lock(ptr);
119
120         if(!ThreadDynarray_getCapacityAvailable(ptr))
121                 ThreadDynarray_resize(ptr);
122         
123         ptr->count++;
124         ThreadDynarray_set(ptr,ThreadDynarray_getUpperBound(ptr),__entry);
125
126         ThreadDynarray_unlock(ptr);
127 }
128
129
130 /* 
131  * Inserts __entry at the position pointed to by index.
132  */
133 void ThreadDynarray_insert(ThreadDynarray_t ptr, unsigned long index, ThreadEntry_t const __entry)
134 {
135         ThreadDynarray_lock(ptr);
136
137         if(!ThreadDynarray_getCapacityAvailable(ptr))
138                 ThreadDynarray_resize(ptr);
139         
140         ThreadDynarray_move(ptr,index + 1,index,ptr->count - index);
141         ptr->count++;
142         ThreadDynarray_set(ptr,index,__entry);
143
144         ThreadDynarray_unlock(ptr);
145 }
146
147 /*
148  * Deletes the entry pointed to by index. If __entry is not NULL the
149  * fuction saves the entry threads at this address before.
150  */
151 void ThreadDynarray_erase(ThreadDynarray_t ptr, unsigned long index,ThreadEntry_t const __entry)
152 {
153         
154         ThreadDynarray_lock(ptr);
155
156         if(__entry)
157                 ThreadDynarray_set(ptr,index,__entry);
158         
159         if(index != ThreadDynarray_getUpperBound(ptr))
160                 ThreadDynarray_move(ptr,index,index + 1,(ptr->count - (index + 1)));
161         
162         ptr->count--;
163
164         ThreadDynarray_unlock(ptr);
165 }
166
167 /*
168  * Find the first entry with the same content of the entry addressed by
169  * __entry.The function returns the index of the founded entry, -1 if
170  * no entry is founded.
171  */
172 long ThreadDynarray_getIndex(ThreadDynarray_t ptr, ThreadEntry_t const __entry)
173 {
174         
175     unsigned long i ;
176         ThreadDynarray_lock(ptr);
177
178         for(i = 0; i < ptr->count; i++){
179                 if(ThreadDynarray_compare(ptr,i,__entry)){
180                         ThreadDynarray_unlock(ptr);
181                         return i;
182                 }
183         }
184
185         ThreadDynarray_unlock(ptr);
186         return -1;  
187 }
188
189 /* 
190  * Returns true if the entry exist.
191  */
192 bool ThreadDynarray_exist(ThreadDynarray_t ptr, ThreadEntry_t const __entry)
193 {
194         bool exist;
195         
196         ThreadDynarray_lock(ptr);
197         exist = (-1 != ThreadDynarray_getIndex(ptr,__entry));
198         ThreadDynarray_unlock(ptr); 
199         return exist;
200 }
201
202 /* Deletes the first entry with the same content of the entry addressed
203  * by __entry.The function returns true if the entry is deleted, false
204  * if no entry is founded.
205  */
206 bool ThreadDynarray_remove(ThreadDynarray_t ptr, ThreadEntry_t const __entry)
207 {
208         /* assert(!empty(ptr)); */
209         
210         long __index;
211         ThreadDynarray_lock(ptr);
212         __index = ThreadDynarray_getIndex(ptr,__entry);
213         
214         if(__index == -1){
215                 ThreadDynarray_unlock(ptr);
216                 return false;
217         }
218         
219         ThreadDynarray_set(ptr,(unsigned long)__index,NULL);
220         ThreadDynarray_unlock(ptr);
221         return true;
222 }
223
224 /*
225  * Erase all elements of the self.
226  */
227 void ThreadDynarray_clear(ThreadDynarray_t ptr)
228 {
229         ThreadDynarray_lock(ptr);
230
231         if(ptr->threads){
232                 free(ptr->threads);
233                 ptr->threads = NULL;
234         }
235
236         ptr->count = 0;
237         ptr->capacity = 0;
238         ThreadDynarray_unlock(ptr);     
239 }
240
241 /*
242  * Resets entry count to zero.
243  */
244 void ThreadDynarray_reset(ThreadDynarray_t ptr)
245 {
246          ThreadDynarray_lock(ptr);
247          ptr->count = 0;
248          ThreadDynarray_unlock(ptr);
249 }
250
251 /*
252  * Moves count elements from src index to dst index.
253  */
254 void ThreadDynarray_move(ThreadDynarray_t ptr, const unsigned long dst,const unsigned long src,unsigned long count)
255 {
256         ThreadDynarray_lock(ptr);
257
258         if(ptr->count)
259                 memmove(ThreadDynarray_at(ptr,dst),ThreadDynarray_at(ptr,src),count * sizeof(s_ThreadEntry_t));
260
261         ThreadDynarray_unlock(ptr);
262 }
263
264 /* Compare the content of the entry pointed to by index with the content of
265  * the entry addressed by __entry. The function returns true if the contents
266  * are same.
267  */
268 bool ThreadDynarray_compare(ThreadDynarray_t ptr, const unsigned long index,ThreadEntry_t const __entry)
269 {
270         bool are_equals;
271         ThreadDynarray_lock(ptr);
272         are_equals = (!memcmp(ThreadDynarray_at(ptr,index),__entry,sizeof(s_ThreadEntry_t)));
273         ThreadDynarray_unlock(ptr);
274         return are_equals;
275 }
276
277 /*
278  * Returns a reference to a new ThreadDynarray new set is a clone of the self.
279  */
280 ThreadDynarray_t ThreadDynarray_clone(ThreadDynarray_t ptr)
281 {
282         ThreadDynarray_t new_ptr;
283         ThreadDynarray_lock(ptr);
284         ptr = ThreadDynarray_new(ptr->capacity);
285         
286         if(ptr->count){
287                 memcpy(new_ptr->threads,ptr->threads,ptr->count * sizeof(s_ThreadEntry_t));
288                 new_ptr->count=ThreadDynarray_getCount(ptr);
289         }
290         ThreadDynarray_unlock(ptr);
291         return new_ptr;
292 }
293
294 /*
295  * Extends the capacity when the container is full.
296  */
297 void ThreadDynarray_resize(ThreadDynarray_t ptr)
298 {
299         ThreadDynarray_lock(ptr);
300         
301         ptr->capacity = (!ptr->capacity) ? 1 : (ptr->count << 1);
302         ptr->threads = (ThreadEntry_t)realloc(ptr->threads, ptr->capacity * sizeof(s_ThreadEntry_t));
303         
304         ThreadDynarray_unlock(ptr);
305 }
306
307
308 /*
309  * Returns the number of elements.
310  */
311 unsigned long ThreadDynarray_getCount(ThreadDynarray_t ptr)
312 {
313         unsigned count;
314         ThreadDynarray_lock(ptr);
315         count = ptr->count;     
316         ThreadDynarray_unlock(ptr);
317         return count;
318 }
319
320 /*
321  * Returns the current storage capacity of the ThreadDynarray. This is guaranteed
322  * to be at least as large as count().
323  */
324 unsigned long ThreadDynarray_getCapacity(ThreadDynarray_t ptr)
325 {
326         unsigned capacity;
327         ThreadDynarray_lock(ptr);
328         capacity = ptr->capacity;
329         ThreadDynarray_unlock(ptr);
330         return capacity;
331 }
332
333
334 /*
335  * Returns upper bound of self (max index).
336  */
337 unsigned long ThreadDynarray_getUpperBound(ThreadDynarray_t ptr)
338 {
339         unsigned long upper_bound;
340         ThreadDynarray_lock(ptr);
341         upper_bound = (ptr->count - 1);
342         ThreadDynarray_unlock(ptr);
343         return upper_bound;
344 }
345
346 /*
347  * Returns lower bound of self (always zero).
348  */
349 unsigned long ThreadDynarray_getLowerBound(ThreadDynarray_t ptr)
350 {
351         return 0;
352 }
353
354 /*
355  * Returns the size of the elements.
356  */
357 unsigned long ThreadDynarray_getElementSize(ThreadDynarray_t ptr)
358 {
359         return sizeof(s_ThreadEntry_t);
360 }
361
362 /*
363  * Returns true if the size of self is zero.
364  */
365 bool ThreadDynarray_isEmpty(ThreadDynarray_t ptr)
366 {
367         bool is_empty;
368         ThreadDynarray_lock(ptr);
369         is_empty = (ptr->count == 0);
370         ThreadDynarray_unlock(ptr);
371         return is_empty;
372 }
373
374 /*
375  * Returns true if capacity available.
376  */
377 bool ThreadDynarray_getCapacityAvailable(ThreadDynarray_t ptr)
378 {
379         bool capacity_available;
380         ThreadDynarray_lock(ptr);
381         capacity_available = (ptr->capacity > ptr->count);
382         ThreadDynarray_unlock(ptr);
383         return capacity_available;
384 }
385
386 /*
387  * Returns true if the container is full.
388  */
389 bool ThreadDynarray_is_full(ThreadDynarray_t ptr)
390 {
391         bool is_full;
392         ThreadDynarray_lock(ptr);
393         is_full = (!ThreadDynarray_isEmpty(ptr) && !ThreadDynarray_getCapacityAvailable(ptr));
394         ThreadDynarray_unlock(ptr);
395         return is_full;
396 }
397
398 /* 
399  * Assignement.
400  */
401 ThreadDynarray_t ThreadDynarray_assign(ThreadDynarray_t src,ThreadDynarray_t dst)
402 {
403         ThreadDynarray_lock(src);
404         ThreadDynarray_lock(dst);
405         
406         if(src != dst)
407         {
408                 ThreadDynarray_clear(dst);
409         
410                 if(src->count)
411                 {
412                         dst->count = src->count;
413                         dst->capacity = src->capacity;
414                         dst->threads = (ThreadEntry_t)malloc(src->capacity * sizeof(s_ThreadEntry_t));
415                         memcpy(dst->threads,src->threads,src->count * sizeof(s_ThreadEntry_t));
416                 }
417         }
418         ThreadDynarray_unlock(src);
419         ThreadDynarray_unlock(dst);
420         
421         return dst;     
422 }
423
424 /* 
425  * Returns true if the dynamic arrays are equal.
426  */ 
427 bool ThreadDynarray_areEquals(ThreadDynarray_t ptr1,ThreadDynarray_t ptr2)
428 {
429         bool are_equals;
430         
431         ThreadDynarray_lock(ptr1);
432         ThreadDynarray_lock(ptr2);
433
434         are_equals = (
435                         ptr1->count == ptr2->count                              &&
436                         ptr1->capacity == ptr2->capacity                        &&
437                         !memcmp(ptr2->threads,ptr1->threads,ptr1->capacity)
438         );
439
440         ThreadDynarray_unlock(ptr1);
441         ThreadDynarray_unlock(ptr2);
442         
443         return are_equals;      
444 }
445
446 /* 
447  * Returns true if the dynamic arrays are not equal.
448  */ 
449 ThreadDynarray_areNotEquals(ThreadDynarray_t ptr1,ThreadDynarray_t ptr2)
450 {
451         return !ThreadDynarray_areEquals(ptr1,ptr2);    
452 }
453
454 void ThreadDynarray_lock(ThreadDynarray_t ptr)
455 {
456         if(!ptr->is_locked){
457                 EnterCriticalSection(&(ptr->cs));
458                 ptr->is_locked = true;
459         }
460 }
461
462 void ThreadDynarray_unlock(ThreadDynarray_t ptr)
463 {
464         if(ptr->is_locked){
465                 LeaveCriticalSection(&(ptr->cs));
466                 ptr->is_locked = false;
467         }
468 }